The JMX console gui
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@424263 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.mosgi.console.gui/pom.xml b/org.apache.felix.mosgi.console.gui/pom.xml
new file mode 100644
index 0000000..637286b
--- /dev/null
+++ b/org.apache.felix.mosgi.console.gui/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 Console Main GUI</name>
+ <artifactId>org.apache.felix.mosgi.console.gui</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.framework</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>
+ </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 Console main GUI</bundleName>
+ <bundleDescription>MOSGi JMX Console main GUI</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>
+ <importPackage>
+ org.osgi.framework;specification-version="1.0.0",
+ javax.swing;specification-version="1.0.0",
+ javax.swing.event;specification-version="1.0.0",
+ javax.swing.tree;specification-version="1.0.0",
+ javax.management;specification-version="1.0.0",
+ javax.management.remote;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/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/Activator.java b/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/Activator.java
new file mode 100644
index 0000000..0abd057
--- /dev/null
+++ b/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/Activator.java
@@ -0,0 +1,219 @@
+/*
+ * 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.console.gui;
+
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import javax.swing.JFrame;
+import javax.swing.JRootPane;
+import javax.swing.JSplitPane;
+import javax.swing.event.EventListenerList;
+
+import org.apache.felix.mosgi.console.ifc.Plugin;
+import org.apache.felix.mosgi.console.ifc.CommonPlugin;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.InvalidSyntaxException;
+
+public class Activator implements BundleActivator {
+ protected BundleContext m_context = null;
+ protected ArrayList m_pluginList = null;
+ protected ArrayList m_commonpluginList = null; //TODO To I need this table ?
+ private EventListenerList m_listenerList = null;
+ private JFrame m_frame = null;
+ private NodesTree nodesTree=null;
+
+ public Activator() {
+ m_pluginList = new ArrayList();
+ m_commonpluginList = new ArrayList();
+ m_listenerList = new EventListenerList();
+ }
+
+ public void start(BundleContext context) {
+ m_context = context;
+
+ // Listen for factory service events.
+ ServiceListener sl = new ServiceListener() {
+ public void serviceChanged(ServiceEvent event) {
+ ServiceReference ref = event.getServiceReference();
+ Object svcObj = m_context.getService(ref);
+ if (event.getType() == ServiceEvent.REGISTERED) {
+ synchronized (Activator.this) {
+ // !!!!!!!!!! ORDER MATTERS (Inheritance pb)
+ if (!m_pluginList.contains(svcObj)) {
+ if(svcObj instanceof CommonPlugin){
+ m_commonpluginList.add(svcObj);
+ firePropertyChangedEvent(CommonPlugin.COMMON_PLUGIN_ADDED, null, svcObj);
+ }else if (svcObj instanceof Plugin){
+ m_pluginList.add(svcObj);
+ firePropertyChangedEvent(Plugin.PLUGIN_ADDED, null, svcObj);
+ }
+ }
+ }
+ } else if (event.getType() == ServiceEvent.UNREGISTERING) {
+ synchronized (Activator.this) {
+ removePropertyChangeListener((PropertyChangeListener)svcObj);
+ if(svcObj instanceof CommonPlugin){
+ m_commonpluginList.remove(svcObj);
+ firePropertyChangedEvent(CommonPlugin.COMMON_PLUGIN_REMOVED, null, svcObj);
+ }else if (svcObj instanceof Plugin){
+ m_pluginList.remove(svcObj);
+ firePropertyChangedEvent(Plugin.PLUGIN_REMOVED, null, svcObj);
+ }
+ }
+ } else {
+ m_context.ungetService(ref);
+ }
+ }
+ };
+ try
+ {
+ m_context.addServiceListener(sl,
+ "(|(objectClass="
+ + Plugin.class.getName()
+ + ")(objectClass="
+ + CommonPlugin.class.getName()+"))");
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ System.err.println("ShellGuiActivator: Cannot add service listener.");
+ System.err.println("ShellGuiActivator: " + ex);
+ }
+
+
+ // Create and display the frame.
+ if (m_frame == null)
+ {
+ m_frame=new JFrame("OSGi GUI Remote Manager");
+ m_frame.setUndecorated(true);
+ m_frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
+ Dimension wndSize = m_frame.getToolkit().getScreenSize();
+ m_frame.setBounds(wndSize.width / 8, wndSize.height / 8, 1000, 700);
+ m_frame.setIconImage(Toolkit.getDefaultToolkit().getImage(m_context.getBundle().getResource("images/logo.gif")));
+
+ //Right panel
+ JSplitPane rightSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, new NodePanel(this, context) , new CommonPanel(this));
+ rightSplitPane.setOneTouchExpandable(true);
+ rightSplitPane.setDividerLocation(500);
+
+ //General Panel
+ this.nodesTree = new NodesTree(this, context);
+ JSplitPane gSplitPane=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, this.nodesTree , rightSplitPane);
+ gSplitPane.setOneTouchExpandable(true);
+ gSplitPane.setDividerLocation(200);
+
+
+ m_frame.getContentPane().add(gSplitPane);
+ //m_frame.setResizable(false);
+ m_frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ }
+
+ // Now try to manually initialize the plugin list
+ // since some might already be available.
+ //initializePlugins();
+ this.nodesTree.runDiscovery();
+
+ m_frame.setVisible(true);
+ }
+
+ private synchronized void initializePlugins() {
+ try {
+ // Get all model services.
+ Object svcObj=null;
+ ServiceReference refs[] = m_context.getServiceReferences(Plugin.class.getName(), null);
+ if (refs != null) {
+ // Add model services to list, ignore duplicates.
+ for (int i = 0; i < refs.length; i++) {
+ svcObj = m_context.getService(refs[i]);
+ if (!m_pluginList.contains(svcObj)) {
+ m_pluginList.add(svcObj);
+ firePropertyChangedEvent(Plugin.PLUGIN_ADDED, null, (Plugin)svcObj);
+ }
+ }
+ }
+ // Get all common plugins
+ refs = m_context.getServiceReferences(CommonPlugin.class.getName(), null);
+ if (refs != null) {
+ for (int i = 0; i < refs.length; i++) {
+ svcObj = m_context.getService(refs[i]);
+ if (!m_commonpluginList.contains(svcObj)) {
+ m_commonpluginList.add(svcObj);
+ firePropertyChangedEvent(CommonPlugin.COMMON_PLUGIN_ADDED, null, (CommonPlugin)svcObj);
+ }
+ }
+ }
+ } catch (Exception ex) {
+ System.err.println("ShellGuiActivator: Error initializing model list.");
+ System.err.println("ShellGuiActivator: " + ex);
+ ex.printStackTrace();
+ }
+ }
+
+ public void stop(BundleContext context)
+ {
+ if (m_frame != null)
+ { this.nodesTree.stop();
+ m_frame.setVisible(false);
+ m_frame.dispose();
+ m_frame = null;
+ }
+ }
+
+ //
+ // Event methods.
+ //
+
+ public void addPropertyChangeListener(PropertyChangeListener l)
+ {
+ m_listenerList.add(PropertyChangeListener.class, l);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener l)
+ {
+ m_listenerList.remove(PropertyChangeListener.class, l);
+ }
+
+ public void firePropertyChangedEvent(String name, Object oldValue, Object newValue)
+ {
+ PropertyChangeEvent event = null;
+
+ // Guaranteed to return a non-null array
+ Object[] listeners = m_listenerList.getListenerList();
+
+ // Process the listeners last to first, notifying
+ // those that are interested in this event
+ for (int i = listeners.length - 2; i >= 0; i -= 2)
+ {
+ if (listeners[i] == PropertyChangeListener.class)
+ {
+ // Lazily create the event:
+ if (event == null)
+ {
+ event = new PropertyChangeEvent(this, name, oldValue, newValue);
+ }
+ ((PropertyChangeListener) listeners[i + 1]).propertyChange(event);
+ }
+ }
+ }
+}
diff --git a/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/CommonPanel.java b/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/CommonPanel.java
new file mode 100644
index 0000000..bad4c8b
--- /dev/null
+++ b/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/CommonPanel.java
@@ -0,0 +1,45 @@
+/*
+ * 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.console.gui;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.JTabbedPane;
+
+import org.apache.felix.mosgi.console.ifc.CommonPlugin;
+
+public class CommonPanel extends JTabbedPane implements PropertyChangeListener {
+ Activator beanEventBroadcaster;
+
+ public CommonPanel(Activator activator){
+ this.beanEventBroadcaster=activator;
+ this.beanEventBroadcaster.addPropertyChangeListener(this);
+ }
+
+ public void propertyChange(PropertyChangeEvent event) {
+ if (event.getPropertyName().equals(CommonPlugin.COMMON_PLUGIN_ADDED)) {
+ CommonPlugin cp=(CommonPlugin)event.getNewValue();
+ this.add(cp.getName(), cp.getGUI());
+ this.beanEventBroadcaster.addPropertyChangeListener(cp);
+ }
+ if (event.getPropertyName().equals(CommonPlugin.COMMON_PLUGIN_REMOVED)){
+ CommonPlugin cp=(CommonPlugin)event.getNewValue();
+ this.remove(cp.getGUI());
+ this.beanEventBroadcaster.removePropertyChangeListener(cp);
+ }
+ }
+}
diff --git a/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/NodeCellRenderer.java b/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/NodeCellRenderer.java
new file mode 100644
index 0000000..c6f2015
--- /dev/null
+++ b/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/NodeCellRenderer.java
@@ -0,0 +1,56 @@
+/*
+ * 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.console.gui;
+
+import java.awt.Component;
+import java.awt.Toolkit;
+
+import javax.swing.ImageIcon;
+import javax.swing.JTree;
+import javax.swing.tree.DefaultTreeCellRenderer;
+
+import org.osgi.framework.BundleContext;
+
+public class NodeCellRenderer extends DefaultTreeCellRenderer {
+ private ImageIcon iconConnected;
+ private ImageIcon iconStopped;
+ private NodesTree nodesTree;
+
+ public NodeCellRenderer(BundleContext m_context, NodesTree nt){
+ this.iconConnected=new ImageIcon(Toolkit.getDefaultToolkit().getImage(m_context.getBundle().getResource("images/ServerRunning.gif")));
+ this.iconStopped=new ImageIcon(Toolkit.getDefaultToolkit().getImage(m_context.getBundle().getResource("images/ServerBlocked.gif")));
+ this.nodesTree=nt;
+ }
+
+ public Component getTreeCellRendererComponent(JTree tree, Object value,
+ boolean sel, boolean expanded, boolean leaf, int row,
+ boolean hasFocus) {
+
+ super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
+ row, hasFocus);
+ String val=value.toString();
+ if (!val.equals(NodesTree.TOP_NAME)){
+ if (nodesTree.isNodeConnected(val)){
+ setIcon(iconConnected);
+ }else{
+ setIcon(iconStopped);
+ }
+ }
+ return this;
+ }
+}
+
diff --git a/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/NodePanel.java b/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/NodePanel.java
new file mode 100644
index 0000000..281fdae
--- /dev/null
+++ b/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/NodePanel.java
@@ -0,0 +1,193 @@
+/*
+ * 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.console.gui;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
+import java.net.URLClassLoader;
+import java.rmi.server.RMIClassLoader;
+import java.rmi.server.RMIClassLoaderSpi;
+import java.security.SecureClassLoader;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Set;
+import javax.swing.JTabbedPane;
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+//import javax.management.MalformedObjectNameException;
+import javax.management.MBeanException;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import org.apache.felix.mosgi.console.ifc.Plugin;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceReference;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.ChangeEvent;
+
+public class NodePanel extends JTabbedPane implements PropertyChangeListener, ChangeListener {
+ //private String repo;
+ private Activator m_activator = null;
+ private BundleContext m_context = null;
+
+ private Hashtable pluginList = null;
+
+ public NodePanel(Activator activator, BundleContext context){
+ m_context = context;
+ m_activator = activator;
+ m_activator.addPropertyChangeListener(this);
+ this.pluginList = new Hashtable();
+ //repo = m_context.getProperty("insa.jmxconsole.repository");
+ this.addChangeListener(this);
+ }
+
+ //////////////////////////////////////
+ // ChangeListener Implementation
+ //////////////////////////////////////
+ public void stateChanged(ChangeEvent e){
+// System.out.println("coucou => "+((JTabbedPane)e.getSource()).getSelectedIndex()+":"+((JTabbedPane)e.getSource()).getSelectedComponent().getName());
+ if (this.getSelectedComponent()!=null){
+ m_activator.firePropertyChangedEvent(Plugin.PLUGIN_ACTIVATED, null, this.getSelectedComponent().getName());
+ }
+ }
+
+
+ public void propertyChange(PropertyChangeEvent event) {
+ if (event.getPropertyName().equals(Plugin.PLUGIN_ADDED)) {
+ Plugin cp = (Plugin) event.getNewValue();
+ this.add(cp.getName(), cp.getGUI());
+System.out.println("add gui "+cp.getName()+" :: "+cp.getGUI());
+ this.m_activator.addPropertyChangeListener(cp);
+ this.pluginList.put(cp.pluginLocation(), cp);
+
+ }else if(event.getPropertyName().equals(Plugin.PLUGIN_REMOVED)) {
+ Plugin cp = (Plugin) event.getNewValue();
+ this.remove(cp.getGUI());
+ this.m_activator.removePropertyChangeListener(cp);
+// this.pluginList.remove(cp.pluginLocation());
+
+ }else if(event.getPropertyName().equals(Plugin.EMPTY_NODE)) {
+System.out.println("******* Debug No node selected");
+ this.clean();
+ }else if (event.getPropertyName().equals(Plugin.NEW_NODE_SELECTED)) {
+//System.out.println("Event NEW_NODE_SELECTED");
+ /* Update the tabs (Plugin) in the JTabbedPane (NodePanel) */
+ MBeanServerConnection mbsc = (MBeanServerConnection)event.getNewValue();
+ try {
+ this.clean();
+
+ Set ons = mbsc.queryNames( null, null );
+ for( Iterator i=ons.iterator(); i.hasNext(); ) {
+ ObjectName name = ( ObjectName )i.next();
+System.out.println("Queried name: "+name.toString());
+ if ( "TabUI".equals(name.getDomain()) ) {
+System.out.println("New tab: "+name.toString());
+ /* Get the plugin implementation via a bundle */
+ String tabBundle = (String) mbsc.getAttribute(name, "BundleName");
+System.out.println("Bundle name for current Plugin: "+tabBundle);
+ if (tabBundle!=null){
+ Plugin p = (Plugin) this.pluginList.get(tabBundle);
+ if (p == null){
+ Bundle b = m_context.installBundle(tabBundle);
+ b.start();
+System.out.println("Bundle started");
+//Thread.sleep(5000);
+ }else{
+System.out.println("register service plugin: " + p);
+ p.registerServicePlugin();
+ }
+
+// ServiceReference[] sr = b.getRegisteredServices();
+// System.out.println(sr);
+// Plugin p;
+// for (int j=0 ; j < sr.length ; j++) {
+// p=(Plugin)m_context.getService(sr[j]);
+// this.add(p.getName(), p.getGUI());
+// this.m_activator.addPropertyChangeListener(p);
+// }
+
+// System.out.println("Delegation for this");
+// printcl = this.getClass().getClassLoader();
+// while (printcl != null) {
+// System.out.println(printcl);
+// printcl = printcl.getParent();
+// }
+// System.out.println("{bootstrap loader}");
+// System.out.println("");
+
+ /* Get the tab object */
+// Object tabObj = mbsc.getAttribute(name, "Tab");
+//
+// System.out.println("Delegation for tabObj: " + tabObj);
+// printcl = tabObj.getClass().getClassLoader();
+// while (printcl != null) {
+// System.out.println(printcl);
+// printcl = printcl.getParent();
+// }
+// System.out.println("{bootstrap loader}");
+// System.out.println("");
+
+// System.out.println("tabObj.getName(): " + ((fr.inria.ares.managedelements.testprobe.tab.TestProbeTabUI) tabObj).getName());
+
+ /* Cast the tab */
+// Plugin tab = (Plugin)tabObj;
+ /* register the tab on the JTabbedPane */
+// this.add(tab.getName(), tab.getGUI());
+ }else{
+ System.out.println("No "+tabBundle+" property defined. I cannot install "+tabBundle+" tab");
+ }
+ }
+ }
+ m_activator.firePropertyChangedEvent(Plugin.NEW_NODE_READY, null, mbsc);
+ m_activator.firePropertyChangedEvent(Plugin.PLUGIN_ACTIVATED, null, this.getComponentAt(0).getName());
+
+
+ } catch (MBeanException e) {
+ System.err.println(e);
+// } catch (MalformedObjectNameException e) {
+// System.err.println(e);
+ } catch (AttributeNotFoundException e) {
+ System.err.println(e);
+ } catch (InstanceNotFoundException e) {
+ System.err.println(e);
+ } catch (ReflectionException e) {
+ System.err.println(e);
+ } catch (IOException e) {
+ System.err.println(e);
+ } catch (BundleException e) {
+ System.err.println(e);
+ }
+
+// catch (java.lang.InterruptedException e) {
+// System.err.println(e);
+// }
+ }
+ }
+
+ private void clean(){
+ this.removeAll();
+ for ( Iterator i=pluginList.keySet().iterator(); i.hasNext();) {
+ ((Plugin) pluginList.get(i.next())).unregisterServicePlugin();
+ }
+ }
+
+}
diff --git a/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/NodesTree.java b/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/NodesTree.java
new file mode 100644
index 0000000..f98c636
--- /dev/null
+++ b/org.apache.felix.mosgi.console.gui/src/main/java/org/apache/felix/mosgi/console/gui/NodesTree.java
@@ -0,0 +1,260 @@
+/*
+ * 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.console.gui;
+
+import java.awt.GridLayout;
+import java.util.Hashtable;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTree;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeSelectionModel;
+
+import org.osgi.framework.BundleContext;
+
+import org.apache.felix.mosgi.console.ifc.Plugin;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.NotificationListener;
+import javax.management.Notification;
+import javax.management.MalformedObjectNameException;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.JMXConnectionNotification;
+
+import org.apache.felix.framework.cache.BundleCache;
+
+
+public class NodesTree extends JPanel implements TreeSelectionListener, NotificationListener {
+ static String TOP_NAME="Servers";
+ static int POOLING_TIME=10000;
+
+ protected JTree tree;
+ private DefaultTreeModel dtm;
+ private Hashtable connectedNodes = new Hashtable();
+ private Hashtable jmxConnectors = new Hashtable();
+ private DefaultMutableTreeNode top = null;
+ protected boolean cont=true;
+
+ private static boolean useSystemLookAndFeel = false;
+
+ private Activator a;
+ private BundleContext bc;
+ private PoolingThread pt;
+ protected Thread poolThread;
+ private NodeCellRenderer ncr;
+ private Hashtable nodes=new Hashtable();
+
+
+ public NodesTree(Activator a,BundleContext bc) {
+ super(new GridLayout(1, 0));
+ this.a=a;
+ this.bc=bc;
+ this.pt=new PoolingThread();
+
+ System.setProperty("java.security.policy", "client.policy");
+ top = new DefaultMutableTreeNode(NodesTree.TOP_NAME);
+ dtm=new DefaultTreeModel(top);
+ tree = new JTree(dtm);
+ tree.setCellRenderer(ncr=new NodeCellRenderer(bc,this));
+ tree.addTreeSelectionListener(this);
+ tree.getSelectionModel().setSelectionMode(
+ TreeSelectionModel.SINGLE_TREE_SELECTION);
+
+ JScrollPane treeView = new JScrollPane(tree);
+ add(treeView);
+ }
+
+ public void runDiscovery(){
+ this.createDefaultNodes(true);
+ poolThread=new Thread(this.pt);
+ poolThread.start();
+ }
+
+ //////////////////////////////////////////////////////
+ // TreeSelectionListener //
+ //////////////////////////////////////////////////////
+ public void valueChanged(TreeSelectionEvent e) {
+// System.out.println("coucou, value changed");
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
+ String selectedNode=(String)node.getUserObject();
+ if (!selectedNode.equals(NodesTree.TOP_NAME)){
+ Object mbsc=connectedNodes.get(selectedNode);
+ if (mbsc!=null){
+ a.firePropertyChangedEvent(Plugin.NEW_NODE_SELECTED, selectedNode, mbsc);
+ }else{
+ a.firePropertyChangedEvent(Plugin.EMPTY_NODE, null, "null");
+ }
+ }
+ }
+
+ ////////////////////////////////////////////////////
+ // NotificationListener //
+ ////////////////////////////////////////////////////
+ public void handleNotification(Notification notification, Object handback) {
+// System.out.println("Connection ==> "+notification.getMessage()+":"+((JMXConnectionNotification)notification).getConnectionId()+":"+handback);
+ if ( !JMXConnectionNotification.OPENED.equals(notification.getType()) ){
+ this.disconnectFromNode((String)handback);
+ tree.treeDidChange();
+ }
+ }
+
+ ////////////////////////////////////////////////////
+ // Friend methods //
+ ///////////////////////////////////////////////////
+ void stop(){
+ this.cont=false;
+ }
+
+ boolean isNodeConnected(String s){
+ if (this.connectedNodes.get(s)==null){
+ return false;
+ }else{
+ return true;
+ }
+ }
+
+ ///////////////////////////////////////////////////
+ // Private part //
+ ///////////////////////////////////////////////////
+ protected void createDefaultNodes(boolean createTreeNode) {
+ String profile;
+ String rmiPort;
+ String ip;
+
+ int i=1;
+ profile=bc.getProperty("insa.jmxconsole.profile" + i);
+
+ while (profile!=null){
+ rmiPort=bc.getProperty("insa.jmxconsole.rmiport."+profile);
+ if (rmiPort==null){rmiPort="1099";}
+ String virtual=bc.getProperty("insa.jmxconsole.core."+profile);
+ ip=bc.getProperty("insa.jmxconsole.ip" + i);
+ String connString=ip+":"+rmiPort+"/"+profile;
+ if (createTreeNode){
+ DefaultMutableTreeNode dmtn=new DefaultMutableTreeNode(connString);
+ DefaultMutableTreeNode parent=top;
+ if (virtual==null){
+ nodes.put(connString, dmtn);
+ }else{
+ String parentString=ip+":"+virtual;
+ parent=(DefaultMutableTreeNode)nodes.get(parentString);
+ }
+ parent.add(dmtn);
+ }
+ this.connectToNode(connString);
+ i++;
+ profile=bc.getProperty("insa.jmxconsole.profile" + i);
+ }
+
+ if (i==1){
+ try{
+ System.out.println("No property insa.jmxconsole.profile, managing local profile");
+ String prof=bc.getProperty(BundleCache.CACHE_PROFILE_PROP);
+ if (prof==null){
+ prof=System.getProperty(BundleCache.CACHE_PROFILE_PROP);
+ }
+ String connString=java.net.InetAddress.getLocalHost().getHostAddress()+":1099/"+prof;
+ if (createTreeNode){
+ top.add(new DefaultMutableTreeNode(connString));
+ }
+// this.connectToNode(connString);
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void disconnectFromNode(String connString){
+ JMXConnector jmxc=(JMXConnector)this.jmxConnectors.remove(connString);
+ MBeanServerConnection mbscl=(MBeanServerConnection)this.connectedNodes.remove(connString);
+ try{
+ jmxc.removeConnectionNotificationListener(this);
+ //mbscl.removeNotificationListener(new ObjectName("OSGI:name=OSGi
+ // Server"), this); // Does not work since the connexion is lost !!
+ jmxc.close();
+ a.firePropertyChangedEvent(Plugin.EMPTY_NODE, null, "null");
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ jmxc=null;
+ mbscl=null;
+ }
+
+ private void connectToNode(String connString){
+ Object ls=this.connectedNodes.get(connString);
+ if (ls==null){
+ JMXConnector jmxc = null;
+ try {
+
+ JMXServiceURL surl = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + connString);
+/*
+Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
+System.out.println("=====> "+java.util.logging.Logger.getLogger("javax.management.remote.misc"));
+java.util.logging.Logger.getLogger("javax.management.remote.misc").setLevel(java.util.logging.Level.FINEST);
+java.util.logging.Logger.getLogger("javax.management.remote.rmi").setLevel(java.util.logging.Level.FINEST);
+
+java.util.logging.ConsoleHandler ch=new java.util.logging.ConsoleHandler();
+ch.setLevel(java.util.logging.Level.FINEST);
+java.util.logging.Logger.getLogger("javax.management.remote.misc").addHandler(ch);
+java.util.logging.Logger.getLogger("javax.management.remote.rmi").addHandler(ch);
+*/
+
+ jmxc = JMXConnectorFactory.connect(surl);
+ MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
+ if (mbsc.isRegistered(new ObjectName("OSGI:name=Remote Logger"))){
+ jmxc.addConnectionNotificationListener(this, null, connString);
+ mbsc.addNotificationListener(new ObjectName("TabUI:name=OsgiProbes"), this, null, null); //Needed,
+
+ this.connectedNodes.put(connString, mbsc);
+ this.jmxConnectors.put(connString, jmxc);
+ a.firePropertyChangedEvent(Plugin.NEW_NODE_CONNECTION, connString, mbsc);
+ System.out.println("Node "+connString+" connected");
+ }else {
+System.out.println("The Remote Logger of "+connString+" is not started");
+ }
+ }catch(java.io.IOException ex){
+System.out.println("Impossible to connect to "+connString);
+ }catch(MalformedObjectNameException e){
+ e.printStackTrace();
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ }else{
+ a.firePropertyChangedEvent(Plugin.NEW_NODE_CONNECTION, connString, ls);
+ }
+ }
+
+ protected class PoolingThread implements Runnable{
+ public void run(){
+ while (cont){
+ createDefaultNodes(false);
+ tree.treeDidChange();
+ try{
+ Thread.sleep(POOLING_TIME);
+ }catch(InterruptedException e){
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+}
diff --git a/org.apache.felix.mosgi.console.gui/src/main/resources/images/GraphSettings.gif b/org.apache.felix.mosgi.console.gui/src/main/resources/images/GraphSettings.gif
new file mode 100644
index 0000000..982e2dc
--- /dev/null
+++ b/org.apache.felix.mosgi.console.gui/src/main/resources/images/GraphSettings.gif
Binary files differ
diff --git a/org.apache.felix.mosgi.console.gui/src/main/resources/images/ServerBlocked.gif b/org.apache.felix.mosgi.console.gui/src/main/resources/images/ServerBlocked.gif
new file mode 100644
index 0000000..50459cb
--- /dev/null
+++ b/org.apache.felix.mosgi.console.gui/src/main/resources/images/ServerBlocked.gif
Binary files differ
diff --git a/org.apache.felix.mosgi.console.gui/src/main/resources/images/ServerRunning.gif b/org.apache.felix.mosgi.console.gui/src/main/resources/images/ServerRunning.gif
new file mode 100644
index 0000000..ab3c237
--- /dev/null
+++ b/org.apache.felix.mosgi.console.gui/src/main/resources/images/ServerRunning.gif
Binary files differ
diff --git a/org.apache.felix.mosgi.console.gui/src/main/resources/images/logo.gif b/org.apache.felix.mosgi.console.gui/src/main/resources/images/logo.gif
new file mode 100644
index 0000000..b523df7
--- /dev/null
+++ b/org.apache.felix.mosgi.console.gui/src/main/resources/images/logo.gif
Binary files differ