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  /*
19   */
20  package org.apache.log4j.chainsaw;
21  
22  import java.util.Collections;
23  import java.util.Comparator;
24  import java.util.Enumeration;
25  import java.util.HashMap;
26  import java.util.Map;
27  import java.util.StringTokenizer;
28  
29  import javax.swing.SwingUtilities;
30  import javax.swing.tree.DefaultMutableTreeNode;
31  import javax.swing.tree.DefaultTreeModel;
32  import javax.swing.tree.MutableTreeNode;
33  
34  import org.apache.log4j.LogManager;
35  import org.apache.log4j.Logger;
36  
37  
38  /***
39   *
40   * A TreeModel that represents the Loggers for a given LogPanel
41   *
42   * @author Paul Smith <psmith@apaceh.org>
43   */
44  class LogPanelLoggerTreeModel extends DefaultTreeModel
45    implements LoggerNameListener {
46    private Map fullPackageMap = new HashMap();
47    private final Logger logger = LogManager.getLogger(LogPanelLoggerTreeModel.class);
48  
49    LogPanelLoggerTreeModel() {
50      super(new LogPanelTreeNode("Root Logger"));
51    }
52  
53    /* (non-Javadoc)
54     * @see org.apache.log4j.chainsaw.LoggerNameListener#loggerNameAdded(java.lang.String)
55     */
56    public void loggerNameAdded(final String loggerName) {
57      SwingUtilities.invokeLater(
58        new Runnable() {
59          public void run() {
60            addLoggerNameInDispatchThread(loggerName);
61          }
62        });
63    }
64  
65    private void addLoggerNameInDispatchThread(final String loggerName) {
66      String[] packages = tokenize(loggerName);
67  
68      /***
69       * The packages array is effectively the tree
70       * path that must exist within the tree, so
71       * we walk the tree ensuring each level is present
72       */
73      DefaultMutableTreeNode current = (DefaultMutableTreeNode) getRoot();
74  
75  
76  /***
77   * This label is used to break out when descending the
78   * current tree hierachy, and it has matched a package name
79   * with an already existing TreeNode.
80   */
81  outerFor: 
82      for (int i = 0; i < packages.length; i++) {
83        String packageName = packages[i];
84        Enumeration enumeration = current.children();
85  
86        while (enumeration.hasMoreElements()) {
87          DefaultMutableTreeNode child =
88            (DefaultMutableTreeNode) enumeration.nextElement();
89          String childName = child.getUserObject().toString();
90  
91          if (childName.equals(packageName)) {
92            /***
93             * This the current known branch to descend
94             */
95            current = child;
96  
97            /***
98             * we've found it, so break back to the outer
99             * for loop to continue processing further
100            * down the tree
101            */
102           continue outerFor;
103         }
104       }
105 
106       /*
107        * So we haven't found this index in the current children,
108        * better create the child
109        */
110       final LogPanelTreeNode newChild = new LogPanelTreeNode(packageName);
111 
112       StringBuffer fullPackageBuf = new StringBuffer();
113 
114       for (int j = 0; j <= i; j++) {
115         fullPackageBuf.append(packages[j]);
116 
117         if (j < i) {
118           fullPackageBuf.append(".");
119         }
120       }
121 
122       logger.debug("Adding to Map " + fullPackageBuf.toString());
123       fullPackageMap.put(fullPackageBuf.toString(), newChild);
124 
125       final DefaultMutableTreeNode changedNode = current;
126 
127       changedNode.add(newChild);
128 
129       final int[] changedIndices = new int[changedNode.getChildCount()];
130 
131       for (int j = 0; j < changedIndices.length; j++) {
132         changedIndices[j] = j;
133       }
134 
135       nodesWereInserted(
136         changedNode, new int[] { changedNode.getIndex(newChild) });
137       nodesChanged(changedNode, changedIndices);
138       current = newChild;
139     }
140   }
141 
142   LogPanelTreeNode lookupLogger(String newLogger) {
143     if (fullPackageMap.containsKey(newLogger)) {
144       return (LogPanelTreeNode) fullPackageMap.get(newLogger);
145     }else{
146         logger.debug("No logger found matching '" + newLogger + "'");
147         logger.debug("Map Dump: " + fullPackageMap);
148     }
149 
150     return null;
151   }
152 
153   /***
154      * Takes the loggerName and tokenizes it into it's
155      * package name lements returning the elements
156      * via the Stirng[]
157      * @param loggerName
158      * @return array of strings representing the package hierarchy
159      */
160   private String[] tokenize(String loggerName) {
161     StringTokenizer tok = new StringTokenizer(loggerName, ".");
162 
163     String[] tokens = new String[tok.countTokens()];
164 
165     int index = 0;
166 
167     while (tok.hasMoreTokens()) {
168       tokens[index++] = tok.nextToken();
169     }
170 
171     return tokens;
172   }
173 
174   private static class LogPanelTreeNode extends DefaultMutableTreeNode {
175     protected static Comparator nodeComparator =
176       new Comparator() {
177         public int compare(Object o1, Object o2) {
178           return o1.toString().compareToIgnoreCase(o2.toString());
179         }
180 
181         public boolean equals(Object obj) {
182           return false;
183         }
184       };
185 
186     private LogPanelTreeNode(String logName) {
187       super(logName);
188     }
189 
190     public void insert(MutableTreeNode newChild, int childIndex) {
191       //      logger.debug("[" + this.getUserObject() + "] inserting child " + newChild + " @ index " + childIndex);
192       //      logger.debug("Children now: " + this.children);
193       super.insert(newChild, childIndex);
194 
195       //	  logger.debug("Children after insert: " + this.children);
196       Collections.sort(this.children, nodeComparator);
197 
198       //	  logger.debug("Children after sort: " + this.children);
199     }
200   }
201 }