Package org.apache.felix.mosgi.console.component

Source Code of org.apache.felix.mosgi.console.component.RemoteLogger_jtree

/*
*   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.MyTree;
import org.osgi.framework.BundleContext;
import java.beans.PropertyChangeEvent;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JScrollBar;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.JOptionPane;
import javax.swing.JDialog;
import java.awt.Component;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.event.ActionEvent;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.MBeanServerConnection;
import javax.management.Attribute;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.Date;
import java.util.Enumeration;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
//import org.osgi.service.prefs.Preferences;

public class RemoteLogger_jtree extends DefaultTreeModel implements CommonPlugin, NotificationListener, MouseListener {

  private static final String OLDLOG_THIS_TIME     ="This time";
  private static final String OLDLOG_NOT_THIS_TIME ="Not this time";
  private static final String OLDLOG_ALWAYS        ="Always";
  private static final String OLDLOG_NEVER         ="Never";
  private static final String[] LOG_LVL=new String[] {"Error", "Warning", "Info", "Debug"};
 
  private String oldLogChoice=OLDLOG_THIS_TIME;
  private Hashtable ht_connectedGateway=new Hashtable(); // connString/mbsc
  protected Hashtable ht_logLvl=new Hashtable(); // DefaultMutableTreeNode/Integer_logLvl
  protected Vector v_ul=new Vector(); // tree node containing not visible log yet  (placer ce vecteur dans le renderer ???)

  private MyTree logTree;
  private TreePath selPath;
  private JPanel jp;
  private DefaultMutableTreeNode rootNode=new DefaultMutableTreeNode("");
  private JScrollBar jsb_horizontal=null;
  private JScrollBar jsb_vertical=null;

  public RemoteLogger_jtree (BundleContext bdlCtx){
    super(null);
    setRoot(rootNode);

    this.jp=new JPanel();
    this.jp.setLayout(new BorderLayout());
  
    this.logTree=new MyTree(this);
    JtreeCellRenderer treeCellRenderer=new JtreeCellRenderer(bdlCtx, this);
    this.logTree.setCellRenderer(treeCellRenderer);
    this.logTree.setLargeModel(true);
    this.logTree.setToggleClickCount(-1);
    this.logTree.setScrollsOnExpand(false);
    // if I do this.logTree.setRootVisible(false) => Create an invisible tree, even if I use an "expand"
    // then need to expand after the first insert into the tree so i give up with root not visible.
    this.logTree.addMouseListener(this);

    JScrollPane jsp=new JScrollPane(logTree);
    this.jsb_horizontal=jsp.getHorizontalScrollBar();
    this.jsb_vertical=jsp.getVerticalScrollBar();
    jp.add(jsp, BorderLayout.CENTER);   
    jp.setMinimumSize(new Dimension(500,25));
  }

  /////////////////////////////////////////////////////
  //           Mouse Listener Interface              //
  /////////////////////////////////////////////////////
  public void mouseEntered(MouseEvent e){}
  public void mouseClicked(MouseEvent e) {}
  public void mouseExited(MouseEvent e){}
  public void mouseReleased(MouseEvent e){}
  public void mousePressed(MouseEvent e) {
    final int selRow = logTree.getRowForLocation(e.getX(), e.getY());
    selPath = logTree.getPathForLocation(e.getX(), e.getY());

    if ( e.getClickCount()==1 & selRow!=-1 & e.getButton()>1 ) { // show JPopupMenu
      String nodeString="\""+((DefaultMutableTreeNode) selPath.getLastPathComponent()).getUserObject()+"\"";
      JPopupMenu jpopup=new JPopupMenu();
      JMenuItem jmiRemove=new JMenuItem("Remove logs \""+nodeString.substring(0,Math.min(15,nodeString.length()))+((nodeString.length()>15)?"...\"":"\""));
      jmiRemove.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
    removeLog_actionPerformed(selRow);
       
      });
      jpopup.add(jmiRemove);
      if (selPath.getPath().length==3) {
        JMenuItem jmiLogLvl=new JMenuItem("Set log level");
        jmiLogLvl.addActionListener(new ActionListener(){
          public void actionPerformed(ActionEvent e){
            setLogLvl(selPath);
          }
        });
        jpopup.add(jmiLogLvl);
      }
      jpopup.show(jp, e.getX()-jsb_horizontal.getValue(), e.getY()-jsb_vertical.getValue());
    /*} else if ( e.getClickCount()==2 & selPath!=null) { // expand selected path
      if (logTree.isExpanded(selPath)) {
        logTree.collapsePath(selPath);
      } else {
        logTree.expandPath(selPath);
      } */
    } else if ( e.getClickCount()==1 & selPath!=null ) { // reload logTree and let selected path location
      reloadTree(selRow);
    }
  }
 
  private void reloadTree(int selRow) {
    int horizontal_jsb_init_value = jsb_horizontal.getValue();
    int vertical_jsb_init_value = jsb_vertical.getValue();
    int row_y_init_loc = (int) ((logTree.getRowBounds(selRow)).getY());
    Enumeration enu = logTree.getExpandedDescendants(new TreePath(rootNode));
    reload();
    if ( enu != null ) { // necessaire ce test ?
      while (enu.hasMoreElements()) {
        logTree.expandPath((TreePath) enu.nextElement());
      }
    }
    // Redefini tous les noeuds rmiport/profilName comme a jour
    this.v_ul.removeAllElements();
    // without next line if scrollbar_value=scrollbar_max it's generate a bad shift (may be vertical scrollbar height)
    logTree.scrollPathToVisible(selPath);
    int row_y_new_loc = (int) ((logTree.getRowBounds(logTree.getRowForPath(selPath))).getY());
    int vertical_jsb_new_value = vertical_jsb_init_value+(row_y_new_loc-row_y_init_loc);
    jsb_vertical.setValue(vertical_jsb_new_value);
    jsb_horizontal.setValue(horizontal_jsb_init_value);
    logTree.setSelectionPath(selPath);
    logTree.repaint();
  }

  /////////////////////////////////////
  //        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 mbsc=(MBeanServerConnection)e.getNewValue();
  if ( !ht_connectedGateway.containsValue(mbsc) ) {
    String jmxsurl = (String) e.getOldValue();
    mbsc.addNotificationListener(Activator.REMOTE_LOGGER_ON, this, null, jmxsurl);
    // At gateway connection time : add into the tree a "port/profileName" node under an "ip" node
    String ref = jmxsurl.substring(jmxsurl.lastIndexOf(":")+1);
    String ip_tmp = jmxsurl.substring(0, jmxsurl.lastIndexOf(":"));
    String ip = ip_tmp.substring(ip_tmp.lastIndexOf("/")+1);
    String connString = jmxsurl.substring(ip_tmp.lastIndexOf("/")+1);
    ht_connectedGateway.put(connString, mbsc);
          DefaultMutableTreeNode dmtn_ip=createIfNeed(ip, rootNode);
          DefaultMutableTreeNode dmtn_ref=createIfNeed(ref, dmtn_ip);
          Integer lL = this.getLogLvl(connString);
          ht_logLvl.put(dmtn_ref, lL);
          // ask for old log management choice :
          if (oldLogChoice==OLDLOG_THIS_TIME | oldLogChoice==OLDLOG_NOT_THIS_TIME) {
            JOptionPane jop = new JOptionPane("Do you want old log from gateway :\n"+jmxsurl+" ?", JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, new String[] {OLDLOG_THIS_TIME, OLDLOG_NOT_THIS_TIME, OLDLOG_ALWAYS, OLDLOG_NEVER}, OLDLOG_THIS_TIME);
            JDialog dialog = jop.createDialog(jp, "Old log management");
      //dialog.setModal(true);
      dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
      dialog.show();
      oldLogChoice = (String) jop.getValue();
      if (oldLogChoice==JOptionPane.UNINITIALIZED_VALUE) {
              oldLogChoice=OLDLOG_THIS_TIME; // *1)
      }
    }
          if (oldLogChoice==OLDLOG_THIS_TIME | oldLogChoice==OLDLOG_ALWAYS) {
            mbsc.invoke(Activator.REMOTE_LOGGER_ON, "sendOldLog", new Object[]{}, new String[]{});
    }
        }
      } catch(Exception ex){
        System.out.println("[RemoteLogger_jtree] error : "+ex);
      }
    }
  }
  private static final DateFormat dateFormat = new SimpleDateFormat("dd-MM-yy");
  private static final DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss:SSS");
  ///////////////////////////////////////////////////
  //       NotificationListener implementation     // 
  ///////////////////////////////////////////////////
  public void handleNotification(Notification notification, Object handback) {
    String jmxsurl = handback.toString();
    String ref = jmxsurl.substring(jmxsurl.lastIndexOf(":")+1);
    String ip_tmp = jmxsurl.substring(0, jmxsurl.lastIndexOf(":"));
    String ip = ip_tmp.substring(ip_tmp.lastIndexOf("/")+1);
 
    StringTokenizer st = new StringTokenizer(notification.getMessage(), "*");
    long ts=notification.getTimeStamp();
    String time=JtreeCellRenderer.UNKNOWN_TIME;
    String date=JtreeCellRenderer.UNKNOWN_DATE;
    if (ts!=0) {
      Date timeDate=new Date(ts);
      // if I use local date format there are indentations problems
      //DateFormat df = DateFormat.getTimeInstance(DateFormat.MEDIUM);
      //DateFormat df2 = DateFormat.getDateInstance(DateFormat.SHORT);
      time=timeFormat.format(timeDate);
      date=dateFormat.format(timeDate);
    }
    String id=st.nextToken();
    String name=st.nextToken();
    String idname=new String(id+" : "+name);
    // bundle state juste after remote loger received a the log entry (in old log case do state="")
    String state=(String) JtreeCellRenderer.ht_num2string.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(time+" | "+date+" | "+state+" | "+lvl+" | "+msg,false);
    this.insertNodeInto(dmtn, dmtn_idname, 0);
    // if usefull save nodes which contains new log
    if ( !v_ul.contains(dmtn_ip) ) {
  v_ul.add(dmtn_ip);
  v_ul.add(dmtn_ref);
  v_ul.add(dmtn_idname);
    } else if ( !v_ul.contains(dmtn_ref) ) {
  v_ul.add(dmtn_ref);
  v_ul.add(dmtn_idname);
    } else if ( !v_ul.contains(dmtn_idname) ) {
  v_ul.add(dmtn_idname);
    }
    this.logTree.repaint();
  }

  //////////////////////////////////////////
  //     MBean attribute manipulation     //
  //////////////////////////////////////////
  private Integer getLogLvl(String connString) {
    Integer val=new Integer(0);
    try {
      MBeanServerConnection mb=(MBeanServerConnection) ht_connectedGateway.get(connString);
      val=(Integer) mb.getAttribute(Activator.REMOTE_LOGGER_ON, "LogLvl");
    } catch (Exception exc) {
      exc.printStackTrace();
    }
    return val;
  }

  private void setLogLvl(TreePath tp) {
    Object[] o=tp.getPath();
    String connString = o[1]+":"+o[2];
    try {
      MBeanServerConnection mb=(MBeanServerConnection) ht_connectedGateway.get(connString);
      Integer curentVal=(Integer) mb.getAttribute(Activator.REMOTE_LOGGER_ON, "LogLvl");

      int val = JOptionPane.showOptionDialog(jp, "Select a log level for \"..."+connString+"\" :", "Log level", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, LOG_LVL, LOG_LVL[curentVal.intValue()-1]);
      if ( val == JOptionPane.CLOSED_OPTION ) { return; }
      Integer newVal = new Integer(val+1);

      mb.setAttribute(Activator.REMOTE_LOGGER_ON, new Attribute("LogLvl", newVal));
      DefaultMutableTreeNode ddmmttnn=(DefaultMutableTreeNode) tp.getLastPathComponent();
      ht_logLvl.put(ddmmttnn, newVal);
    } catch (Exception ex) {
      JOptionPane.showMessageDialog(jp,"Error with \"..."+connString+"\" :\n"+ex, "Error :", JOptionPane.ERROR_MESSAGE);
      ex.printStackTrace();
    }
  }

  //////////////////////////////////////////
  //         PRIVATE TOOLS                //
  //////////////////////////////////////////
  private void removeLog_actionPerformed(int selRow) {
    //System.out.println("selected path="+this.selPath);
    Object[] o= this.selPath.getPath();
    DefaultMutableTreeNode selectedDmtn=(DefaultMutableTreeNode) this.selPath.getLastPathComponent();
    if (o.length==5) {
      // Can't remove first child of a bundle to avoid modify tree node color
      if ( ((DefaultMutableTreeNode) selectedDmtn.getParent()).getFirstChild()!=selectedDmtn ) {
        removeNodeFromParent(selectedDmtn);
      }
    } else if (o.length==4) {
      removeNodeFromParent(selectedDmtn);
    } else if (o.length==3) {
      selectedDmtn.removeAllChildren();
      reloadTree(selRow);
    } else if (o.length==2) {
      Enumeration enu_1=selectedDmtn.children();
      while (enu_1.hasMoreElements()) {
        DefaultMutableTreeNode dmtn_child=(DefaultMutableTreeNode) enu_1.nextElement();
  dmtn_child.removeAllChildren();
      }
      reloadTree(selRow);
    } else if (o.length==1) {
      Enumeration enume=rootNode.children();
      while (enume.hasMoreElements()) {
        DefaultMutableTreeNode dmtn_child=(DefaultMutableTreeNode) enume.nextElement();
  Enumeration enume2=dmtn_child.children();
        while (enume2.hasMoreElements()) {
          DefaultMutableTreeNode dmtn_child_child=(DefaultMutableTreeNode) enume2.nextElement();
    dmtn_child_child.removeAllChildren();
  }
      }
      reloadTree(selRow);
    }
  }

  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);
      this.insertNodeInto(theNode, parent, 0);
      if ( parent==rootNode ) {
        v_ul.add(rootNode);
      }
    }
   
    return theNode;
  }

  protected String getLogLvl(DefaultMutableTreeNode dmtn) {
    // used by treeCellRenderer
    return LOG_LVL[ ((Integer) ht_logLvl.get(dmtn)).intValue() - 1 ];
  }
  protected void fireTreeNodesInserted(Object source, Object path[], int childIndices[], Object children[]) {
    // Do nothing to avoid refresh jtree after each log.
  }

}
TOP

Related Classes of org.apache.felix.mosgi.console.component.RemoteLogger_jtree

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.