1
edit
Changes
no edit summary
===Implementing the Service Provider===
Now we will be creating another project but this time the project will be used as the service provider. Like our example above, create a new plug-in project and name it '''cs.ecl.osgi.tasksystem'''. This time make sure that you check the '''Generate an activator...''' option on the second step of the create project screen.
[[File:Tasksystem_00.png]]
We will now be using the service interface we created above, so double-click the '''MANIFEST.MF''' file and go to the '''Dependencies''' tab. Now add the following dependencies as shown below. Use the '''Add...''' options and filter to search for the package.
[[File:Tasksystem_01.png]]
We will now create a class to act as the system for adding and removing tasks. Essentially, this will be the core of our service. In our example, we decided to keep this class in a separate package so, let's do this by right-clicking on the '''cs.ecl.osgi.tasksystem''' package and selecting '''New''' -> '''Package'''; name this new package '''cs.ecl.osgi.tasksystem.internals'''.
Now within the new package, create a new class called '''SimpleTaskSystem''' that implements the service interface, TaskManager, that we created before. The class should look like this:
<pre>
package cs.ecl.osgi.tasksystem.internals;
import java.util.ArrayList;
import java.util.List;
import cs.ecl.osgi.taskmanager.TaskManager;
public class SimpleTaskSystem implements TaskManager {
public static List<String> tasks = new ArrayList<String>();
public static List<Boolean> complete = new ArrayList<Boolean>();
@Override
public boolean addTask(String name) {
boolean success = false;
if(tasks.add(name)) {
complete.add(false);
success = true;
}
return success;
}
@Override
public String removeTask(int index) {
String taskName = "";
taskName = tasks.remove(index);
if( taskName != "") {
complete.remove(index);
}
return taskName;
}
}
</pre>
Using the Package Explorer find the '''Activator.java''' class and open it by double-clicking. Now we will implement the service provider (TaskManagerSystem) we just created. The code should look like this:
<pre>
package cs.ecl.osgi.tasksystem;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import cs.ecl.osgi.taskmanager.TaskManager;
import cs.ecl.osgi.tasksystem.internals.SimpleTaskSystem;
public class Activator implements BundleActivator {
private static BundleContext context;
static BundleContext getContext() {
return context;
}
/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
TaskManager tm = new SimpleTaskSystem();
context.registerService(TaskManager.class.getName(), tm, null);
System.out.println("Task Manager registered!");
}
/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
System.out.println("Task Manager stopped!");
}
}
</pre>
===Creating the Service Consumer===
Now that we have the service finished, we need to create a user interface that will act as the service consumer. This basically refers to something that will be using our service, task system. To start, let's create another '''Plug-in Project''' as we've done before and name it '''cs.ecl.osgi.tasksystem.client'''. Once again, make sure that we generate an activator for this new project.
Now we will be adding the dependencies again. As shown in the previous step, make sure that the following plug-ins are required.
[[File:Tasksystemclient_00.png]]
Let's create the graphical user interface (GUI) for the project. Create a new class that looks like the following:
<pre>
package cs.ecl.osgi.tasksystem.client;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import cs.ecl.osgi.taskmanager.TaskManager;
public class TaskDialog extends JPanel {
JLabel label;
JFrame frame;
DefaultListModel taskListModel;
JList taskList;
String addTaskString = "Add Task";
String deleteTaskString = "Delete Task";
String instructions = "<html><B>Add New Task:</B> Type a task in the textbox below and press the \"Add Task\" button. <P>" +
"<B>Delete Task:</B> Select a task and press the \"Delete Task\" button.<P><P></html>";
JTextField taskName;
JButton deleteTaskButton;
JButton addTaskButton;
static TaskManager tm;
public TaskDialog(JFrame frame) {
super(new BorderLayout());
this.frame = frame;
JPanel taskPanel = createTaskPanel();
taskPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 5, 20));
JPanel taskAddPanel = createTaskAddPanel();
JPanel headerPanel = getHeaderPanel();
// GUI Layout
add(headerPanel, BorderLayout.NORTH);
add(taskPanel, BorderLayout.CENTER);
add(taskAddPanel,BorderLayout.PAGE_END);
}
private JPanel getHeaderPanel() {
JPanel headerPanel = new JPanel();
headerPanel.setLayout(new BoxLayout(headerPanel, BoxLayout.Y_AXIS));
JLabel instructionsLabel = new JLabel(instructions, JLabel.CENTER);
Font font = new Font("Serif", Font.PLAIN, 24);
instructionsLabel.setFont(font);
label = new JLabel("<html><FONT COLOR=GREEN>Start adding Tasks...</FONT></html>", JLabel.CENTER);
headerPanel.add(instructionsLabel);
headerPanel.add(label);
return headerPanel;
}
private JPanel createTaskPanel() {
JPanel taskPanel = new JPanel();
taskPanel.setLayout(new BoxLayout(taskPanel, BoxLayout.LINE_AXIS));
taskListModel = new DefaultListModel();
// create JList then add it to scroll pane
taskList = new JList(taskListModel);
taskList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
taskList.setSelectedIndex(0);
taskList.setVisibleRowCount(50);
JScrollPane taskListScrollPane = new JScrollPane(taskList);
taskPanel.add(taskListScrollPane);
return taskPanel;
}
private JPanel createTaskAddPanel() {
JPanel taskAddPanel = new JPanel();
taskAddPanel.setLayout(new BoxLayout(taskAddPanel, BoxLayout.LINE_AXIS));
taskName = new JTextField(100);
addTaskButton = new JButton(addTaskString);
addTaskButton.setActionCommand(addTaskString);
addTaskButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String task = taskName.getText();
if(tm.addTask(task)) {
taskListModel.addElement(task);
taskName.setText("");
label.setText("<html><FONT COLOR=GREEN>\"" + task + "\"" + " has been added to your to do list.</FONT></html>");
}
}
});
deleteTaskButton = new JButton(deleteTaskString);
deleteTaskButton.setActionCommand(deleteTaskString);
deleteTaskButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(taskList.getSelectedIndex() != -1) {
// ****** uncomment this line to handle multiple indicies ******
//int [] arr = taskList.getSelectedIndices();
//for(int i=0; i< arr.length; i++) {
// tm.removeTask(arr[i]);
// taskListModel.removeElementAt(arr[i]);
// label.setText("\"" + task + "\"" + " has been added to your to do list.");
//}
// ****** comment the following lines to handle single item selects ********
int selectedIndex = taskList.getSelectedIndex();
String taskName = tm.removeTask(selectedIndex);
taskListModel.removeElementAt(selectedIndex);
label.setText("<html><FONT COLOR=RED>\"" + taskName + "\"" + " has been removed from your to do list.</FONT></html>");
}
}
});
taskAddPanel.add(deleteTaskButton);
taskAddPanel.add(Box.createHorizontalStrut(5));
taskAddPanel.add(Box.createHorizontalStrut(5));
taskAddPanel.add(taskName);
taskAddPanel.add(addTaskButton);
taskAddPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
return taskAddPanel;
}
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
*/
private static void createAndShowGUI(TaskManager tm) {
// Make sure we have nice window decorations.
JFrame.setDefaultLookAndFeelDecorated(true);
JDialog.setDefaultLookAndFeelDecorated(true);
// Create and set up the window.
JFrame frame = new JFrame("To Do List");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Set up the content pane.
Container contentPane = frame.getContentPane();
contentPane.setLayout(new GridLayout(1, 1));
contentPane.add(new TaskDialog(frame));
TaskDialog.tm = tm;
// Display the window.
frame.pack();
frame.setVisible(true);
}
public static void runDialog(final TaskManager tm) {
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI(tm);
}
});
}
}
</pre>
Once again, we will need to edit the activator for this new project to make use of the GUI we created for our project. To do this, find the '''Activator.java''' class for our new project ('''cs.ecl.osgi.tasksystem.client''') and add the following:
<pre>
package cs.ecl.osgi.tasksystem.client;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import cs.ecl.osgi.taskmanager.TaskManager;
public class Activator implements BundleActivator {
private static BundleContext context;
private TaskManager tm;
static BundleContext getContext() {
return context;
}
/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
ServiceReference reference = context.getServiceReference(TaskManager.class.getName());
if(reference != null) {
tm = (TaskManager) context.getService(reference);
if(tm != null) {
// start GUI
TaskDialog.runDialog(tm);
context.ungetService(reference);
} else {
System.err.println("Task Manager could not be used!");
}
} else {
System.err.println("The Task Manager System could not be found!");
}
}
/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
}
}
</pre>
We are now finished. To run our application, right-click the '''MANIFEST.MF''' file and select the '''Run As...''' -> '''Run Configurations'''. Now make sure that all the required bundles in our workspace are selected and that the '''Validate bundles automatically prior to launching''' is checked.
[[File:Tasksystemclient_01.png]]
If everything was done correctly, you should be able to run the project and see our new application.
[[File:Tasksystemclient_02.png]]