Adding a tab for remotely managing bundles through a jmx console

- bundlesprobes : is the mbean enabling bundle management
- bundlesprobes.tab : is the graphical component automatically
  integrated in the jmxconsole



git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@438464 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/mosgi.managedelements.bundlesprobes.tab/pom.xml b/mosgi.managedelements.bundlesprobes.tab/pom.xml
new file mode 100644
index 0000000..978481a
--- /dev/null
+++ b/mosgi.managedelements.bundlesprobes.tab/pom.xml
@@ -0,0 +1,69 @@
+<project>
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>osgi-bundle</packaging>
+  <name>MOSGi Bundles management tab for the JMX console</name>
+  <artifactId>org.apache.felix.mosgi.managedelements.bundlesprobes.tab</artifactId>
+  <dependencies>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.mosgi.console.ifc</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.framework</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix.plugins</groupId>
+        <artifactId>maven-osgi-plugin</artifactId>
+        <version>${pom.version}</version>
+        <extensions>true</extensions>
+        <configuration>
+          <osgiManifest>
+            <bundleName>MOSGi Bundles management tab for the JMX console</bundleName>
+            <bundleDescription>MOSGi Bundles management tab for the JMX console</bundleDescription>
+            <bundleActivator>auto-detect</bundleActivator>
+            <bundleDocUrl>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/</bundleDocUrl>
+            <bundleUrl>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}.jar</bundleUrl>
+            <bundleSource>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}-src.jar</bundleSource>
+            <bundleSymbolicName>${pom.artifactId}</bundleSymbolicName>
+            <exportPackage>
+              ${pom.artifactId};specification-version="1.0.0"
+            </exportPackage>
+            <importPackage>
+              javax.management;specification-version="1.0.0",
+              org.osgi.framework;specification-version="1.0.0",
+              javax.management.openmbean;specification-version="1.0.0",
+              javax.swing;specification-version="1.0.0",
+              javax.swing.table;specification-version="1.0.0",
+              org.apache.felix.mosgi.console.ifc;specification-version="1.0.0"
+            </importPackage>
+          </osgiManifest>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/mosgi.managedelements.bundlesprobes.tab/src/main/java/org/apache/felix/mosgi/managedelements/bundlesprobes/tab/BundlesProbesModelTabUI.java b/mosgi.managedelements.bundlesprobes.tab/src/main/java/org/apache/felix/mosgi/managedelements/bundlesprobes/tab/BundlesProbesModelTabUI.java
new file mode 100644
index 0000000..9c9911a
--- /dev/null
+++ b/mosgi.managedelements.bundlesprobes.tab/src/main/java/org/apache/felix/mosgi/managedelements/bundlesprobes/tab/BundlesProbesModelTabUI.java
@@ -0,0 +1,162 @@
+/*

+ *   Copyright 2005 The Apache Software Foundation

+ *

+ *   Licensed under the Apache License, Version 2.0 (the "License");

+ *   you may not use this file except in compliance with the License.

+ *   You may obtain a copy of the License at

+ *

+ *       http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *   Unless required by applicable law or agreed to in writing, software

+ *   distributed under the License is distributed on an "AS IS" BASIS,

+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *   See the License for the specific language governing permissions and

+ *   limitations under the License.

+ *

+ */

+package org.apache.felix.mosgi.managedelements.bundlesprobes.tab;

+

+import java.util.Iterator;

+import java.util.StringTokenizer;

+import java.util.Vector;

+import java.util.Hashtable;

+

+import javax.management.MBeanServerConnection;

+import javax.management.ObjectName;

+import javax.management.openmbean.ArrayType;

+import javax.management.openmbean.SimpleType;

+import javax.management.Notification;

+import javax.management.NotificationListener;

+

+import javax.swing.table.DefaultTableModel;

+

+import org.osgi.framework.Bundle;

+import org.osgi.framework.BundleEvent;

+

+public class BundlesProbesModelTabUI extends DefaultTableModel implements NotificationListener  { 

+  private static final String OSGI_ON="TabUI:name=BundlesProbes";

+

+  private MBeanServerConnection mbsc = null;

+  private Hashtable eventName=new Hashtable();

+  private ObjectName osgiON=null;

+

+  public BundlesProbesModelTabUI() throws Exception{

+    super(new String[]{"Id", "State", "Location"}, 1);

+    eventName.put(new Integer(Bundle.UNINSTALLED), "UNINSTALLED");

+    eventName.put(new Integer(Bundle.INSTALLED), "INSTALLED");

+    eventName.put(new Integer(Bundle.RESOLVED), "RESOLVED");

+    eventName.put(new Integer(Bundle.STARTING), "STARTING");

+    eventName.put(new Integer(Bundle.STOPPING), "STOPPING");

+    eventName.put(new Integer(Bundle.ACTIVE), "ACTIVE");

+    osgiON=new ObjectName(OSGI_ON);

+  }

+

+  ///////////////////////////////

+  //   DefaultTableModel       //

+  ///////////////////////////////

+  public boolean isCellEditable(int row, int col){

+    return false;

+  }

+

+  private void removeAll(){

+    int size=this.getRowCount();

+    if (size!=0){

+      for (int i=0; i<size;i++){

+        super.removeRow(0);

+      }

+      super.fireTableRowsDeleted(0, size-1);

+    }

+  }

+

+  private void insertRows() throws Exception{

+    Vector bundleList= (Vector) mbsc.invoke(this.osgiON, "bundleList", null, null);

+    Iterator iterator = bundleList.iterator();

+    this.removeAll();

+    int i=0;

+    while (iterator.hasNext()) {

+      Vector vector = (Vector) iterator.next();

+      this.addRow(vector);

+      i++;

+    }

+    super.fireTableRowsInserted(0, i-1);

+  }

+

+  /////////////////////////////////////////////

+  //        NotificationListener             //

+  /////////////////////////////////////////////

+  public void handleNotification(Notification notification, Object handback) {

+    boolean found=false;

+    StringTokenizer st=new StringTokenizer(notification.getMessage(), ":");

+    String eventClassName=st.nextToken();

+    long id=Long.parseLong(st.nextToken());

+    int type=Integer.parseInt(st.nextToken());

+    String bundleName=st.nextToken();

+

+System.out.println("))"+id+":"+type+":"+ this.eventName.get(new Integer(type)));

+    if (eventClassName.equals(BundleEvent.class.getName())){

+      int row=0;

+      for (; row<this.getRowCount(); row++) {

+        if (((Long)this.getValueAt(row, 0)).longValue()==id) {

+          found=true;

+          break;

+        }

+      }

+      if (type==Bundle.INSTALLED && !found){

+        super.addRow(new Object[]{new Long(id), this.eventName.get(new Integer(type)), bundleName});

+        super.fireTableRowsInserted(row, row);

+      }else {

+        super.setValueAt(this.eventName.get(new Integer(type)), row, 1);

+        super.fireTableRowsUpdated(row, row);

+

+      }

+

+    }

+  }

+

+  ////////////////////////////////////////////////

+  //          Main Class                       //

+  ////////////////////////////////////////////////

+  public void createBundleList(MBeanServerConnection conn) throws Exception {

+    this.mbsc=conn;

+    mbsc.addNotificationListener(this.osgiON, this, null, null);

+    this.insertRows();

+  }

+

+  public void emptyPanel(){

+    if (this.mbsc!=null){

+      try{

+        mbsc.removeNotificationListener(this.osgiON, this);

+        this.mbsc=null;

+        this.removeAll();

+      }catch(Exception e){

+        e.printStackTrace();

+      }

+    }

+  }

+

+	public void installButtonAction(String text) throws Exception {

+System.out.println("=>"+text);

+		mbsc.invoke(this.osgiON, "install", new Object[] {text}, new String[]{String.class.getName()});

+	}

+

+	public void startButtonAction(Long id) throws Exception {

+		mbsc.invoke(this.osgiON, "startService", new Object[] {new Long [] {id}} , new String[]{new ArrayType(1, SimpleType.LONG).getTypeName()});

+	}

+

+	public void stopButtonAction(Long id) throws Exception {

+		mbsc.invoke(this.osgiON, "stopService",new Object[] {new Long [] {id}} , new String[]{new ArrayType(1, SimpleType.LONG).getTypeName()});

+	}

+

+	public void updateButtonAction(Long id) throws Exception {

+		mbsc.invoke(this.osgiON, "update", new Object[] {new Long [] {id}} , new String[]{new ArrayType(1, SimpleType.LONG).getTypeName()});

+	}

+

+	public void refreshButtonAction() throws Exception {

+    this.insertRows();

+	}

+

+	public void uninstallButtonAction(Long id) throws Exception {

+		mbsc.invoke(this.osgiON, "uninstall", new Object[] {new Long [] {id}} , new String[]{new ArrayType(1, SimpleType.LONG).getTypeName()});

+	}

+

+}

diff --git a/mosgi.managedelements.bundlesprobes.tab/src/main/java/org/apache/felix/mosgi/managedelements/bundlesprobes/tab/BundlesProbesTabUI.java b/mosgi.managedelements.bundlesprobes.tab/src/main/java/org/apache/felix/mosgi/managedelements/bundlesprobes/tab/BundlesProbesTabUI.java
new file mode 100644
index 0000000..9074d19
--- /dev/null
+++ b/mosgi.managedelements.bundlesprobes.tab/src/main/java/org/apache/felix/mosgi/managedelements/bundlesprobes/tab/BundlesProbesTabUI.java
@@ -0,0 +1,234 @@
+/*

+ *   Copyright 2005 The Apache Software Foundation

+ *

+ *   Licensed under the Apache License, Version 2.0 (the "License");

+ *   you may not use this file except in compliance with the License.

+ *   You may obtain a copy of the License at

+ *

+ *       http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *   Unless required by applicable law or agreed to in writing, software

+ *   distributed under the License is distributed on an "AS IS" BASIS,

+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *   See the License for the specific language governing permissions and

+ *   limitations under the License.

+ *

+ */

+package org.apache.felix.mosgi.managedelements.bundlesprobes.tab;

+

+import java.awt.BorderLayout;

+import java.awt.Dimension;

+import java.awt.FlowLayout;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+

+import javax.management.MBeanServerConnection;

+import java.awt.Component;

+import javax.swing.BorderFactory;

+import javax.swing.JButton;

+import javax.swing.JLabel;

+import javax.swing.JOptionPane;

+import javax.swing.JPanel;

+import javax.swing.JScrollPane;

+import javax.swing.JTable;

+import javax.swing.JTextField;

+import javax.swing.ListSelectionModel;

+import javax.swing.table.TableColumn;

+

+import org.apache.felix.mosgi.console.ifc.Plugin;

+

+import java.beans.PropertyChangeEvent;

+

+import org.osgi.framework.BundleActivator;

+import org.osgi.framework.BundleActivator;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.ServiceRegistration;

+

+public class BundlesProbesTabUI extends JPanel implements BundleActivator, ActionListener, Plugin {

+  private JTable table;

+

+  private JTextField urlTextField;

+  private JButton installButton;

+  private JButton startButton;

+  private JButton stopButton;

+  private JButton updateButton;

+  private JButton refreshButton;

+  private JButton uninstallButton;

+

+  private BundlesProbesModelTabUI panelModel = null;

+  private BundleContext m_context=null;

+  private ServiceRegistration sreg = null;

+  private MBeanServerConnection mbsc=null;

+

+  ///////////////////////////////////////////

+  //           BundleActivator             //

+  ///////////////////////////////////////////

+  public void start(BundleContext context) {

+    m_context = context;

+    this.registerServicePlugin();

+  }

+  

+  public void stop(BundleContext context) {

+  }

+

+  ///////////////////////////////////////////////

+  //               Plugin                      //

+  ///////////////////////////////////////////////

+  public void registerServicePlugin(){

+    sreg = m_context.registerService(Plugin.class.getName(), this, null);

+  }

+

+  public void unregisterServicePlugin(){

+    sreg.unregister();

+  }

+

+  public String pluginLocation(){

+    return m_context.getBundle().getLocation();

+  }

+  public String getName(){ return "Bundles List"; }

+  public Component getGUI(){ return this; }

+  public void propertyChange(PropertyChangeEvent ee){

+    String action=ee.getPropertyName();

+    if (action.equals(Plugin.NEW_NODE_READY)){

+      this.mbsc=(MBeanServerConnection)ee.getNewValue();

+    }else if(action.equals(Plugin.EMPTY_NODE)){

+      panelModel.emptyPanel();

+      this.mbsc=null;

+    }else if(action.equals(Plugin.PLUGIN_ACTIVATED) && ee.getNewValue().equals(this.getName())){

+      try {

+        panelModel.createBundleList(this.mbsc);

+        invalidate();

+        validate();

+      } catch (Exception ex) {

+        ex.printStackTrace();

+      }

+    }

+  }

+

+  public BundlesProbesTabUI() throws Exception {

+    panelModel = new BundlesProbesModelTabUI();

+    setLayout(new BorderLayout());

+    add(createInstallPanel(), BorderLayout.NORTH);

+    add(createTablePanel(), BorderLayout.CENTER);

+    add(createMgmntButtonsPanel(), BorderLayout.SOUTH);

+  }

+

+  private void initColumnSizes(JTable table) {

+    TableColumn column = null;

+    for (int i = 0; i < 3; i++) {

+      column = table.getColumnModel().getColumn(i);

+      if ((i == 0) || (i == 1))

+        column.setPreferredWidth(5);

+      if (i == 2)

+        column.setPreferredWidth(200);

+    }

+  }

+

+  private JPanel createInstallPanel() {

+    JPanel installPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));

+    installPanel.setBorder(BorderFactory.createEtchedBorder());

+    installPanel.add(new JLabel("URL: "), BorderLayout.WEST);

+

+    urlTextField = new JTextField(35);

+    urlTextField.addActionListener(this);

+    installPanel.add(urlTextField, BorderLayout.CENTER);

+

+    installButton = new JButton("Install");

+    installButton.setMnemonic('I');

+    installButton.addActionListener(this);

+    installPanel.add(installButton, BorderLayout.EAST);

+    return installPanel;

+  }

+

+  private JScrollPane createTablePanel() {

+    table = new JTable(panelModel);

+    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

+    table.getTableHeader().setReorderingAllowed(false);

+    initColumnSizes(table);

+    JScrollPane tablePanel = new JScrollPane(table);

+    tablePanel.setBorder(BorderFactory.createEtchedBorder());

+    return tablePanel;

+  }

+

+  private JPanel createMgmntButtonsPanel() {

+    JPanel mgmntButtonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));

+    mgmntButtonsPanel.setBorder(BorderFactory.createEtchedBorder());

+    startButton = new MyButton('S', "Start", this, mgmntButtonsPanel);

+    stopButton = new MyButton('p', "Stop", this, mgmntButtonsPanel);

+    updateButton = new MyButton('a', "Update", this, mgmntButtonsPanel);

+    refreshButton = new MyButton('R', "Refresh", this, mgmntButtonsPanel);

+    uninstallButton = new MyButton('U', "Uninstall", this, mgmntButtonsPanel);

+    return mgmntButtonsPanel;

+  }

+

+  public void actionPerformed(ActionEvent e) {

+    Object object = e.getSource();

+    if ((object == installButton) || (object == urlTextField)) {

+      try {

+        String jarPath = urlTextField.getText();

+        jarPath = jarPath.trim();

+        panelModel.installButtonAction(jarPath);

+      } catch (Exception ex) {

+        JOptionPane.showMessageDialog(this, ex.getClass().getName(),

+            "Install Error", JOptionPane.ERROR_MESSAGE);

+      }

+    } else if (object == startButton) {

+      try {

+        panelModel.startButtonAction((Long) (table.getValueAt(table

+            .getSelectedRow(), 0)));

+      } catch (Exception ex) {

+        JOptionPane.showMessageDialog(this, ex.getClass().getName(),

+            "Start Error", JOptionPane.ERROR_MESSAGE);

+      }

+    } else if (object == stopButton) {

+      try {

+        panelModel.stopButtonAction((Long) (table.getValueAt(table

+            .getSelectedRow(), 0)));

+      } catch (Exception ex) {

+        /*

+        JOptionPane.showMessageDialog(this, ex.getClass().getName(),

+            "Stop Error", JOptionPane.ERROR_MESSAGE);

+            */

+        ex.printStackTrace();

+      }

+    } else if (object == updateButton) {

+      try {

+        panelModel.updateButtonAction((Long) (table.getValueAt(table

+            .getSelectedRow(), 0)));

+      } catch (Exception ex) {

+        JOptionPane.showMessageDialog(this, ex.getClass().getName(),

+            "Update Error", JOptionPane.ERROR_MESSAGE);

+      }

+    } else if (object == refreshButton) {

+      try {

+        panelModel.refreshButtonAction();

+      } catch (Exception ex) {

+        JOptionPane.showMessageDialog(this, ex.getClass().getName(),

+            "Refresh Error", JOptionPane.ERROR_MESSAGE);

+      }

+    } else if (object == uninstallButton) {

+      try {

+        panelModel.uninstallButtonAction((Long) (table.getValueAt(table

+            .getSelectedRow(), 0)));

+      } catch (Exception ex) {

+        JOptionPane.showMessageDialog(this, ex.getClass().getName(),

+            "Uninstall Error", JOptionPane.ERROR_MESSAGE);

+      }

+    }

+  }

+

+static class MyButton extends JButton {

+    private int W = 85;

+    private int H = 25;

+

+    public MyButton(char c, String name, BundlesProbesTabUI listener, JPanel panel) {

+      super.setText(name);

+      super.setMnemonic(c);

+      super.setMinimumSize(new Dimension(W, H));

+      super.setPreferredSize(new Dimension(W, H));

+      super.setMaximumSize(new Dimension(W, H));

+      super.addActionListener(listener);

+      panel.add(this);

+    }

+  }

+}