diff --git a/osgi.bundle.monitoring.dem1/.classpath b/osgi.bundle.monitoring.dem1/.classpath new file mode 100644 index 0000000..b1dabee --- /dev/null +++ b/osgi.bundle.monitoring.dem1/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/osgi.bundle.monitoring.dem1/.project b/osgi.bundle.monitoring.dem1/.project new file mode 100644 index 0000000..69aeb69 --- /dev/null +++ b/osgi.bundle.monitoring.dem1/.project @@ -0,0 +1,28 @@ + + + osgi.bundle.monitoring.dem1 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/osgi.bundle.monitoring.dem1/.settings/org.eclipse.jdt.core.prefs b/osgi.bundle.monitoring.dem1/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..11f6e46 --- /dev/null +++ b/osgi.bundle.monitoring.dem1/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/osgi.bundle.monitoring.dem1/.settings/org.eclipse.pde.core.prefs b/osgi.bundle.monitoring.dem1/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 0000000..d711c29 --- /dev/null +++ b/osgi.bundle.monitoring.dem1/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +pluginProject.equinox=false +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/osgi.bundle.monitoring.dem1/META-INF/MANIFEST.MF b/osgi.bundle.monitoring.dem1/META-INF/MANIFEST.MF new file mode 100644 index 0000000..1afe9f3 --- /dev/null +++ b/osgi.bundle.monitoring.dem1/META-INF/MANIFEST.MF @@ -0,0 +1,12 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Dem1 +Bundle-SymbolicName: osgi.bundle.monitoring.dem1 +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: osgi.bundle.monitoring.dem1.Activator +Import-Package: org.osgi.framework;version="1.3.0", + osgi.framework.monitoring.event;version="1.0.0", + osgi.framework.monitoring.event.filter;version="1.0.0", + javax.swing, + javax.swing.table +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/Activator.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/Activator.java new file mode 100644 index 0000000..66a2cd9 --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/Activator.java @@ -0,0 +1,53 @@ +package osgi.bundle.monitoring.dem1; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +import osgi.bundle.monitoring.dem1.controller.ButtonListener; +import osgi.bundle.monitoring.dem1.controller.CheckBoxMenuListener; +import osgi.bundle.monitoring.dem1.controller.MenuItemListener; +import osgi.bundle.monitoring.dem1.model.Model; +import osgi.bundle.monitoring.dem1.view.View; + +public class Activator implements BundleActivator +{ + + private static BundleContext context; + + private View view; + + private Model model; + + static BundleContext getContext() + { + return context; + } + + public void start(BundleContext bundleContext) throws Exception + { + Activator.context = bundleContext; + + view = new View(); + view.initUi(); + + model = new Model(bundleContext); + + ButtonListener buttonListener = new ButtonListener(model, view); + CheckBoxMenuListener checkBoxMenuListener = new CheckBoxMenuListener(model); + MenuItemListener menuItemListener = new MenuItemListener(model, view); + + model.addObserver(view); + + view.completeUi(buttonListener, checkBoxMenuListener, menuItemListener); + } + + public void stop(BundleContext bundleContext) throws Exception + { + Activator.context = null; + + model.unregisterServices(); + + view.close(); + } + +} diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/controller/ButtonListener.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/controller/ButtonListener.java new file mode 100644 index 0000000..78353f2 --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/controller/ButtonListener.java @@ -0,0 +1,120 @@ +package osgi.bundle.monitoring.dem1.controller; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +import javax.swing.JButton; + +import osgi.bundle.monitoring.dem1.model.Model; +import osgi.bundle.monitoring.dem1.view.View; + +public class ButtonListener implements MouseListener +{ + + private Model model; + + private View view; + + public ButtonListener(Model model, View view) + { + this.model = model; + this.view = view; + } + + @Override + public void mouseClicked(MouseEvent me) + { + String button = ((JButton)me.getSource()).getText(); + + if(button.compareTo("Install") == 0) + { + String fileName = view.installDialog(); + + if(fileName != null) + { + model.installBundle(fileName); + } + } + else if(button.compareTo("Uninstall") == 0) + { + long id = view.getSelectedBundleId(); + + if(id >= 0) + { + model.uninstallBundle(id); + } + } + else if(button.compareTo("Update") == 0) + { + long id = view.getSelectedBundleId(); + + if(id >= 0) + { + model.updateBundle(id); + } + } + else if(button.compareTo("Start") == 0) + { + long id = view.getSelectedBundleId(); + + if(id >= 0) + { + model.startBundle(id); + } + } + else if(button.compareTo("Stop") == 0) + { + long id = view.getSelectedBundleId(); + + if(id >= 0) + { + model.stopBundle(id); + } + } + else if(button.compareTo("Monitor") == 0) + { + long id = view.getSelectedBundleId(); + + if(id >= 0) + { + model.setIdOpened(id); + view.checkMonitoring(id); + } + } + else if(button.compareTo("Unmonitor") == 0) + { + long id = view.getSelectedBundleId(); + + if(id >= 0) + { + model.setIdClosed(id); + view.uncheckMonitoring(id); + } + } + } + + @Override + public void mouseEntered(MouseEvent me) + { + + } + + @Override + public void mouseExited(MouseEvent me) + { + + } + + @Override + public void mousePressed(MouseEvent me) + { + + } + + @Override + public void mouseReleased(MouseEvent me) + { + + } + +} diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/controller/CheckBoxMenuListener.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/controller/CheckBoxMenuListener.java new file mode 100644 index 0000000..0b4c500 --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/controller/CheckBoxMenuListener.java @@ -0,0 +1,139 @@ +package osgi.bundle.monitoring.dem1.controller; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.JCheckBoxMenuItem; + +import org.osgi.framework.BundleEvent; + +import osgi.bundle.monitoring.dem1.model.Model; +import osgi.framework.monitoring.event.RepositoryEvent; +import osgi.framework.monitoring.event.ManifestEvent; + +public class CheckBoxMenuListener implements ActionListener +{ + + private Model model; + + public CheckBoxMenuListener(Model model) + { + this.model = model; + } + + public void changeMonitorState(boolean state, int index) + { + if(state == true) + { + model.setMonitorOn(index); + } + else + { + model.setMonitorOff(index); + } + } + + private void changeTypeFilter(boolean state, int index, int type) + { + if(state == true) + { + model.setTypeOpened(index, type); + } + else + { + model.setTypeClosed(index, type); + } + } + + @Override + public void actionPerformed(ActionEvent ae) + { + JCheckBoxMenuItem cb = (JCheckBoxMenuItem)ae.getSource(); + String checkBox = cb.getText(); + + if(checkBox.compareTo("Bundle repository") == 0) + { + changeMonitorState(cb.getState(), 0); + } + else if(checkBox.compareTo("Bundle state") == 0) + { + changeMonitorState(cb.getState(), 1); + } + else if(checkBox.compareTo("Bundle manifest") == 0) + { + changeMonitorState(cb.getState(), 2); + } + else if(checkBox.compareTo("Data field") == 0) + { + changeMonitorState(cb.getState(), 3); + } + else if(checkBox.compareTo("Create") == 0) + { + changeTypeFilter(cb.getState(), 0, RepositoryEvent.ENTRY_CREATE); + } + else if(checkBox.compareTo("Modify") == 0) + { + changeTypeFilter(cb.getState(), 0, RepositoryEvent.ENTRY_MODIFY); + } + else if(checkBox.compareTo("Delete") == 0) + { + changeTypeFilter(cb.getState(), 0, RepositoryEvent.ENTRY_DELETE); + } + else if(checkBox.compareTo("Installed") == 0) + { + changeTypeFilter(cb.getState(), 1, BundleEvent.INSTALLED); + } + else if(checkBox.compareTo("Lazy Activation") == 0) + { + changeTypeFilter(cb.getState(), 1, BundleEvent.LAZY_ACTIVATION); + } + else if(checkBox.compareTo("Resolved") == 0) + { + changeTypeFilter(cb.getState(), 1, BundleEvent.RESOLVED); + } + else if(checkBox.compareTo("Started") == 0) + { + changeTypeFilter(cb.getState(), 1, BundleEvent.STARTED); + } + else if(checkBox.compareTo("Starting") == 0) + { + changeTypeFilter(cb.getState(), 1, BundleEvent.STARTING); + } + else if(checkBox.compareTo("Stopped") == 0) + { + changeTypeFilter(cb.getState(), 1, BundleEvent.STOPPED); + } + else if(checkBox.compareTo("Stopping") == 0) + { + changeTypeFilter(cb.getState(), 1, BundleEvent.STOPPING); + } + else if(checkBox.compareTo("Uninstalled") == 0) + { + changeTypeFilter(cb.getState(), 1, BundleEvent.UNINSTALLED); + } + else if(checkBox.compareTo("Unresolved") == 0) + { + changeTypeFilter(cb.getState(), 1, BundleEvent.UNRESOLVED); + } + else if(checkBox.compareTo("Updated") == 0) + { + changeTypeFilter(cb.getState(), 1, BundleEvent.UPDATED); + } + else if(checkBox.compareTo("Created") == 0) + { + changeTypeFilter(cb.getState(), 2, ManifestEvent.CREATED); + } + else if(checkBox.compareTo("Modified") == 0) + { + changeTypeFilter(cb.getState(), 2, ManifestEvent.MODIFIED); + } + else if(checkBox.compareTo("Deleted") == 0) + { + changeTypeFilter(cb.getState(), 2, ManifestEvent.DELETED); + } + else + { + //fields + } + } + +} diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/controller/MenuItemListener.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/controller/MenuItemListener.java new file mode 100644 index 0000000..710755a --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/controller/MenuItemListener.java @@ -0,0 +1,36 @@ +package osgi.bundle.monitoring.dem1.controller; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JMenuItem; + +import osgi.bundle.monitoring.dem1.model.Model; +import osgi.bundle.monitoring.dem1.view.View; + +public class MenuItemListener implements ActionListener +{ + + private Model model; + + private View view; + + public MenuItemListener(Model model, View view) + { + this.model = model; + this.view = view; + } + + @Override + public void actionPerformed(ActionEvent ae) + { + JMenuItem mi = (JMenuItem)ae.getSource(); + String menuItem = mi.getText(); + + if(menuItem.compareTo("Add field") == 0) + { + model.addField(view.addFieldDialog()); + } + } + +} diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/model/ContextManager.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/model/ContextManager.java new file mode 100644 index 0000000..94a8699 --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/model/ContextManager.java @@ -0,0 +1,75 @@ +package osgi.bundle.monitoring.dem1.model; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; + +/** + * Provides methods to manage bundles in the OSGi BundleContext + * @author Anibal + */ +public class ContextManager +{ + + private BundleContext bundleContext; + + public ContextManager(BundleContext bundleContext) + { + this.bundleContext = bundleContext; + } + + public void installBundle(String file) + { + try + { + bundleContext.installBundle("file:"+file); + } catch (BundleException e) + { + + } + } + + public void uninstallBundle(long id) + { + try + { + bundleContext.getBundle(id).uninstall(); + } catch (BundleException e) + { + + } + } + + public void updateBundle(long id) + { + try + { + bundleContext.getBundle(id).update(); + } catch (BundleException e) + { + + } + } + + public void startBundle(long id) + { + try + { + bundleContext.getBundle(id).start(); + } catch (BundleException e) + { + + } + } + + public void stopBundle(long id) + { + try + { + bundleContext.getBundle(id).stop(); + } catch (BundleException e) + { + + } + } + +} diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/model/FieldEvent.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/model/FieldEvent.java new file mode 100644 index 0000000..0b1e6bf --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/model/FieldEvent.java @@ -0,0 +1,26 @@ +package osgi.bundle.monitoring.dem1.model; + +public class FieldEvent +{ + + private String className; + + private String fieldName; + + public FieldEvent(String className, String fieldName) + { + this.className = className; + this.fieldName = fieldName; + } + + public String getClassName() + { + return className; + } + + public String getFieldName() + { + return fieldName; + } + +} diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/model/Model.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/model/Model.java new file mode 100644 index 0000000..51a8d27 --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/model/Model.java @@ -0,0 +1,95 @@ +package osgi.bundle.monitoring.dem1.model; + +import org.osgi.framework.BundleContext; + +import osgi.bundle.monitoring.dem1.view.View; + +/** + * Provides an API with the actions the user can perform + * @author Anibal + */ +public class Model +{ + + private Monitor monitor; + + private ContextManager contextManager; + + public Model(BundleContext bundleContext) + { + monitor = new Monitor(bundleContext); + + contextManager = new ContextManager(bundleContext); + } + + public void installBundle(String fileName) + { + contextManager.installBundle(fileName); + } + + public void uninstallBundle(long id) + { + contextManager.uninstallBundle(id); + } + + public void updateBundle(long id) + { + contextManager.updateBundle(id); + } + + public void startBundle(long id) + { + contextManager.startBundle(id); + } + + public void stopBundle(long id) + { + contextManager.stopBundle(id); + } + + public void setIdOpened(long id) + { + monitor.setIdOpened(id); + } + + public void setIdClosed(long id) + { + monitor.setIdClosed(id); + } + + public void setMonitorOn(int index) + { + monitor.setMonitorOn(index); + } + + public void setMonitorOff(int index) + { + monitor.setMonitorOff(index); + } + + public void setTypeOpened(int index, int type) + { + monitor.setTypeOpened(index, type); + } + + public void setTypeClosed(int index, int type) + { + monitor.setTypeClosed(index, type); + } + + public void addObserver(View view) + { + monitor.addObserver(view); + } + + public void addField(String s) + { + monitor.addField(s); + } + + public void unregisterServices() + { + monitor.uniregisterServices(); + } + +} diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/model/Monitor.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/model/Monitor.java new file mode 100644 index 0000000..1c6df32 --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/model/Monitor.java @@ -0,0 +1,177 @@ +package osgi.bundle.monitoring.dem1.model; + +import java.util.ArrayList; +import java.util.Observable; +import java.util.Observer; + +import org.osgi.framework.BundleContext; + +import osgi.framework.monitoring.event.DataFieldMonitor; +import osgi.framework.monitoring.event.ManifestMonitor; +import osgi.framework.monitoring.event.RepositoryMonitor; +import osgi.framework.monitoring.event.StateMonitor; +import osgi.framework.monitoring.event.EventMonitor; +import osgi.framework.monitoring.event.filter.IdFilterSet; +import osgi.framework.monitoring.event.filter.TypeFilterSet; + +/** + * Manages the different types of monitors: repository monitor, state monitor, + * manifest monitor and data field monitor + * @author Anibal + */ +public class Monitor extends Observable implements Observer +{ + // Contains all monitor objects + private ArrayList bundleMonitors; + + // Contains all type filer for the various monitors + private ArrayList typeFilters; + + private IdFilterSet idFilter; + + /** + * Constructor. Initialize the different monitors + * @param bundleContext + */ + public Monitor(BundleContext bundleContext) + { + bundleMonitors = new ArrayList(); + + typeFilters = new ArrayList(); + + idFilter = new IdFilterSet(); + + // Positions in array 0: RepositoryMonitor, 1: StateMonitor, 2: ManifestMonitor, 3: DataFieldMonitor + bundleMonitors.add(new RepositoryMonitor(bundleContext)); + bundleMonitors.add(new StateMonitor(bundleContext)); + bundleMonitors.add(new ManifestMonitor(bundleContext)); + bundleMonitors.add(new DataFieldMonitor(bundleContext)); + + // Set the type filter sets to each monitor object + for(int i = 0; i < bundleMonitors.size() - 1; i++) + { + typeFilters.add(new TypeFilterSet()); + bundleMonitors.get(i).setTypeFilterSet(typeFilters.get(i)); + bundleMonitors.get(i).setBundleFilterSet(idFilter); + } + + // Registers necessary services for DataFieldMonitor + ((DataFieldMonitor)bundleMonitors.get(3)).registerWeavingService(); + + // StateMonitor activated by default + setMonitorOn(1); + } + + /** + * Activate monitor object + * @param index 0: RepositoryMonitor, 1: StateMonitor, 2: ManifestMonitor, 3: DataFieldMonitor + */ + public void setMonitorOn(int index) + { + bundleMonitors.get(index).addObserver(this); + } + + /** + * Deactivate monitor object + * @param index 0: RepositoryMonitor, 1: StateMonitor, 2: ManifestMonitor, 3: DataFieldMonitor + */ + public void setMonitorOff(int index) + { + bundleMonitors.get(index).deleteObservers(); + } + + /** + * Open or close type in one TypeFilterSet + * @param typeFilterSet + * @param type type of event + * @param open true: opened, false: closed + */ + private void setType(TypeFilterSet typeFilterSet, int type, Boolean open) + { + typeFilterSet.addEntry(type, open); + } + + /** + * Open type in one TypeFilterSet + * @param index 0: RepositoryMonitor, 1: StateMonitor, 2: ManifestMonitor, 3: DataFieldMonitor + * @param type type of event + */ + public void setTypeOpened(int index, int type) + { + setType(typeFilters.get(index), type, true); + } + + /** + * Close type in one TypeFilterSet + * @param index 0: RepositoryMonitor, 1: StateMonitor, 2: ManifestMonitor, 3: DataFieldMonitor + * @param type type of event + */ + public void setTypeClosed(int index, int type) + { + setType(typeFilters.get(index), type, false); + } + + /** + * Open or close bundle in one IdFilterSet + * @param idBundle + * @param mode true: opened, false: closed + */ + private void setId(long idBundle, boolean mode) + { + idFilter.addEntry(idBundle, mode); + } + + /** + * Open bundle in one IdFilterSet + * @param idBundle + */ + public void setIdOpened(long idBundle) + { + setId(idBundle, true); + } + + /** + * Close bundle in one IdFilterSet + * @param idBundle + */ + public void setIdClosed(long idBundle) + { + setId(idBundle, false); + } + + /** + * Add a new field and class to be instrumented + * @param s format: "field/class" + */ + public void addField(String s) + { + String[] ss = s.split("/"); + if(ss.length == 2) + { + if(((DataFieldMonitor)bundleMonitors.get(3)).addDataField(ss[0], ss[1])) + { + setChanged(); + notifyObservers(new FieldEvent(ss[0], ss[1])); + } + } + } + + /* (non-Javadoc) + * @see java.util.Observer#update(java.util.Observable, java.lang.Object) + */ + @Override + public void update(Observable obs, Object obj) + { + setChanged(); + notifyObservers(obj); + } + + /** + * Unregisters necessary services for DataFieldMonitor + */ + public void uniregisterServices() + { + ((DataFieldMonitor)bundleMonitors.get(3)).unregisterWeavingService(); + } + +} diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/BundleTable.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/BundleTable.java new file mode 100644 index 0000000..18ab980 --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/BundleTable.java @@ -0,0 +1,136 @@ +package osgi.bundle.monitoring.dem1.view; + +import java.awt.Dimension; + +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleEvent; + +public class BundleTable extends JScrollPane +{ + + private static final long serialVersionUID = 1L; + + JTable bundleTable; + + BundleTableModel tableModel; + + public BundleTable(int x, int y) + { + tableModel = new BundleTableModel(); + + bundleTable = new JTable(tableModel); + bundleTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + bundleTable.getColumnModel().getColumn(0).setPreferredWidth(75); + bundleTable.getColumnModel().getColumn(1).setPreferredWidth(75); + bundleTable.getColumnModel().getColumn(2).setPreferredWidth(150); + bundleTable.getColumnModel().getColumn(3).setPreferredWidth(300); + + setViewportView(bundleTable); + setPreferredSize(new Dimension(x, y)); + } + + private String getBundleState(int state) + { + switch(state) + { + case Bundle.UNINSTALLED: + return "Uninstalled"; + case Bundle.INSTALLED: + return "Installed"; + case Bundle.RESOLVED: + return "Resolved"; + case Bundle.STARTING: + return "Starting"; + case Bundle.STOPPING: + return "Stopping"; + case Bundle.ACTIVE: + return "Active"; + } + + return "Unknown"; + } + + private void addBundle(Bundle bundle) + { + tableModel.insertRow(true, + bundle.getBundleId(), + getBundleState(bundle.getState()), + bundle.getSymbolicName()); + } + + private void modifyBundle(Bundle bundle) + { + tableModel.modifyState(bundle.getBundleId(), + getBundleState(bundle.getState())); + } + + private void removeBundle(long id) + { + tableModel.deleteRow(id); + } + + public void changeBundle(BundleEvent be) + { + switch(be.getType()) + { + case BundleEvent.INSTALLED: + addBundle(be.getBundle()); + break; + case BundleEvent.LAZY_ACTIVATION: + modifyBundle(be.getBundle()); + break; + case BundleEvent.RESOLVED: + modifyBundle(be.getBundle()); + break; + case BundleEvent.STARTED: + modifyBundle(be.getBundle()); + break; + case BundleEvent.STARTING: + modifyBundle(be.getBundle()); + break; + case BundleEvent.STOPPED: + modifyBundle(be.getBundle()); + break; + case BundleEvent.STOPPING: + modifyBundle(be.getBundle()); + break; + case BundleEvent.UNINSTALLED: + removeBundle(be.getBundle().getBundleId()); + break; + case BundleEvent.UNRESOLVED: + modifyBundle(be.getBundle()); + break; + case BundleEvent.UPDATED: + modifyBundle(be.getBundle()); + break; + } + } + + public long getSelectedBundleId() + { + int index = bundleTable.getSelectedRow(); + + if(index >= 0) + { + return tableModel.idOfRow(index); + } + + return -1; + } + + public void checkMonitor(long id) + { + tableModel.modifyMonitoring(id, true); + } + + public void uncheckMonitor(long id) + { + tableModel.modifyMonitoring(id, false); + } + +} \ No newline at end of file diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/BundleTableModel.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/BundleTableModel.java new file mode 100644 index 0000000..232290b --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/BundleTableModel.java @@ -0,0 +1,143 @@ +package osgi.bundle.monitoring.dem1.view; + +import java.util.ArrayList; + +import javax.swing.table.AbstractTableModel; + +public class BundleTableModel extends AbstractTableModel +{ + + private static final long serialVersionUID = 1L; + + private String[] columnNames = + {"Monitoring", + "Id", + "State", + "Symbolic Name" + }; + + private ArrayList> data; + + public BundleTableModel() + { + data = new ArrayList>(); + } + + @Override + public int getColumnCount() + { + return columnNames.length; + } + + @Override + public int getRowCount() + { + return data.size(); + } + + public String getColumnName(int col) + { + return columnNames[col]; + } + + @Override + public Object getValueAt(int row, int col) + { + return data.get(row).get(col); + } + + public Class getColumnClass(int col) + { + return getValueAt(0, col).getClass(); + } + + public void setValueAt(Object value, int row, int col) + { + if(row == data.size()) + { + data.add(new ArrayList()); + data.get(row).add(value); + data.get(row).add(null); + data.get(row).add(null); + data.get(row).add(null); + fireTableDataChanged(); + } + else if(row < data.size()) + { + data.get(row).set(col, value); + fireTableCellUpdated(row, col); + } + } + + public void insertRow(Boolean monitoring, long id, String state, String name) + { + int row = data.size(); + + setValueAt(monitoring, row, 0); + setValueAt(id, row, 1); + setValueAt(state, row, 2); + setValueAt(name, row, 3); + } + + private int rowOfId(long id) + { + int first = 0; + int last = data.size() - 1; + + int middle; + + while((first <= last)) + { + middle = (int)(first + ((last - first)/2)); + + if(id < (long)data.get(middle).get(1)) + { + last = middle - 1; + } + else if(id > (long)data.get(middle).get(1)) + { + first = middle + 1; + } + else + { + return middle; + } + } + + return -1; + } + + public void modifyState(long id, String state) + { + int row = rowOfId(id); + + if(row > -1) + { + setValueAt(state, row, 2); + } + } + + public void modifyMonitoring(long id, Boolean monitoring) + { + int row = rowOfId(id); + + if(row > -1) + { + setValueAt(monitoring, row, 0); + } + } + + public void deleteRow(long id) + { + int row = rowOfId(id); + + data.remove(row); + fireTableDataChanged(); + } + + public long idOfRow(int row) + { + return (long)data.get(row).get(1); + } + +} diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/LeftPane.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/LeftPane.java new file mode 100644 index 0000000..647df2d --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/LeftPane.java @@ -0,0 +1,100 @@ +package osgi.bundle.monitoring.dem1.view; + +import java.awt.Container; +import java.awt.Dimension; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JLabel; + +import org.osgi.framework.BundleEvent; + +import osgi.framework.monitoring.event.DataFieldEvent; +import osgi.framework.monitoring.event.RepositoryEvent; +import osgi.framework.monitoring.event.ManifestEvent; + +public class LeftPane extends Container +{ + + private static final long serialVersionUID = 1L; + + private LogList logList; + + private BundleTable bundleTable; + + public LeftPane() + { + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + addFillerToYPane(); + addLabelToPane("Installed bundles"); + addBundleListToPane(600, 150); + addFillerToYPane(); + addLabelToPane("Monitoring log"); + addLogListToPane(600, 200); + addFillerToYPane(); + } + + private void addFillerToYPane() + { + add(Box.createRigidArea(new Dimension(0, 25))); + } + + private void addLabelToPane(String text) + { + JLabel label = new JLabel(text); + add(label); + } + + private void addLogListToPane(int x, int y) + { + logList = new LogList(x, y); + + add(logList); + } + + private void addBundleListToPane(int x, int y) + { + bundleTable = new BundleTable(x, y); + + add(bundleTable); + } + + public void checkEvent(Object event) + { + String className = event.getClass().getName(); + + if(className.compareTo(RepositoryEvent.class.getName()) == 0) + { + logList.logFileEvent((RepositoryEvent)event); + } + else if(className.compareTo(BundleEvent.class.getName()) == 0) + { + bundleTable.changeBundle((BundleEvent)event); + logList.logBundleEvent((BundleEvent)event); + } + else if(className.compareTo(ManifestEvent.class.getName()) == 0) + { + logList.logManifestEvent((ManifestEvent)event); + } + else if(className.compareTo(DataFieldEvent.class.getName()) == 0) + { + logList.logDataFieldEvent((DataFieldEvent)event); + } + } + + public long getSelectedBundleId() + { + return bundleTable.getSelectedBundleId(); + } + + public void checkMonitor(long id) + { + bundleTable.checkMonitor(id); + } + + public void uncheckMonitor(long id) + { + bundleTable.uncheckMonitor(id); + } + +} diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/LogList.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/LogList.java new file mode 100644 index 0000000..12993b6 --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/LogList.java @@ -0,0 +1,157 @@ +package osgi.bundle.monitoring.dem1.view; + +import java.awt.Dimension; + +import javax.swing.DefaultListModel; +import javax.swing.JList; +import javax.swing.JScrollPane; +import javax.swing.ListSelectionModel; + +import org.osgi.framework.BundleEvent; + +import osgi.framework.monitoring.event.DataFieldEvent; +import osgi.framework.monitoring.event.RepositoryEvent; +import osgi.framework.monitoring.event.ManifestEvent; + +public class LogList extends JScrollPane +{ + + private static final long serialVersionUID = 1L; + + private JList listLog; + + private DefaultListModel listModelLog; + + public LogList(int x, int y) + { + listLog = new JList(); + + listModelLog = new DefaultListModel(); + + listLog.setModel(listModelLog); + + setViewportView(listLog); + setPreferredSize(new Dimension(x, y)); + + listLog.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + } + + public void insertList(String message) + { + listModelLog.addElement(message); + } + + public void insertListLog(String message) + { + try + { + Thread.sleep(10); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + + insertList(message); + } + + public String getFileEvent(int type) + { + switch(type) + { + case RepositoryEvent.ENTRY_CREATE: + return "Created"; + case RepositoryEvent.ENTRY_MODIFY: + return "Modified"; + case RepositoryEvent.ENTRY_DELETE: + return "Deleted"; + } + + return "Unknown"; + } + + private String getBundleEvent(int type) + { + switch(type) + { + case BundleEvent.INSTALLED: + return "Installed"; + case BundleEvent.LAZY_ACTIVATION: + return "Lazily activated"; + case BundleEvent.RESOLVED: + return "Resolved"; + case BundleEvent.STARTED: + return "Started"; + case BundleEvent.STARTING: + return "Activated"; + case BundleEvent.STOPPED: + return "Stopped"; + case BundleEvent.STOPPING: + return "Deactivated"; + case BundleEvent.UNINSTALLED: + return "Uninstalled"; + case BundleEvent.UNRESOLVED: + return "Unresolved"; + case BundleEvent.UPDATED: + return "Updated"; + } + + return "Unknown"; + } + + private String getManifestEvent(int type) + { + switch(type) + { + case ManifestEvent.CREATED: + return "Created"; + case ManifestEvent.MODIFIED: + return "Modified"; + case ManifestEvent.DELETED: + return "Deleted"; + } + + return "Unknown"; + } + + public void logFileEvent(RepositoryEvent fe) + { + String message = "Bundle repository: bundle "+ + fe.getBundle().getBundleId()+ + " file "+ + getFileEvent(fe.getType()); + insertListLog(message); + } + + public void logBundleEvent(BundleEvent be) + { + String message = "Bundle state: bundle "+ + be.getBundle().getBundleId()+ + " "+ + getBundleEvent(be.getType()); + insertListLog(message); + } + + public void logManifestEvent(ManifestEvent me) + { + String message = "Bundle manifest: bundle "+ + me.getBundle().getBundleId()+ + " manifest modified: "+ + me.getHeader()+ + " "+ + getManifestEvent(me.getType()); + insertListLog(message); + } + + public void logDataFieldEvent(DataFieldEvent dfe) + { + String message = "Data field: "+ + dfe.getFieldName()+ + " in "+ + dfe.getClassName()+ + " has changed to "+ + dfe.getField(); + insertListLog(message); + } + +} \ No newline at end of file diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/Menu.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/Menu.java new file mode 100644 index 0000000..adcc29f --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/Menu.java @@ -0,0 +1,147 @@ +package osgi.bundle.monitoring.dem1.view; + +import java.util.ArrayList; + +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; + +import osgi.bundle.monitoring.dem1.controller.CheckBoxMenuListener; +import osgi.bundle.monitoring.dem1.controller.MenuItemListener; + +public class Menu extends JMenuBar +{ + + private static final long serialVersionUID = 1L; + + private ArrayList checkBoxesMonitor; + + private ArrayList checkBoxesRepFilter; + + private ArrayList checkBoxesStatFilter; + + private ArrayList checkBoxesManFilter; + + private JMenuItem addInstItem; + + private JMenu instrumentationMenu; + + public Menu() + { + checkBoxesMonitor = new ArrayList(); + + checkBoxesRepFilter = new ArrayList(); + + checkBoxesStatFilter = new ArrayList(); + + checkBoxesManFilter = new ArrayList(); + + JMenu monitorMenu, filterMenu, repSubMenu, statSubMenu, manSubMenu; + + monitorMenu = new JMenu("Monitors"); + + checkBoxesMonitor.add(new JCheckBoxMenuItem("Bundle repository")); + checkBoxesMonitor.add(new JCheckBoxMenuItem("Bundle state")); + checkBoxesMonitor.add(new JCheckBoxMenuItem("Bundle manifest")); + checkBoxesMonitor.add(new JCheckBoxMenuItem("Data field")); + + for(JCheckBoxMenuItem checkBox: checkBoxesMonitor) + { + monitorMenu.add(checkBox); + } + + checkBoxesMonitor.get(1).setState(true); + + filterMenu = new JMenu("Filters"); + + repSubMenu = new JMenu("Bundle repository"); + statSubMenu = new JMenu("Bundle state"); + manSubMenu = new JMenu("Bundle manifest"); + + checkBoxesRepFilter.add(new JCheckBoxMenuItem("Create")); + checkBoxesRepFilter.add(new JCheckBoxMenuItem("Modify")); + checkBoxesRepFilter.add(new JCheckBoxMenuItem("Delete")); + + for(JCheckBoxMenuItem checkBox: checkBoxesRepFilter) + { + repSubMenu.add(checkBox); + checkBox.setState(true); + } + + checkBoxesStatFilter.add(new JCheckBoxMenuItem("Installed")); + checkBoxesStatFilter.add(new JCheckBoxMenuItem("Lazy Activation")); + checkBoxesStatFilter.add(new JCheckBoxMenuItem("Resolved")); + checkBoxesStatFilter.add(new JCheckBoxMenuItem("Started")); + checkBoxesStatFilter.add(new JCheckBoxMenuItem("Starting")); + checkBoxesStatFilter.add(new JCheckBoxMenuItem("Stopped")); + checkBoxesStatFilter.add(new JCheckBoxMenuItem("Stopping")); + checkBoxesStatFilter.add(new JCheckBoxMenuItem("Uninstalled")); + checkBoxesStatFilter.add(new JCheckBoxMenuItem("Unresolved")); + checkBoxesStatFilter.add(new JCheckBoxMenuItem("Updated")); + + for(JCheckBoxMenuItem checkBox: checkBoxesStatFilter) + { + statSubMenu.add(checkBox); + checkBox.setState(true); + } + + checkBoxesManFilter.add(new JCheckBoxMenuItem("Created")); + checkBoxesManFilter.add(new JCheckBoxMenuItem("Modified")); + checkBoxesManFilter.add(new JCheckBoxMenuItem("Deleted")); + + for(JCheckBoxMenuItem checkBox: checkBoxesManFilter) + { + manSubMenu.add(checkBox); + checkBox.setState(true); + } + + filterMenu.add(repSubMenu); + filterMenu.add(statSubMenu); + filterMenu.add(manSubMenu); + + instrumentationMenu = new JMenu("Instrumentation"); + + addInstItem = new JMenuItem("Add field"); + + instrumentationMenu.add(addInstItem); + instrumentationMenu.addSeparator(); + + add(monitorMenu); + add(filterMenu); + add(instrumentationMenu); + } + + public void completeMenu(CheckBoxMenuListener checkBoxMenuListener, MenuItemListener menuItemListener) + { + for(JCheckBoxMenuItem checkBox: checkBoxesMonitor) + { + checkBox.addActionListener(checkBoxMenuListener); + } + + for(JCheckBoxMenuItem checkBox: checkBoxesRepFilter) + { + checkBox.addActionListener(checkBoxMenuListener); + } + + for(JCheckBoxMenuItem checkBox: checkBoxesStatFilter) + { + checkBox.addActionListener(checkBoxMenuListener); + } + + for(JCheckBoxMenuItem checkBox: checkBoxesManFilter) + { + checkBox.addActionListener(checkBoxMenuListener); + } + + addInstItem.addActionListener(menuItemListener); + } + + public void addField(String className, String fieldName, CheckBoxMenuListener checkBoxMenuListener) + { + JCheckBoxMenuItem checkBoxMenuItem = new JCheckBoxMenuItem(className+" "+fieldName); + instrumentationMenu.add(checkBoxMenuItem); + checkBoxMenuItem.addActionListener(checkBoxMenuListener); + } + +} diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/RightPane.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/RightPane.java new file mode 100644 index 0000000..78ca307 --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/RightPane.java @@ -0,0 +1,63 @@ +package osgi.bundle.monitoring.dem1.view; + +import java.awt.Container; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.util.ArrayList; + +import javax.swing.Box; +import javax.swing.JButton; + +import osgi.bundle.monitoring.dem1.controller.ButtonListener; + +public class RightPane extends Container +{ + + private static final long serialVersionUID = 1L; + + private ArrayList buttons; + + public RightPane() + { + setLayout(new GridLayout(15, 1)); + + buttons = new ArrayList(); + + addFillerToYPane(); + addButtonToPane("Install"); + addFillerToYPane(); + addButtonToPane("Uninstall"); + addFillerToYPane(); + addButtonToPane("Update"); + addFillerToYPane(); + addButtonToPane("Start"); + addFillerToYPane(); + addButtonToPane("Stop"); + addFillerToYPane(); + addButtonToPane("Monitor"); + addFillerToYPane(); + addButtonToPane("Unmonitor"); + addFillerToYPane(); + } + + private void addFillerToYPane() + { + add(Box.createRigidArea(new Dimension(0, 25))); + } + + private void addButtonToPane(String text) + { + JButton button = new JButton(text); + buttons.add(button); + add(button); + } + + public void completeRightPane(ButtonListener buttonListener) + { + for(JButton button: buttons) + { + button.addMouseListener(buttonListener); + } + } + +} diff --git a/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/View.java b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/View.java new file mode 100644 index 0000000..799fbcf --- /dev/null +++ b/osgi.bundle.monitoring.dem1/src/osgi/bundle/monitoring/dem1/view/View.java @@ -0,0 +1,133 @@ +package osgi.bundle.monitoring.dem1.view; + +import java.awt.Container; +import java.awt.Dimension; +import java.util.Observable; +import java.util.Observer; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JOptionPane; + +import osgi.bundle.monitoring.dem1.controller.ButtonListener; +import osgi.bundle.monitoring.dem1.controller.CheckBoxMenuListener; +import osgi.bundle.monitoring.dem1.controller.MenuItemListener; +import osgi.bundle.monitoring.dem1.model.FieldEvent; + +public class View implements Observer +{ + + private JFrame mainFrame; + + private LeftPane leftPane; + + private RightPane rightPane; + + private Menu menu; + + private CheckBoxMenuListener checkBoxMenuListener; + + public View() + { + rightPane = new RightPane(); + + leftPane = new LeftPane(); + + menu = new Menu(); + } + + private static void addFillerToXPane(Container pane) + { + pane.add(Box.createRigidArea(new Dimension(25, 0))); + } + + private void addComponentsToPane(Container pane) + { + pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS)); + + addFillerToXPane(pane); + pane.add(leftPane); + addFillerToXPane(pane); + pane.add(rightPane); + addFillerToXPane(pane); + } + + public void initUi() + { + mainFrame = new JFrame("Monitoring System: demonstrator 1"); + + mainFrame.setJMenuBar(menu); + addComponentsToPane(mainFrame.getContentPane()); + + mainFrame.pack(); + mainFrame.setResizable(false); + mainFrame.setVisible(true); + } + + public String installDialog() + { + JFileChooser fc = new JFileChooser(); + + int returnVal = fc.showOpenDialog(mainFrame); + + if(returnVal == JFileChooser.APPROVE_OPTION) + { + return fc.getSelectedFile().getName(); + } + + return null; + } + + public String addFieldDialog() + { + return JOptionPane.showInputDialog(mainFrame, "Please, introduce the fully qualified name of class and field (e.g. for String class and foo field \"java.lang.String/foo\"):", "New Field", JOptionPane.PLAIN_MESSAGE); + } + + public void completeUi(ButtonListener buttonListener, CheckBoxMenuListener checkBoxMenuListener, MenuItemListener menuItemListener) + { + this.checkBoxMenuListener = checkBoxMenuListener; + + rightPane.completeRightPane(buttonListener); + + menu.completeMenu(checkBoxMenuListener, menuItemListener); + } + + public long getSelectedBundleId() + { + return leftPane.getSelectedBundleId(); + } + + public void checkMonitoring(long id) + { + leftPane.checkMonitor(id); + } + + public void uncheckMonitoring(long id) + { + leftPane.uncheckMonitor(id); + } + + public void close() + { + mainFrame.setVisible(false); + mainFrame.dispose(); + } + + @Override + public void update(Observable obs, Object obj) + { + String className = obj.getClass().getName(); + + if(className.compareTo(FieldEvent.class.getName()) == 0) + { + FieldEvent fe = (FieldEvent)obj; + menu.addField(fe.getClassName(), fe.getFieldName(), checkBoxMenuListener); + } + else + { + leftPane.checkEvent(obj); + } + } + +}