FELIX-151
Improve remote logger panel whith colored jtree and jtable
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@448510 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/mosgi.console.component/pom.xml b/mosgi.console.component/pom.xml
index 9a3ecd5..4397381 100644
--- a/mosgi.console.component/pom.xml
+++ b/mosgi.console.component/pom.xml
@@ -43,7 +43,8 @@
javax.management;specification-version="1.0.0",
javax.swing;specification-version="1.0.0",
javax.swing.table;specification-version="1.0.0",
- org.osgi.framework;specification-version="1.0.0"
+ org.osgi.framework;specification-version="1.0.0",
+ javax.swing.tree;specification-version="1.0.0"
</importPackage>
</osgiManifest>
</configuration>
diff --git a/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/Activator.java b/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/Activator.java
index 94b1d81..9530341 100644
--- a/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/Activator.java
+++ b/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/Activator.java
@@ -1,45 +1,57 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
-*/
+/*
+ * 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.component;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.apache.felix.mosgi.console.ifc.CommonPlugin;
+import java.lang.String;
-public class Activator implements BundleActivator
-{
- private BundleContext m_context = null;
+public class Activator implements BundleActivator {
+
+ public void start(BundleContext context) throws Exception{
+ String propVal=new String("both");
+ String propValue=context.getProperty("mosgi.jmxconsole.remotelogger.componentfilter");
+ if (propValue!=null) {
+ if (propValue.equals("treeonly") | propValue.equals("tableonly") | propValue.equals("both") | propValue.equals("none")) {
+ propVal=propValue;
+ }else {
+ propVal="both";
+ }
+ }
- public void start(BundleContext context) throws Exception
- {
- m_context = context;
- m_context.registerService( CommonPlugin.class.getName(), new RemoteLogger(), null);
+ if (propVal.equals("treeonly") | propVal.equals("both")) {
+ context.registerService(CommonPlugin.class.getName(), new RemoteLogger_jtree(context), null);
+ }
+ if (propVal.equals("tableonly") | propVal.equals("both")) {
+ context.registerService(CommonPlugin.class.getName(), new RemoteLogger_jtable(), null);
+ }
+ }
+
+ public void stop(BundleContext context) {
+ }
+
// m_context.registerService( Plugin.class.getName(), new NodeDetails(), null);
// m_context.registerService( Plugin.class.getName(), new BundleListPanel(), null);
-
+//
// m_context.registerService( CommonPlugin.class.getName(), new OBRPlugin(context), null);
-
- // m_context.registerService( Plugin.class.getName(), new MemoryLauncher(context), null);
+//
+// m_context.registerService( Plugin.class.getName(), new MemoryLauncher(context), null);
// m_context.registerService( Plugin.class.getName(), new LinuxDetails(), null);
- }
+//
- public void stop(BundleContext context)
- {
- }
}
diff --git a/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/JtableCellRenderer.java b/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/JtableCellRenderer.java
new file mode 100644
index 0000000..2d95879
--- /dev/null
+++ b/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/JtableCellRenderer.java
@@ -0,0 +1,60 @@
+/*
+ * 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.component;
+
+import org.osgi.framework.Bundle;
+
+import java.util.Hashtable;
+import java.awt.Color;
+import javax.swing.JTable;
+import javax.swing.JLabel;
+import javax.swing.table.TableCellRenderer;
+import java.awt.Component;
+
+public class JtableCellRenderer extends JLabel implements TableCellRenderer {
+
+ private Hashtable eventName=new Hashtable();
+
+ public JtableCellRenderer() {
+ super();
+ eventName.put(new Integer( Bundle.ACTIVE ), Color.green );
+ eventName.put(new Integer( Bundle.INSTALLED ), Color.orange );
+ eventName.put(new Integer( Bundle.RESOLVED ), Color.red );
+ eventName.put(new Integer( Bundle.STARTING ), Color.gray );
+ eventName.put(new Integer( Bundle.STOPPING ), Color.gray );
+ eventName.put(new Integer( Bundle.UNINSTALLED ), Color.black );
+ }
+
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
+ boolean hasFocus, int row, int column) {
+ setOpaque(true);
+ if (column==0){
+ Integer state;
+ try{
+ state=new Integer(Integer.parseInt((String) table.getValueAt(row,5)));
+ }catch (NumberFormatException nfe) {
+ state=new Integer(-1);
+ }
+ setBackground((Color) eventName.get(state));
+ }
+ setText((String) value);
+
+ return this;
+ }
+
+}
diff --git a/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/JtreeCellRenderer.java b/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/JtreeCellRenderer.java
new file mode 100644
index 0000000..d6c33d9
--- /dev/null
+++ b/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/JtreeCellRenderer.java
@@ -0,0 +1,101 @@
+/*
+ * 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.component;
+
+import org.osgi.framework.BundleContext;
+
+import java.awt.Color;
+import javax.swing.JTree;
+import javax.swing.JLabel;
+import java.util.StringTokenizer;
+
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.TreeCellRenderer;
+import java.awt.Component;
+import javax.swing.tree.DefaultMutableTreeNode;
+import java.awt.Graphics;
+import java.util.NoSuchElementException;
+import java.awt.Font;
+import java.awt.Dimension;
+
+import javax.swing.ImageIcon;
+import java.awt.Toolkit;
+
+public class JtreeCellRenderer extends DefaultTreeCellRenderer {
+
+ private boolean isLeaf=false;
+ //private int maxL;
+
+ private String[] states=new String[]{"ACTIVE","INSTALLED","RESOLVED","STARTING","STOPPING","UNINSTALLED"};
+ private Color[] colors=new Color[]{Color.green,Color.orange,Color.red,Color.white,Color.white,Color.black};
+ private ImageIcon[] ii=new ImageIcon[6];
+
+ public JtreeCellRenderer(BundleContext bdlCtx){
+ for (int i=0 ; i<states.length ; i++){
+ this.ii[i]=new ImageIcon(Toolkit.getDefaultToolkit().getImage(bdlCtx.getBundle().getResource("icons/"+states[i]+".gif")));
+ }
+ }
+
+ public Dimension getPreferredSize() {
+ Dimension dim = super.getPreferredSize();
+ //maxL=(isLeaf)?Math.max(maxL,dim.width):maxL;
+ //
+ return (isLeaf)?dim:new Dimension(800/*maxL*/,dim.height);
+ }
+
+ public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+ this.isLeaf=leaf;
+
+ super.getTreeCellRendererComponent(tree,value,sel,expanded,leaf,row,hasFocus);
+ setOpaque(true);
+ setBackground(Color.white);
+ setFont(new Font("Monospaced",Font.BOLD,12));
+
+ StringTokenizer st=null;
+ DefaultMutableTreeNode dmtn=(DefaultMutableTreeNode)value;
+ int lvl=dmtn.getLevel();
+ if(lvl==3 & dmtn.getChildCount()>0){
+ st=new StringTokenizer(dmtn.getFirstChild().toString()," | ");
+ }
+ if (lvl==4){
+ st=new StringTokenizer(dmtn.toString()," | ");
+ }
+
+ if(st!=null){
+ st.nextToken();
+ st.nextToken();
+ String state=st.nextToken();
+ for (int i=0 ; i<states.length ; i++){
+ if (state.equals(states[i])){
+ if (lvl==4){
+ setIcon(ii[i]);
+ setFont(new Font("Monospaced",Font.PLAIN,10));
+ }else{
+ StringTokenizer st2 = new StringTokenizer(((DefaultMutableTreeNode)dmtn.getFirstChild()).toString()," | ");
+ setToolTipText("<html><B>IP = </B>"+/*IP=<ip> Profil=<port>/<profil>*/dmtn.getParent().getParent()+"<B> Profil =</B>"+dmtn.getParent()+"<br><B>Bundle : </B>"+/*Bundle : Id=<bundleId> : <bundleSymbolicName>*/dmtn+"<br><B>Date : </B>"+/*<date> - <time>*/st2.nextToken()+" - "+st2.nextToken()+"<br><B>State : </B>"+/*<bundleState>*/st2.nextToken()+"<B><br>Event "+/*Event <eventNumber> : <logLevel> : <message>*/dmtn.getChildCount()+" : "+st2.nextToken()+" : "+st2.nextToken()+"</B></html>");
+ setBackground(colors[i]);
+ }
+ break;
+ }
+ }
+ }
+
+ return this;
+ }
+
+}
diff --git a/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/MyTree.java b/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/MyTree.java
new file mode 100644
index 0000000..4157140
--- /dev/null
+++ b/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/MyTree.java
@@ -0,0 +1,48 @@
+/*
+ * 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.component;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.JTree;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.ToolTipManager;
+import javax.swing.UIManager;
+
+public class MyTree extends JTree{
+
+ public MyTree(DefaultTreeModel dtm){
+ super(dtm);
+ //setRowHeight(0); // so DefaultTreeModel.getPreferedSize() is always call
+ ToolTipManager.sharedInstance().registerComponent(this);
+ ToolTipManager.sharedInstance().setInitialDelay(700);
+ ToolTipManager.sharedInstance().setDismissDelay(7000);
+ //ToolTipManager.setReshownDelay();
+ //ToolTipManager.setEnabled();
+ }
+
+ public String convertValueToText(Object value,boolean selected,boolean expanded,boolean leaf,int row,boolean hasFocus){
+ DefaultMutableTreeNode dmtn=(DefaultMutableTreeNode) value;
+ if (dmtn.getLevel()==3) {
+ int childNumber=dmtn.getChildCount();
+ //String lastMsg=new String((childNumber==0)?"":dmtn.getFirstChild().toString());
+ return value.toString()+" ("+dmtn.getChildCount()+" events)";//+lastMsg;
+ }else{
+ return value.toString();
+ }
+ }
+
+}
diff --git a/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/RemoteLogger_jtable.java b/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/RemoteLogger_jtable.java
new file mode 100644
index 0000000..38318a1
--- /dev/null
+++ b/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/RemoteLogger_jtable.java
@@ -0,0 +1,184 @@
+/*
+ * 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.component;
+
+import org.apache.felix.mosgi.console.ifc.CommonPlugin;
+import org.apache.felix.mosgi.console.ifc.Plugin;
+//import org.apache.felix.mosgi.console.component.JtableCellRenderer;
+
+import javax.swing.table.DefaultTableModel;
+import javax.swing.JTable;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import java.awt.Component;
+
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.MBeanServerConnection;
+import javax.swing.ListSelectionModel;
+
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+import java.beans.PropertyChangeEvent;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import java.util.Vector;
+
+import java.io.PrintStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import javax.swing.JFileChooser;
+
+import java.util.Date;
+import java.text.DateFormat;
+//import java.text.SimpleDateFormat;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.tree.DefaultMutableTreeNode;
+
+public class RemoteLogger_jtable extends DefaultTableModel implements CommonPlugin, NotificationListener{
+
+ private JTable logList;
+ private JButton jb_save;
+ private JPanel jbPanel;
+ private JPanel jp;
+ private Hashtable nodes=new Hashtable();
+
+ public void jb_actionPerformed(ActionEvent e) {
+ String compoName=((Component) e.getSource()).getName();
+
+ if (compoName.equals("jb_save")){
+ PrintStream ps=System.out;
+ JFileChooser jfc=new JFileChooser();
+ if (jfc.showSaveDialog(null)==JFileChooser.APPROVE_OPTION & jfc.getSelectedFile()!=null){
+ try{
+ ps=new PrintStream(jfc.getSelectedFile());
+ System.out.println("Save remote log into \""+jfc.getSelectedFile().getName()+"\""); }
+ catch (FileNotFoundException fnfe){
+ System.out.println("err : "+fnfe); }
+ }
+ int col=this.logList.getColumnCount(); // TODO : try this.getColumnCount()
+ int line=this.logList.getRowCount() - 1; // last line always empty
+ //ps.print(col+" "+line);
+ Vector tableData=new Vector();
+ tableData=this.getDataVector();
+ for (int i=0 ; i<line ; i++){
+ ps.print(i+" : ");
+ for (int j=0 ; j<col ; j++){
+ ps.print((String) ( ((Vector) (tableData.elementAt(i))).elementAt(j) )+" | ");
+ }
+ ps.print("\n");
+ }
+ }
+ }
+
+ public RemoteLogger_jtable (){
+ super(new String[]{"Date","Time", "Src", "Id", "Name", "State", "Lvl", "Msg"},1);
+ System.out.println("JTable Remote logger");
+
+ this.jp=new JPanel();
+ this.jp.setLayout(new BorderLayout());
+
+ this.jbPanel=new JPanel();
+ this.jbPanel.setSize(300,25);
+
+ this.jb_save=new JButton("Save log on file");
+ this.jb_save.setName("jb_save");
+
+ ActionListener al = new ActionListener(){
+ public void actionPerformed(ActionEvent e){
+ jb_actionPerformed(e);
+ }
+ };
+ this.jb_save.addActionListener(al);
+
+ logList=new JTable(this);
+ JtableCellRenderer cellRenderer=new JtableCellRenderer();
+ logList.setDefaultRenderer(Object.class,cellRenderer);
+
+ logList.setPreferredScrollableViewportSize(new java.awt.Dimension(600, 70));
+
+ logList.getColumnModel().getColumn(0).setPreferredWidth(50);
+ logList.getColumnModel().getColumn(1).setPreferredWidth(40);
+ logList.getColumnModel().getColumn(2).setPreferredWidth(120);
+ logList.getColumnModel().getColumn(3).setPreferredWidth(15);
+ logList.getColumnModel().getColumn(4).setPreferredWidth(70);
+ logList.getColumnModel().getColumn(5).setPreferredWidth(15);
+ logList.getColumnModel().getColumn(6).setPreferredWidth(40);
+ logList.getColumnModel().getColumn(7).setPreferredWidth(180);
+
+ logList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ logList.getTableHeader().setReorderingAllowed(true);//false); // true c'est sympa pourtant... ?
+
+ this.jbPanel.add(jb_save);
+ jp.add(this.jbPanel, BorderLayout.NORTH);
+ jp.add(new JScrollPane(logList), BorderLayout.CENTER);
+ }
+
+ /////////////////////////////////////
+ // Plugin Interface ////////////////
+ /////////////////////////////////////
+ public String getName(){ return "JTable Remote Logger";}
+ public Component getGUI(){return this.jp;}
+
+/* a supprimer si on enleve l'heritage CommonPlugin -> Plugin */
+ public String pluginLocation(){
+ return null;
+ }
+ public void registerServicePlugin(){}
+ public void unregisterServicePlugin(){}
+/* fin a supprimer */
+
+
+ public void propertyChange(PropertyChangeEvent e){
+ if (e.getPropertyName().equals(Plugin.NEW_NODE_CONNECTION)){
+ try{
+ MBeanServerConnection mbs=(MBeanServerConnection)e.getNewValue();
+ if (nodes.get(mbs)==null){
+ System.out.println("Ajout d'un listener " +mbs);
+ ((MBeanServerConnection)e.getNewValue()).addNotificationListener(new ObjectName("OSGI:name=Remote Logger"), this, null, e.getOldValue());
+ nodes.put(mbs, "ok");
+ }
+ }catch(Exception ex){
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ public void handleNotification(Notification notification, Object handback) {
+ StringTokenizer st = new StringTokenizer(notification.getMessage(),":");
+ Date d=new Date(notification.getTimeStamp());
+ //DateFormat dateFormat = new SimpleDateFormat("hh'h'mm dd-MM-yy");
+ DateFormat df = DateFormat.getTimeInstance(DateFormat.MEDIUM); // utilise le format de date local
+ DateFormat df2 = DateFormat.getDateInstance(DateFormat.SHORT);
+ String id=st.nextToken();
+ String name=st.nextToken();
+ String shortName=name.substring(name.lastIndexOf(".")+1,name.length());
+ String state=st.nextToken();
+ String lvl=st.nextToken();
+ String msg=st.nextToken();
+ Object [] event = new Object []{df2.format(d),df.format(d),handback,id,shortName,state,lvl,msg};
+
+ this.insertRow(0,event);
+ this.fireTableRowsInserted(0, 0);
+ }
+
+}
diff --git a/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/RemoteLogger_jtree.java b/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/RemoteLogger_jtree.java
new file mode 100644
index 0000000..a7a5863
--- /dev/null
+++ b/mosgi.console.component/src/main/java/org/apache/felix/mosgi/console/component/RemoteLogger_jtree.java
@@ -0,0 +1,187 @@
+/*
+ * 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.component;
+
+import org.apache.felix.mosgi.console.ifc.CommonPlugin;
+import org.apache.felix.mosgi.console.ifc.Plugin;
+//import org.apache.felix.mosgi.console.component.JtreeCellRenderer;
+import org.apache.felix.mosgi.console.component.MyTree;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Bundle;
+
+import javax.swing.table.DefaultTableModel;
+import javax.swing.JTable;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import java.awt.Component;
+
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.MBeanServerConnection;
+import javax.swing.ListSelectionModel;
+
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+import java.beans.PropertyChangeEvent;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import java.util.Vector;
+
+import java.io.PrintStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import javax.swing.JFileChooser;
+
+import java.util.Date;
+import java.text.DateFormat;
+//import java.text.SimpleDateFormat;
+
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.JTree;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.JFrame;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreePath;
+
+//import org.osgi.service.prefs.Preferences;
+
+public class RemoteLogger_jtree extends DefaultTreeModel implements CommonPlugin, NotificationListener{
+
+ private MyTree logTree;
+ private JPanel jp;
+ private Hashtable nodes=new Hashtable();
+ private DefaultMutableTreeNode rootNode=new DefaultMutableTreeNode("root");
+ private Hashtable eventName=new Hashtable();
+
+ public RemoteLogger_jtree (BundleContext bdlCtx){
+ super(null);
+ setRoot(rootNode);
+ System.out.println("JTree Remote logger");
+
+ this.jp=new JPanel();
+ this.jp.setLayout(new BorderLayout());
+
+ this.logTree=new MyTree(this);
+ JtreeCellRenderer treeCellRenderer=new JtreeCellRenderer(bdlCtx);
+ this.logTree.setCellRenderer(treeCellRenderer);
+ this.logTree.setLargeModel(true);
+ this.logTree.setToggleClickCount(1);
+ this.logTree.setRootVisible(false);
+ // this create an invisible tree even if I use *expand* so...
+ // I use expand after the first insert into the tree
+
+ jp.add(new JScrollPane(logTree), BorderLayout.CENTER);
+
+ eventName.put(new Integer(Bundle.ACTIVE), "ACTIVE ");
+ 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.UNINSTALLED),"UNINSTALLED");
+ }
+
+ /////////////////////////////////////
+ // Plugin Interface ////////////////
+ /////////////////////////////////////
+ public String getName(){ return "JTree Remote Logger";}
+ public Component getGUI(){return this.jp;}
+
+/* a supprimer si on enleve l'heritage CommonPlugin -> Plugin */
+ public String pluginLocation(){
+ return null;
+ }
+ public void registerServicePlugin(){}
+ public void unregisterServicePlugin(){}
+/* fin a supprimer */
+
+
+ public void propertyChange(PropertyChangeEvent e){
+ if (e.getPropertyName().equals(Plugin.NEW_NODE_CONNECTION)){
+ try{
+ MBeanServerConnection mbs=(MBeanServerConnection)e.getNewValue();
+ if (nodes.get(mbs)==null){
+System.out.println("Ajout d'un listener " +mbs);
+ ((MBeanServerConnection)e.getNewValue()).addNotificationListener(new ObjectName("OSGI:name=Remote Logger"), this, null, e.getOldValue());
+ nodes.put(mbs, "ok");
+ }
+ }catch(Exception ex){
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ private DefaultMutableTreeNode createIfNeed(String nodeToCreateAndGet, DefaultMutableTreeNode parent){
+ int childNumber=this.getChildCount(parent);
+ DefaultMutableTreeNode theNode=null;
+ for (int i=0 ; i<childNumber ; i++){ // is node even exist ?
+ String string_pool=((DefaultMutableTreeNode)(this.getChild(parent, i))).toString();
+ if (string_pool.equals(nodeToCreateAndGet)){
+ theNode=(DefaultMutableTreeNode) (this.getChild(parent, i));
+ break;
+ }
+ }
+ if (theNode==null){ // create the node
+ theNode=new DefaultMutableTreeNode(nodeToCreateAndGet);
+ // Unable to set tree expand whithout a first node
+ if (rootNode.getChildCount()==0){
+ this.insertNodeInto(theNode, parent, 0);
+ logTree.expandPath(new TreePath(rootNode.getPath()));
+ }else{
+ this.insertNodeInto(theNode, parent, 0);
+ }
+ }
+ return theNode;
+ }
+
+ public void handleNotification(Notification notification, Object handback) {
+ StringTokenizer st=new StringTokenizer(handback.toString(),":");
+ String ip=st.nextToken();
+ String ref=st.nextToken();
+
+ st = new StringTokenizer(notification.getMessage(),":");
+ Date timeDate=new Date(notification.getTimeStamp());
+ //DateFormat dateFormat = new SimpleDateFormat("hh'h'mm dd-MM-yy");
+ DateFormat df = DateFormat.getTimeInstance(DateFormat.MEDIUM); // use local date format
+ DateFormat df2 = DateFormat.getDateInstance(DateFormat.SHORT);
+ String time=df.format(timeDate);
+ String date=df2.format(timeDate);
+
+ String id=st.nextToken();
+ String name=st.nextToken();
+ String idname=new String(id+" : "+name);
+ String state=""+eventName.get(new Integer((int) Integer.parseInt(st.nextToken())));
+ String lvl=st.nextToken();
+ String msg=st.nextToken();
+
+ // Get and maybe create parents nodes : ip, ref, idname
+ DefaultMutableTreeNode dmtn_ip=createIfNeed(ip, rootNode);
+ DefaultMutableTreeNode dmtn_ref=createIfNeed(ref, dmtn_ip);
+ DefaultMutableTreeNode dmtn_idname=createIfNeed(idname, dmtn_ref);
+
+ // insert the leaf with message under id/ref/idname
+ DefaultMutableTreeNode dmtn=new DefaultMutableTreeNode(date+" | "+time+" | "+state+" | "+lvl+" | "+msg,false);
+ this.insertNodeInto(dmtn, dmtn_idname, 0);
+
+ this.reload(dmtn_idname);
+ }
+
+}
diff --git a/mosgi.console.component/src/main/resources/icons/ACTIVE.gif b/mosgi.console.component/src/main/resources/icons/ACTIVE.gif
new file mode 100644
index 0000000..e4747bb
--- /dev/null
+++ b/mosgi.console.component/src/main/resources/icons/ACTIVE.gif
Binary files differ
diff --git a/mosgi.console.component/src/main/resources/icons/INSTALLED.gif b/mosgi.console.component/src/main/resources/icons/INSTALLED.gif
new file mode 100644
index 0000000..eba380d
--- /dev/null
+++ b/mosgi.console.component/src/main/resources/icons/INSTALLED.gif
Binary files differ
diff --git a/mosgi.console.component/src/main/resources/icons/RESOLVED.gif b/mosgi.console.component/src/main/resources/icons/RESOLVED.gif
new file mode 100644
index 0000000..9ec50f6
--- /dev/null
+++ b/mosgi.console.component/src/main/resources/icons/RESOLVED.gif
Binary files differ
diff --git a/mosgi.console.component/src/main/resources/icons/STARTING.gif b/mosgi.console.component/src/main/resources/icons/STARTING.gif
new file mode 100644
index 0000000..8c20575
--- /dev/null
+++ b/mosgi.console.component/src/main/resources/icons/STARTING.gif
Binary files differ
diff --git a/mosgi.console.component/src/main/resources/icons/STOPPING.gif b/mosgi.console.component/src/main/resources/icons/STOPPING.gif
new file mode 100644
index 0000000..8c20575
--- /dev/null
+++ b/mosgi.console.component/src/main/resources/icons/STOPPING.gif
Binary files differ
diff --git a/mosgi.console.component/src/main/resources/icons/UNINSTALLED.gif b/mosgi.console.component/src/main/resources/icons/UNINSTALLED.gif
new file mode 100644
index 0000000..69368e4
--- /dev/null
+++ b/mosgi.console.component/src/main/resources/icons/UNINSTALLED.gif
Binary files differ