KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > jclasslib > browser > BrowserTreePane


1 /*
2     This library is free software; you can redistribute it and/or
3     modify it under the terms of the GNU General Public
4     License as published by the Free Software Foundation; either
5     version 2 of the license, or (at your option) any later version.
6 */

7
8 package org.gjt.jclasslib.browser;
9
10 import org.gjt.jclasslib.structures.*;
11 import org.gjt.jclasslib.structures.attributes.*;
12 import org.gjt.jclasslib.structures.constants.ConstantLargeNumeric;
13 import org.gjt.jclasslib.structures.elementvalues.*;
14
15 import javax.swing.*;
16 import javax.swing.tree.*;
17 import java.awt.*;
18 import java.util.HashMap JavaDoc;
19 import java.util.Map JavaDoc;
20
21 /**
22  * The pane containing the tree structure for the class file shown in the
23  * child window.
24  *
25  * @author <a HREF="mailto:jclasslib@ej-technologies.com">Ingo Kegel</a>, <a HREF="mailto:vitor.carreira@gmail.com">Vitor Carreira</a>
26  * @version $Revision: 1.10 $ $Date: 2004/12/28 13:04:31 $
27  */

28 public class BrowserTreePane extends JPanel {
29
30     private static final Dimension treeMinimumSize = new Dimension(100, 150);
31     private static final Dimension treePreferredSize = new Dimension(250, 150);
32
33     private BrowserServices services;
34     private JTree tree;
35     private Map JavaDoc categoryToPath = new HashMap JavaDoc();
36
37     /**
38      * Constructor.
39      *
40      * @param services the associated browser services.
41      */

42     public BrowserTreePane(BrowserServices services) {
43         this.services = services;
44         setLayout(new BorderLayout());
45         setupComponent();
46     }
47
48     /**
49      * Get the tree view.
50      *
51      * @return the tree view
52      */

53     public JTree getTree() {
54         return tree;
55     }
56
57     /**
58      * Get the tree path for a given category.
59      *
60      * @param category the category. One the <tt>BrowserTree.NODE_</tt> constants.
61      * @return the tree path.
62      */

63     public TreePath getPathForCategory(String JavaDoc category) {
64         return (TreePath)categoryToPath.get(category);
65     }
66
67     /**
68      * Show the specified method if it exists.
69      *
70      * @param methodName the name of the method
71      * @param methodSignature the signature of the method (in class file format)
72      */

73     public void showMethod(String JavaDoc methodName, String JavaDoc methodSignature) {
74
75         TreePath methodsPath = (TreePath)categoryToPath.get(BrowserTreeNode.NODE_METHOD);
76         if (methodsPath == null) {
77             return;
78         }
79         MethodInfo[] methods = services.getClassFile().getMethods();
80         TreeNode methodsNode = (TreeNode)methodsPath.getLastPathComponent();
81         for (int i = 0; i < methodsNode.getChildCount(); i++) {
82             BrowserTreeNode treeNode = (BrowserTreeNode)methodsNode.getChildAt(i);
83             MethodInfo testMethod = methods[treeNode.getIndex()];
84             try {
85                 if (testMethod.getName().equals(methodName) && testMethod.getDescriptor().equals(methodSignature)) {
86                     TreePath path = methodsPath.pathByAddingChild(treeNode);
87                     BrowserTreeNode codeNode = findCodeNode(treeNode, testMethod);
88                     if (codeNode != null) {
89                         path = path.pathByAddingChild(codeNode);
90                     }
91
92                     tree.makeVisible(path);
93                     tree.scrollPathToVisible(path);
94                     tree.setSelectionPath(path);
95                     return;
96                 }
97             } catch (InvalidByteCodeException ex) {
98             }
99         }
100     }
101
102     /**
103      * Rebuild the tree from the <tt>ClassFile</tt> object.
104      */

105     public void rebuild() {
106         categoryToPath.clear();
107         tree.clearSelection();
108         tree.setModel(buildTreeModel());
109     }
110
111     private void setupComponent() {
112
113         JScrollPane treeScrollPane = new JScrollPane(buildTree());
114         treeScrollPane.setMinimumSize(treeMinimumSize);
115         treeScrollPane.setPreferredSize(treePreferredSize);
116
117         add(treeScrollPane, BorderLayout.CENTER);
118     }
119
120     private JTree buildTree() {
121
122         tree = new JTree(buildTreeModel());
123
124         tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
125         tree.setRootVisible(false);
126         tree.setShowsRootHandles(true);
127
128         return tree;
129     }
130
131     private TreeModel buildTreeModel() {
132         BrowserTreeNode rootNode = buildRootNode();
133         DefaultTreeModel treeModel = new DefaultTreeModel(rootNode);
134
135         return treeModel;
136     }
137
138     private BrowserTreeNode buildRootNode() {
139
140         BrowserTreeNode rootNode = new BrowserTreeNode("Class file");
141         ClassFile classFile = services.getClassFile();
142         if (classFile != null) {
143
144             BrowserTreeNode generalNode = new BrowserTreeNode("General Information", BrowserTreeNode.NODE_GENERAL);
145             BrowserTreeNode constantPoolNode = buildConstantPoolNode();
146             BrowserTreeNode interfacesNode = buildInterfacesNode();
147             BrowserTreeNode fieldsNode = buildFieldsNode();
148             BrowserTreeNode methodsNode = buildMethodsNode();
149             BrowserTreeNode attributesNode = buildAttributesNode();
150
151             rootNode.add(generalNode);
152             rootNode.add(constantPoolNode);
153             rootNode.add(interfacesNode);
154             rootNode.add(fieldsNode);
155             rootNode.add(methodsNode);
156             rootNode.add(attributesNode);
157
158             categoryToPath.put(BrowserTreeNode.NODE_GENERAL, new TreePath(new Object JavaDoc[]{rootNode, generalNode}));
159             categoryToPath.put(BrowserTreeNode.NODE_CONSTANT_POOL, new TreePath(new Object JavaDoc[]{rootNode, constantPoolNode}));
160             categoryToPath.put(BrowserTreeNode.NODE_INTERFACE, new TreePath(new Object JavaDoc[]{rootNode, interfacesNode}));
161             categoryToPath.put(BrowserTreeNode.NODE_FIELD, new TreePath(new Object JavaDoc[]{rootNode, fieldsNode}));
162             categoryToPath.put(BrowserTreeNode.NODE_METHOD, new TreePath(new Object JavaDoc[]{rootNode, methodsNode}));
163             categoryToPath.put(BrowserTreeNode.NODE_ATTRIBUTE, new TreePath(new Object JavaDoc[]{rootNode, attributesNode}));
164         }
165
166         return rootNode;
167     }
168
169     private BrowserTreeNode buildConstantPoolNode() {
170
171         BrowserTreeNode constantPoolNode = new BrowserTreeNode("Constant Pool");
172
173         CPInfo[] constantPool = services.getClassFile().getConstantPool();
174         int constantPoolCount = constantPool.length;
175
176         for (int i = 1; i < constantPoolCount; i++) {
177             i += addConstantPoolEntry(constantPool[i], i, constantPoolCount, constantPoolNode);
178         }
179
180         return constantPoolNode;
181     }
182
183     private int addConstantPoolEntry(CPInfo constantPoolEntry,
184                                      int index,
185                                      int constantPoolCount,
186                                      BrowserTreeNode constantPoolNode) {
187
188
189         if (constantPoolEntry == null) {
190             constantPoolNode.add(buildNullNode());
191         } else {
192             BrowserTreeNode entryNode =
193                     new BrowserTreeNode(getFormattedIndex(index, constantPoolCount) +
194                     constantPoolEntry.getTagVerbose(),
195                             BrowserTreeNode.NODE_CONSTANT_POOL,
196                             index);
197
198             constantPoolNode.add(entryNode);
199             if (constantPoolEntry instanceof ConstantLargeNumeric) {
200                 addConstantPoolContinuedEntry(index + 1,
201                         constantPoolCount,
202                         constantPoolNode);
203                 return 1;
204             }
205         }
206         return 0;
207     }
208
209     private void addConstantPoolContinuedEntry(int index,
210                                                int constantPoolCount,
211                                                BrowserTreeNode constantPoolNode) {
212
213         BrowserTreeNode entryNode =
214                 new BrowserTreeNode(getFormattedIndex(index, constantPoolCount) +
215                 "(large numeric continued)",
216                         BrowserTreeNode.NODE_NO_CONTENT);
217         constantPoolNode.add(entryNode);
218     }
219
220     private BrowserTreeNode buildInterfacesNode() {
221
222         BrowserTreeNode interfacesNode = new BrowserTreeNode("Interfaces");
223         int[] interfaces = services.getClassFile().getInterfaces();
224         int interfacesCount = interfaces.length;
225         BrowserTreeNode entryNode;
226         for (int i = 0; i < interfacesCount; i++) {
227             entryNode = new BrowserTreeNode("Interface " + i,
228                     BrowserTreeNode.NODE_INTERFACE,
229                     i);
230             interfacesNode.add(entryNode);
231         }
232
233         return interfacesNode;
234     }
235
236     private BrowserTreeNode buildFieldsNode() {
237
238         return buildClassMembersNode("Fields",
239                 BrowserTreeNode.NODE_FIELD,
240                 services.getClassFile().getFields());
241     }
242
243     private BrowserTreeNode buildMethodsNode() {
244
245         return buildClassMembersNode("Methods",
246                 BrowserTreeNode.NODE_METHOD,
247                 services.getClassFile().getMethods());
248     }
249
250     private BrowserTreeNode buildClassMembersNode(String JavaDoc text,
251                                                   String JavaDoc type,
252                                                   ClassMember[] classMembers) {
253
254         BrowserTreeNode classMemberNode = new BrowserTreeNode(text);
255         int classMembersCount = classMembers.length;
256
257         for (int i = 0; i < classMembersCount; i++) {
258             addClassMembersNode(classMembers[i],
259                     i,
260                     classMembersCount,
261                     type,
262                     classMemberNode);
263         }
264
265         return classMemberNode;
266     }
267
268     private void addClassMembersNode(ClassMember classMember,
269                                      int index,
270                                      int classMembersCount,
271                                      String JavaDoc type,
272                                      BrowserTreeNode classMemberNode) {
273
274         if (classMember == null) {
275             classMemberNode.add(buildNullNode());
276         } else {
277             try {
278                 BrowserTreeNode entryNode =
279                         new BrowserTreeNode(getFormattedIndex(index, classMembersCount) +
280                         classMember.getName(),
281                                 type,
282                                 index);
283
284                 classMemberNode.add(entryNode);
285                 addAttributeNodes(entryNode, classMember);
286
287             } catch (InvalidByteCodeException ex) {
288                 classMemberNode.add(buildNullNode());
289             }
290         }
291     }
292
293     private BrowserTreeNode buildAttributesNode() {
294         BrowserTreeNode attributesNode = new BrowserTreeNode("Attributes");
295
296         addAttributeNodes(attributesNode, services.getClassFile());
297
298         return attributesNode;
299     }
300
301     private BrowserTreeNode buildNullNode() {
302
303         return new BrowserTreeNode("[error] null");
304     }
305
306     private void addAttributeNodes(BrowserTreeNode parentNode,
307                                    AbstractStructureWithAttributes structure) {
308
309         AttributeInfo[] attributes = structure.getAttributes();
310         if (attributes == null) {
311             return;
312         }
313         int attributesCount = attributes.length;
314         for (int i = 0; i < attributesCount; i++) {
315             addSingleAttributeNode(attributes[i],
316                     i,
317                     attributesCount,
318                     parentNode);
319         }
320     }
321
322     private void addSingleAttributeNode(AttributeInfo attribute,
323                                         int index,
324                                         int attributesCount,
325                                         BrowserTreeNode parentNode) {
326
327
328         if (attribute == null) {
329             parentNode.add(buildNullNode());
330         } else {
331             try {
332                 BrowserTreeNode entryNode =
333                         new BrowserTreeNode(getFormattedIndex(index, attributesCount) +
334                         attribute.getName(),
335                                 BrowserTreeNode.NODE_ATTRIBUTE,
336                                 index);
337
338                 parentNode.add(entryNode);
339                 if (attribute instanceof RuntimeAnnotationsAttribute) {
340                     addRuntimeAnnotation(entryNode, (RuntimeAnnotationsAttribute)attribute);
341                 } else if (attribute instanceof AnnotationDefaultAttribute) {
342                     addSingleElementValueEntryNode(((AnnotationDefaultAttribute)attribute).getDefaultValue(), 0, 1, entryNode);
343                 } else {
344                     addAttributeNodes(entryNode, attribute);
345                 }
346
347             } catch (InvalidByteCodeException ex) {
348                 parentNode.add(buildNullNode());
349             }
350         }
351     }
352
353
354     private String JavaDoc getFormattedIndex(int index, int maxIndex) {
355
356         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("[");
357         String JavaDoc indexString = String.valueOf(index);
358         String JavaDoc maxIndexString = String.valueOf(maxIndex - 1);
359         for (int i = 0; i < maxIndexString.length() - indexString.length(); i++) {
360             buffer.append("0");
361         }
362         buffer.append(indexString);
363         buffer.append("]");
364         buffer.append(" ");
365
366         return buffer.toString();
367     }
368
369     private BrowserTreeNode findCodeNode(BrowserTreeNode treeNode, MethodInfo methodInfo) {
370         AttributeInfo[] attributes = methodInfo.getAttributes();
371         for (int i = 0; i < attributes.length; i++) {
372             if (attributes[i] instanceof CodeAttribute) {
373                 return (BrowserTreeNode)treeNode.getChildAt(i);
374             }
375         }
376         return null;
377     }
378
379
380     private void addRuntimeAnnotation(BrowserTreeNode parentNode,
381                                       RuntimeAnnotationsAttribute structure) {
382
383         AnnotationElementValue[] annotations = structure.getRuntimeAnnotations();
384         if (annotations == null) {
385             return;
386         }
387         int annotationsCount = annotations.length;
388         for (int i = 0; i < annotationsCount; i++) {
389             addSingleAnnotationNode(annotations[i],
390                     i,
391                     annotationsCount,
392                     parentNode);
393         }
394     }
395
396     private void addSingleAnnotationNode(AnnotationElementValue annotation,
397                                          int index,
398                                          int attributesCount,
399                                          BrowserTreeNode parentNode) {
400
401
402         if (annotation == null) {
403             parentNode.add(buildNullNode());
404         } else {
405             BrowserTreeNode entryNode =
406                     new BrowserTreeNode(getFormattedIndex(index, attributesCount) +
407                     annotation.getEntryName(),
408                             BrowserTreeNode.NODE_ANNOTATION,
409                             index,
410                             annotation);
411             parentNode.add(entryNode);
412             addElementValuePairEntry(entryNode, annotation);
413         }
414     }
415
416     private void addElementValuePairEntry(BrowserTreeNode parentNode,
417                                           AnnotationElementValue annotation) {
418
419         ElementValuePair[] entries = annotation.getElementValuePairEntries();
420         if (entries == null) {
421             return;
422         }
423         int entriesCount = entries.length;
424         for (int i = 0; i < entriesCount; i++) {
425             addSingleElementValuePairEntryNode(entries[i],
426                     i,
427                     entriesCount,
428                     parentNode);
429         }
430     }
431
432     private void addArrayElementValueEntry(BrowserTreeNode parentNode,
433                                            ArrayElementValue aeve) {
434
435         ElementValue[] entries = aeve.getElementValueEntries();
436         if (entries == null) {
437             return;
438         }
439         int entriesCount = entries.length;
440         for (int i = 0; i < entriesCount; i++) {
441             addSingleElementValueEntryNode(entries[i],
442                     i,
443                     entriesCount,
444                     parentNode);
445         }
446     }
447
448
449     private void addSingleElementValuePairEntryNode(ElementValuePair evep,
450                                                     int index,
451                                                     int attributesCount,
452                                                     BrowserTreeNode parentNode) {
453
454
455         if (evep == null) {
456             parentNode.add(buildNullNode());
457         } else {
458             BrowserTreeNode entryNode =
459                     new BrowserTreeNode(getFormattedIndex(index, attributesCount) +
460                     evep.getEntryName(),
461                             BrowserTreeNode.NODE_ELEMENTVALUEPAIR,
462                             index,
463                             evep);
464             parentNode.add(entryNode);
465             addSingleElementValueEntryNode(evep.getElementValue(), 0, 1, entryNode);
466         }
467     }
468
469     private void addSingleElementValueEntryNode(ElementValue eve,
470                                                 int index,
471                                                 int attributesCount,
472                                                 BrowserTreeNode parentNode) {
473
474         if (eve == null) {
475             parentNode.add(buildNullNode());
476         } else {
477             String JavaDoc prefix = attributesCount > 1 ?
478                     getFormattedIndex(index, attributesCount) : "";
479             String JavaDoc nodeType = BrowserTreeNode.NODE_ELEMENTVALUE;
480             if (eve instanceof AnnotationElementValue) {
481                 nodeType = BrowserTreeNode.NODE_ANNOTATION;
482             } else if (eve instanceof ArrayElementValue) {
483                 nodeType = BrowserTreeNode.NODE_ARRAYELEMENTVALUE;
484             }
485
486             BrowserTreeNode entryNode =
487                     new BrowserTreeNode(prefix + eve.getEntryName(),
488                             nodeType, index, eve);
489
490             parentNode.add(entryNode);
491             if (nodeType == BrowserTreeNode.NODE_ANNOTATION) {
492                 addElementValuePairEntry(entryNode, (AnnotationElementValue)eve);
493             } else if (nodeType == BrowserTreeNode.NODE_ARRAYELEMENTVALUE) {
494                 addArrayElementValueEntry(entryNode, (ArrayElementValue)eve);
495             }
496         }
497     }
498 }
499
Popular Tags