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