View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package org.apache.log4j.chainsaw.receivers;
    19
    20  import java.beans.PropertyChangeEvent;
    21  import java.beans.PropertyChangeListener;
    22  import java.util.Collection;
    23  import java.util.Vector;
    24  import java.util.Enumeration;
    25  import java.util.Iterator;
    26
    27  import javax.swing.tree.DefaultMutableTreeNode;
    28  import javax.swing.tree.DefaultTreeModel;
    29  import javax.swing.tree.TreeNode;
    30
    31  import org.apache.log4j.LogManager;
    32  import org.apache.log4j.Logger;
    33  import org.apache.log4j.net.SocketReceiver;
    34  import org.apache.log4j.spi.LoggerRepository;
    35  import org.apache.log4j.spi.LoggerRepositoryEx;
    36  import org.apache.log4j.plugins.Plugin;
    37  import org.apache.log4j.plugins.PluginEvent;
    38  import org.apache.log4j.plugins.PluginListener;
    39  import org.apache.log4j.plugins.Receiver;
    40
    41
    42  /**
    43   * A TreeModel that encapsulates the details of all the Receivers and their
    44   * related information in the Log4j framework
    45   *
    46   * @author Paul Smith &lt;psmith@apache.org&gt;
    47   */
    48  public class ReceiversTreeModel extends DefaultTreeModel
    49    implements PluginListener {
    50    private static final String ROOTNODE_LABEL = "Receivers";
    51    final DefaultMutableTreeNode NoReceiversNode =
    52      new DefaultMutableTreeNode("No Receivers defined");
    53    final DefaultMutableTreeNode RootNode;
    54    private final Logger logger = LogManager.getLogger(ReceiversTreeModel.class);
    55
    56    ReceiversTreeModel() {
    57      super(new DefaultMutableTreeNode(ROOTNODE_LABEL));
    58      RootNode = (DefaultMutableTreeNode) getRoot();
    59      refresh();
    60    }
    61
    62    /**
    63     * Creates a new ReceiversTreeModel by querying the Log4j Plugin Repository
    64     * and building up the required information.
    65     *
    66     * @return ReceiversTreeModel
    67     */
    68    public final synchronized ReceiversTreeModel refresh() {
    69      RootNode.removeAllChildren();
    70
    71      LoggerRepository repo = LogManager.getLoggerRepository();
    72      Collection receivers;
    73      if (repo instanceof LoggerRepositoryEx) {
    74          receivers = ((LoggerRepositoryEx) repo).getPluginRegistry().getPlugins(Receiver.class);
    75      } else {
    76          receivers = new Vector();
    77      }
    78
    79      updateRootDisplay();
    80
    81      if (receivers.size() == 0) {
    82        getRootNode().add(NoReceiversNode);
    83      } else {
    84        for (Iterator iter = receivers.iterator(); iter.hasNext();) {
    85          final Receiver item = (Receiver) iter.next();
    86          final DefaultMutableTreeNode receiverNode = new DefaultMutableTreeNode(item);
    87
    88          item.addPropertyChangeListener(creatPluginPropertyChangeListener(item, receiverNode));
    89          if (item instanceof SocketReceiver) {
    90            for (
    91              Iterator iterator =
    92                ((SocketReceiver) item).getConnectedSocketDetails().iterator();
    93                iterator.hasNext();) {
    94              Object details = iterator.next();
    95              receiverNode.add(new DefaultMutableTreeNode(details));
    96            }
    97          }
    98
    99          getRootNode().add(receiverNode);
    100       }
    101     }
    102
    103     reload();
    104
    105     return this;
    106   }
    107
    108   private PropertyChangeListener creatPluginPropertyChangeListener(final Receiver item, final DefaultMutableTreeNode receiverNode)
    109   {
    110     return new PropertyChangeListener() {
    111
    112       public void propertyChange(PropertyChangeEvent evt)
    113       {
    114         logger.debug(evt.toString());
    115         ReceiversTreeModel.this.fireTreeNodesChanged(item, receiverNode.getPath(), null, null);
    116
    117       }};
    118   }
    119
    120   /**
    121    * Ensure the Root node of this tree is updated with the latest information
    122    * and that listeners are notified.
    123    */
    124   void updateRootDisplay() {
    125     getRootNode().setUserObject(ROOTNODE_LABEL);
    126     nodeChanged(getRootNode());
    127   }
    128
    129   DefaultMutableTreeNode getRootNode() {
    130     return (DefaultMutableTreeNode) getRoot();
    131   }
    132
    133   /* (non-Javadoc)
    134    * @see org.apache.log4j.plugins.PluginListener#pluginStarted(org.apache.log4j.plugins.PluginEvent)
    135    */
    136   public void pluginStarted(PluginEvent e) {
    137     if (e.getPlugin() instanceof Receiver) {
    138       if (NoReceiversNode.getParent() == getRootNode()) {
    139         int index = getRootNode().getIndex(NoReceiversNode);
    140         getRootNode().remove(NoReceiversNode);
    141         nodesWereRemoved(
    142           getRootNode(), new int[] { index }, new Object[] { NoReceiversNode });
    143       }
    144
    145       Receiver receiver = (Receiver) e.getPlugin();
    146       DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(receiver);
    147       getRootNode().add(newNode);
    148       receiver.addPropertyChangeListener(creatPluginPropertyChangeListener(receiver, newNode));
    149       nodesWereInserted(
    150         getRootNode(), new int[] { getRootNode().getIndex(newNode) });
    151     }
    152   }
    153
    154 	TreeNode resolvePluginNode(Plugin p){
    155 		/**
    156 		 * Lets walk the tree, top-down until we find the node with the plugin
    157 		 * attached.
    158 		 *
    159 		 * Since the tree hierachy is quite flat, this is should not
    160 		 * be a performance issue at all, but if it is,
    161 		 * then "I have no recollection of that Senator".
    162 		 */
    163 		TreeNode treeNode = null;
    164 		Enumeration e = getRootNode().breadthFirstEnumeration();
    165 		while(e.hasMoreElements()){
    166 			DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.nextElement();
    167 			if(node.getUserObject().equals(p)){
    168 				treeNode = node;
    169 				break;
    170 			}
    171 		}
    172 		return treeNode;
    173 	}
    174
    175   /* (non-Javadoc)
    176    * @see org.apache.log4j.plugins.PluginListener#pluginStopped(org.apache.log4j.plugins.PluginEvent)
    177    */
    178   public void pluginStopped(PluginEvent e) {
    179     if (e.getPlugin() instanceof Receiver) {
    180       Receiver receiver = (Receiver) e.getPlugin();
    181       DefaultMutableTreeNode node =
    182         (DefaultMutableTreeNode) resolvePluginNode(receiver);
    183         if (node != null) {
    184             int index = getRootNode().getIndex(node);
    185             getRootNode().remove(node);
    186             nodesWereRemoved(
    187                 getRootNode(), new int[] { index }, new Object[] { node });
    188         }
    189
    190       if (getRootNode().getChildCount() == 0) {
    191         getRootNode().add(NoReceiversNode);
    192
    193         int index = getRootNode().getIndex(NoReceiversNode);
    194         nodesWereInserted(getRootNode(), new int[] { index });
    195       }
    196     }
    197   }
    198 }