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.doc/config.properties.core b/mosgi.doc/config.properties.core
index fb3f010..c7cc576 100644
--- a/mosgi.doc/config.properties.core
+++ b/mosgi.doc/config.properties.core
@@ -21,7 +21,8 @@
file:../mosgi.jmx.registry/target/org.apache.felix.mosgi.jmx.registry-0.8.0-SNAPSHOT.jar \
file:../mosgi.jmx.rmiconnector/target/org.apache.felix.mosgi.jmx.rmiconnector-0.8.0-SNAPSHOT.jar \
file:../mosgi.console.ifc/target/org.apache.felix.mosgi.console.ifc-0.8.0-SNAPSHOT.jar \
- file:../mosgi.managedelements.osgiprobes/target/org.apache.felix.mosgi.managedelements.osgiprobes-0.8.0-SNAPSHOT.jar
+ file:../mosgi.managedelements.osgiprobes/target/org.apache.felix.mosgi.managedelements.osgiprobes-0.8.0-SNAPSHOT.jar \
+ file:../mosgi.managedelements.bundlesprobes/target/org.apache.felix.mosgi.managedelements.bundlesprobes-0.8.0-SNAPSHOT.jar
# if we need the http jmx connector
# file:../mosgi.jmx.httpconnector/target/org.apache.felix.mosgi.jmx.httpconnector-0.8.0-SNAPSHOT.jar
@@ -341,6 +342,7 @@
version="1.5.0"
insa.jmxconsole.tab.url.osgiprobestab=file:../mosgi.managedelements.osgiprobes.tab/target/org.apache.felix.mosgi.managedelements.osgiprobes.tab-0.8.0-SNAPSHOT.jar
+insa.jmxconsole.tab.url.bundlesprobestab=file:../mosgi.managedelements.bundlesprobes.tab/target/org.apache.felix.mosgi.managedelements.bundlesprobes.tab-0.8.0-SNAPSHOT.jar
insa.jmxconsole.ip1=127.0.0.1
insa.jmxconsole.profile1=core
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);
+ }
+ }
+}
diff --git a/mosgi.managedelements.bundlesprobes/pom.xml b/mosgi.managedelements.bundlesprobes/pom.xml
new file mode 100644
index 0000000..406604c
--- /dev/null
+++ b/mosgi.managedelements.bundlesprobes/pom.xml
@@ -0,0 +1,67 @@
+<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 JMX MBean for OSGi bundles management</name>
+ <artifactId>org.apache.felix.mosgi.managedelements.bundlesprobes</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 JMX MBean for OSGi bundles management</bundleName>
+ <bundleDescription>MOSGi JMX MBean for OSGi bundles management</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>
+ org.osgi.framework;specification-version="1.0.0",
+ org.osgi.service.log;specification-version="1.0.0",
+ javax.management;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/src/main/java/org/apache/felix/mosgi/managedelements/bundlesprobes/BundlesProbes.java b/mosgi.managedelements.bundlesprobes/src/main/java/org/apache/felix/mosgi/managedelements/bundlesprobes/BundlesProbes.java
new file mode 100644
index 0000000..42b17cb
--- /dev/null
+++ b/mosgi.managedelements.bundlesprobes/src/main/java/org/apache/felix/mosgi/managedelements/bundlesprobes/BundlesProbes.java
@@ -0,0 +1,251 @@
+/*
+ * 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;
+
+/**
+ * TODO : Should listen to Agent Service lifecycle
+ * Need to change ObjectName
+ * Should listen to serviceLifecycle
+**/
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Vector;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.ObjectName;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.AttributeChangeNotification;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+
+import org.osgi.service.log.LogService;
+
+public class BundlesProbes extends NotificationBroadcasterSupport implements BundleActivator, BundlesProbesMBean, ServiceListener, BundleListener {
+
+ private String version = null;
+ private static String tabNameString = "TabUI:name=BundlesProbes";
+
+ private ObjectName tabName = null;
+ private MBeanServer server = null;
+ private BundleContext bc = null;
+ private ServiceReference sr = null;
+
+
+ ////////////////////////////////////////////////////////
+ // TabIfc (from BundlesProbesMBean) //
+ ////////////////////////////////////////////////////////
+ public String getBundleName() {
+ return this.bc.getProperty("insa.jmxconsole.tab.url.bundlesprobestab");
+ }
+
+
+ ////////////////////////////////////////////////////////
+ // BundleActivator //
+ ////////////////////////////////////////////////////////
+ public void start(BundleContext context) throws Exception {
+ this.bc=context;
+ this.version=(String)bc.getBundle().getHeaders().get(Constants.BUNDLE_VERSION);
+ this.log(LogService.LOG_INFO, "Starting BundlesProbe MBean " + this.version,null);
+ this.tabName=new ObjectName(tabNameString);
+ this.sr = context.getServiceReference(MBeanServer.class.getName());
+ if (sr!=null){
+ this.connectToAgent(sr);
+ }
+ this.log(LogService.LOG_INFO, "BundlesProbes MBean "+this.version+" started", null);
+ }
+
+
+ public void stop(BundleContext context) {
+ this.log(LogService.LOG_INFO, "Stopping BundlesProbes MBean "+this.version, null);
+ if (this.server!=null){
+ this.disconnectFromAgent();
+ }
+ this.sr=null;
+ this.log(LogService.LOG_INFO, "BundlesProbes MBean "+this.version+" stopped", null);
+ this.bc=null;
+ }
+
+ ////////////////////////////////////////////////////////
+ // BundlesProbesMBean //
+ ////////////////////////////////////////////////////////
+ public Vector bundleList() {
+ Bundle[] bl = this.bc.getBundles();
+ Vector bundleList = new Vector();
+ Vector bundle = null;
+ for (int i = 0; i < bl.length; i++) {
+ bundle = new Vector();
+ String enum1 = (String) bl[i].getHeaders().get(Constants.BUNDLE_NAME);
+ long id = bl[i].getBundleId();
+ bundle.add(new Long(id));
+ int state = bl[i].getState();
+ switch (state) {
+ case Bundle.ACTIVE:
+ bundle.add(new String("ACTIVE"));
+ break;
+ case Bundle.INSTALLED:
+ bundle.add(new String("INSTALLED"));
+ break;
+ case Bundle.RESOLVED:
+ bundle.add(new String("RESOLVED"));
+ break;
+ case Bundle.UNINSTALLED:
+ bundle.add(new String("UNINSTALLED"));
+ break;
+ default:
+ bundle.add(new String("RESOLVED"));
+ }
+ bundle.add(enum1);
+ bundleList.add(bundle);
+ }
+ return bundleList;
+ }
+
+ public void startService(Long [] id) {
+ try {
+ bc.getBundle(id[0].longValue()).start();
+ } catch (BundleException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void stopService(Long [] id) {
+ try {
+ bc.getBundle(id[0].longValue()).stop();
+ } catch (BundleException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void install(String location) {
+ try {
+ bc.installBundle(location);
+ } catch (BundleException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void uninstall(Long [] id) {
+ try {
+ bc.getBundle(id[0].longValue()).uninstall();
+ } catch (BundleException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void update(Long [] id) {
+ try {
+ bc.getBundle(id[0].longValue()).update();
+ } catch (BundleException e) {
+ e.printStackTrace();
+ }
+ }
+
+ ////////////////////////////////////////////////////////
+ // ServiceListener //
+ ////////////////////////////////////////////////////////
+ public void serviceChanged(ServiceEvent event) {
+ ServiceReference sr=event.getServiceReference();
+ Object service=bc.getService(sr);
+ if (this.server==null && event.getType()==ServiceEvent.REGISTERED && service instanceof MBeanServer){
+ this.connectToAgent(sr);
+ }
+ if (this.server!=null){
+ if(event.getType()==ServiceEvent.UNREGISTERING && service instanceof MBeanServer){
+ this.disconnectFromAgent();
+ }else{
+ this.sendRemoteNotification(ServiceEvent.class.getName(),sr.getBundle().getBundleId(), event.getType(), (String)sr.getBundle().getHeaders().get(Constants.BUNDLE_NAME));
+ }
+ }
+ }
+
+ ////////////////////////////////////////////////////////
+ // BundleListener //
+ ////////////////////////////////////////////////////////
+ public void bundleChanged(BundleEvent event) {
+ if (this.server!=null){
+ Bundle b=event.getBundle();
+ //SFR this.sendRemoteNotification(BundleEvent.class.getName(), b.getBundleId(), b.getState(), (String)b.getHeaders().get(Constants.BUNDLE_NAME));
+System.out.println("Evenement bundle "+b.getBundleId()+" : "+event.getType());
+ this.sendRemoteNotification(BundleEvent.class.getName(), b.getBundleId(), event.getType(), (String)b.getHeaders().get(Constants.BUNDLE_NAME));
+ }
+ }
+
+ private void sendRemoteNotification(String className, long id, int type, String name){
+ StringBuffer str = new StringBuffer(className);
+ str.append(":");
+ str.append(id);
+ str.append(":");
+ str.append(type);
+ str.append(":");
+ str.append(name);
+ super.sendNotification(new AttributeChangeNotification(this.tabName, 0, 0,str.toString(),null, "Bundle", null, null));
+ }
+
+ private void connectToAgent(ServiceReference sr){
+ this.log(LogService.LOG_INFO, "Registering to agent", null);
+ try{
+ this.server=(MBeanServer)this.bc.getService(sr);
+ this.server.registerMBean(this, tabName);
+ this.bc.addServiceListener(this);
+ this.bc.addBundleListener(this);
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ this.log(LogService.LOG_INFO, "Registered to agent", null);
+ }
+
+ private void disconnectFromAgent(){
+ this.log(LogService.LOG_INFO, "Unregistering from agent", null);
+ this.bc.removeServiceListener(this);
+ this.bc.removeBundleListener(this);
+ try {
+ server.unregisterMBean(tabName);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ this.server=null;
+ this.bc.ungetService(this.sr);
+ this.log(LogService.LOG_INFO, "Unregistered from agent", null);
+ }
+
+ private void log(int prio, String message, Throwable t){
+ if (this.bc!=null){
+ ServiceReference logSR=this.bc.getServiceReference(LogService.class.getName());
+ if (logSR!=null){
+ ((LogService)this.bc.getService(logSR)).log(prio, message, t);
+ }else{
+ System.out.println("No Log Service");
+ }
+ }else{
+ System.out.println(this.getClass().getName()+".log: No bundleContext");
+ }
+ }
+
+}
diff --git a/mosgi.managedelements.bundlesprobes/src/main/java/org/apache/felix/mosgi/managedelements/bundlesprobes/BundlesProbesMBean.java b/mosgi.managedelements.bundlesprobes/src/main/java/org/apache/felix/mosgi/managedelements/bundlesprobes/BundlesProbesMBean.java
new file mode 100644
index 0000000..4b3dfba
--- /dev/null
+++ b/mosgi.managedelements.bundlesprobes/src/main/java/org/apache/felix/mosgi/managedelements/bundlesprobes/BundlesProbesMBean.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+import org.apache.felix.mosgi.console.ifc.TabIfc;
+import java.util.Vector;
+
+public interface BundlesProbesMBean extends TabIfc {
+ public Vector bundleList();
+
+ public void startService(Long [] id);
+ public void stopService(Long [] id);
+ public void install(String location);
+ public void uninstall(Long[] id);
+ public void update(Long [] id);
+}
diff --git a/pom.xml b/pom.xml
index d884574..c584d3a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -101,6 +101,8 @@
<module>mosgi.jmx.rmiconnector</module>
<module>mosgi.managedelements.osgiprobes</module>
<module>mosgi.managedelements.osgiprobes.tab</module>
+ <module>mosgi.managedelements.bundlesprobes</module>
+ <module>mosgi.managedelements.bundlesprobes.tab</module>
<module>ipojo.plugin</module>
<module>ipojo.arch</module>