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 org.apache.log4j.LogManager;
    21  import org.apache.log4j.Logger;
    22  import org.apache.log4j.plugins.Plugin;
    23  import org.apache.log4j.plugins.PluginEvent;
    24  import org.apache.log4j.plugins.PluginListener;
    25  import org.apache.log4j.plugins.Receiver;
    26  import org.apache.log4j.spi.LoggerRepository;
    27  import org.apache.log4j.spi.LoggerRepositoryEx;
    28
    29  import javax.swing.tree.DefaultMutableTreeNode;
    30  import javax.swing.tree.DefaultTreeModel;
    31  import javax.swing.tree.TreeNode;
    32  import java.beans.PropertyChangeListener;
    33  import java.util.Collection;
    34  import java.util.Enumeration;
    35  import java.util.Vector;
    36
    37
    38  /**
    39   * A TreeModel that encapsulates the details of all the Receivers and their
    40   * related information in the Log4j framework
    41   *
    42   * @author Paul Smith &lt;psmith@apache.org&gt;
    43   */
    44  public class ReceiversTreeModel extends DefaultTreeModel
    45      implements PluginListener {
    46      private static final String ROOTNODE_LABEL = "Receivers";
    47      final DefaultMutableTreeNode NoReceiversNode =
    48          new DefaultMutableTreeNode("No Receivers defined");
    49      final DefaultMutableTreeNode RootNode;
    50      private final Logger logger = LogManager.getLogger(ReceiversTreeModel.class);
    51
    52      ReceiversTreeModel() {
    53          super(new DefaultMutableTreeNode(ROOTNODE_LABEL));
    54          RootNode = (DefaultMutableTreeNode) getRoot();
    55          refresh();
    56      }
    57
    58      /**
    59       * Creates a new ReceiversTreeModel by querying the Log4j Plugin Repository
    60       * and building up the required information.
    61       *
    62       * @return ReceiversTreeModel
    63       */
    64      public final synchronized ReceiversTreeModel refresh() {
    65          RootNode.removeAllChildren();
    66
    67          LoggerRepository repo = LogManager.getLoggerRepository();
    68          Collection receivers;
    69          if (repo instanceof LoggerRepositoryEx) {
    70              receivers = ((LoggerRepositoryEx) repo).getPluginRegistry().getPlugins(Receiver.class);
    71          } else {
    72              receivers = new Vector();
    73          }
    74
    75          updateRootDisplay();
    76
    77          if (receivers.size() == 0) {
    78              getRootNode().add(NoReceiversNode);
    79          } else {
    80              for (Object receiver : receivers) {
    81                  final Receiver item = (Receiver) receiver;
    82                  final DefaultMutableTreeNode receiverNode = new DefaultMutableTreeNode(item);
    83
    84                  item.addPropertyChangeListener(creatPluginPropertyChangeListener(item, receiverNode));
    85                  getRootNode().add(receiverNode);
    86              }
    87          }
    88
    89          reload();
    90
    91          return this;
    92      }
    93
    94      private PropertyChangeListener creatPluginPropertyChangeListener(final Receiver item, final DefaultMutableTreeNode receiverNode) {
    95          return evt -> {
    96              logger.debug(evt.toString());
    97              ReceiversTreeModel.this.fireTreeNodesChanged(item, receiverNode.getPath(), null, null);
    98
    99          };
    100     }
    101
    102     /**
    103      * Ensure the Root node of this tree is updated with the latest information
    104      * and that listeners are notified.
    105      */
    106     void updateRootDisplay() {
    107         getRootNode().setUserObject(ROOTNODE_LABEL);
    108         nodeChanged(getRootNode());
    109     }
    110
    111     DefaultMutableTreeNode getRootNode() {
    112         return (DefaultMutableTreeNode) getRoot();
    113     }
    114
    115     /* (non-Javadoc)
    116      * @see org.apache.log4j.plugins.PluginListener#pluginStarted(org.apache.log4j.plugins.PluginEvent)
    117      */
    118     public void pluginStarted(PluginEvent e) {
    119         if (e.getPlugin() instanceof Receiver) {
    120             if (NoReceiversNode.getParent() == getRootNode()) {
    121                 int index = getRootNode().getIndex(NoReceiversNode);
    122                 getRootNode().remove(NoReceiversNode);
    123                 nodesWereRemoved(
    124                     getRootNode(), new int[]{index}, new Object[]{NoReceiversNode});
    125             }
    126
    127             Receiver receiver = (Receiver) e.getPlugin();
    128             DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(receiver);
    129             getRootNode().add(newNode);
    130             receiver.addPropertyChangeListener(creatPluginPropertyChangeListener(receiver, newNode));
    131             nodesWereInserted(
    132                 getRootNode(), new int[]{getRootNode().getIndex(newNode)});
    133         }
    134     }
    135
    136     TreeNode resolvePluginNode(Plugin p) {
    137         /**
    138          * Lets walk the tree, top-down until we find the node with the plugin
    139          * attached.
    140          *
    141          * Since the tree hierachy is quite flat, this is should not
    142          * be a performance issue at all, but if it is,
    143          * then "I have no recollection of that Senator".
    144          */
    145         TreeNode treeNode = null;
    146         Enumeration e = getRootNode().breadthFirstEnumeration();
    147         while (e.hasMoreElements()) {
    148             DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.nextElement();
    149             if (node.getUserObject().equals(p)) {
    150                 treeNode = node;
    151                 break;
    152             }
    153         }
    154         return treeNode;
    155     }
    156
    157     /* (non-Javadoc)
    158      * @see org.apache.log4j.plugins.PluginListener#pluginStopped(org.apache.log4j.plugins.PluginEvent)
    159      */
    160     public void pluginStopped(PluginEvent e) {
    161         if (e.getPlugin() instanceof Receiver) {
    162             Receiver receiver = (Receiver) e.getPlugin();
    163             DefaultMutableTreeNode node =
    164                 (DefaultMutableTreeNode) resolvePluginNode(receiver);
    165             if (node != null) {
    166                 int index = getRootNode().getIndex(node);
    167                 getRootNode().remove(node);
    168                 nodesWereRemoved(
    169                     getRootNode(), new int[]{index}, new Object[]{node});
    170             }
    171
    172             if (getRootNode().getChildCount() == 0) {
    173                 getRootNode().add(NoReceiversNode);
    174
    175                 int index = getRootNode().getIndex(NoReceiversNode);
    176                 nodesWereInserted(getRootNode(), new int[]{index});
    177             }
    178         }
    179     }
    180 }