KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > navigation > ElementNode


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.java.navigation;
20
21
22 import java.awt.Image JavaDoc;
23 import java.util.Comparator JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.HashSet JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Set JavaDoc;
28 import javax.lang.model.element.Element;
29 import javax.lang.model.element.ElementKind;
30 import javax.lang.model.element.Modifier;
31 import javax.swing.Action JavaDoc;
32 import org.netbeans.api.java.source.ElementHandle;
33 import org.netbeans.api.java.source.UiUtils;
34 import org.netbeans.modules.java.navigation.ElementNode.Description;
35 import org.netbeans.modules.java.navigation.actions.OpenAction;
36 import org.openide.filesystems.FileObject;
37 import org.openide.nodes.AbstractNode;
38 import org.openide.nodes.Children;
39 import org.openide.nodes.Children;
40 import org.openide.nodes.Node;
41 import org.openide.util.Utilities;
42
43 /** Node representing an Element
44  *
45  * @author Petr Hrebejk
46  */

47 public class ElementNode extends AbstractNode {
48
49     
50     private static Node WAIT_NODE;
51     
52     private OpenAction openAction;
53     private Description description;
54            
55     /** Creates a new instance of TreeNode */
56     public ElementNode( Description description ) {
57         super(description.subs == null ? Children.LEAF: new ElementChilren(description.subs, description.ui.getFilters()));
58         this.description = description;
59         setDisplayName( description.name );
60     }
61     
62     
63     @Override JavaDoc
64     public Image JavaDoc getIcon(int type) {
65          return description.kind == null ? super.getIcon(type) : Utilities.icon2Image(UiUtils.getElementIcon(description.kind, description.modifiers));
66     }
67
68     @Override JavaDoc
69     public Image JavaDoc getOpenedIcon(int type) {
70         return getIcon(type);
71     }
72                    
73     @Override JavaDoc
74     public java.lang.String JavaDoc getDisplayName() {
75         return description.name;
76     }
77             
78     @Override JavaDoc
79     public String JavaDoc getHtmlDisplayName() {
80         return description.htmlHeader;
81     }
82     
83     @Override JavaDoc
84     public Action JavaDoc[] getActions( boolean context ) {
85         
86         if ( context || description.name == null ) {
87             return description.ui.getActions();
88         }
89         else {
90             Action JavaDoc panelActions[] = description.ui.getActions();
91             
92             Action JavaDoc actions[] = new Action JavaDoc[ 2 + panelActions.length ];
93             actions[0] = getOpenAction();
94             actions[1] = null;
95             for( int i = 0; i < panelActions.length; i++ ){
96                 actions[2 + i] = panelActions[i];
97             }
98             return actions;
99         }
100     }
101     
102     @Override JavaDoc
103     public Action JavaDoc getPreferredAction() {
104         return getOpenAction();
105     }
106     
107     
108     private synchronized Action JavaDoc getOpenAction() {
109         if ( openAction == null ) {
110             FileObject fo = description.ui.getFileObject();
111             openAction = new OpenAction(description.elementHandle, fo);
112         }
113         return openAction;
114     }
115     
116     static synchronized Node getWaitNode() {
117         if ( WAIT_NODE == null ) {
118             WAIT_NODE = new WaitNode();
119         }
120         return WAIT_NODE;
121     }
122     
123     public void refreshRecursively() {
124         Children ch = getChildren();
125         if ( ch instanceof ElementChilren ) {
126            ((ElementChilren)ch).resetKeys(description.subs, description.ui.getFilters());
127            for( Node sub : ch.getNodes() ) {
128                description.ui.expandNode(sub);
129                ((ElementNode)sub).refreshRecursively();
130            }
131         }
132     }
133     
134     public void updateRecursively( Description newDescription ) {
135         Children ch = getChildren();
136         if ( ch instanceof ElementChilren ) {
137            HashSet JavaDoc<Description> oldSubs = new HashSet JavaDoc<Description>( description.subs );
138
139            
140            // Create a hashtable which maps Description to node.
141
// We will then identify the nodes by the description. The trick is
142
// that the new and old description are equal and have the same hashcode
143
Node[] nodes = ch.getNodes( true );
144            HashMap JavaDoc<Description,ElementNode> oldD2node = new HashMap JavaDoc<Description,ElementNode>();
145            for (Node node : nodes) {
146                oldD2node.put(((ElementNode)node).description, (ElementNode)node);
147            }
148            
149            // Now refresh keys
150
((ElementChilren)ch).resetKeys(newDescription.subs, newDescription.ui.getFilters());
151
152            
153            // Reread nodes
154
nodes = ch.getNodes( true );
155            
156            for( Description newSub : newDescription.subs ) {
157                 ElementNode node = oldD2node.get(newSub);
158                 if ( node != null ) { // filtered out
159
if ( !oldSubs.contains(newSub) && node.getChildren() != Children.LEAF) {
160                         description.ui.expandNode(node); // Make sure new nodes get expanded
161
}
162                     node.updateRecursively( newSub ); // update the node recursively
163
}
164            }
165         }
166                         
167         Description oldDescription = description; // Remember old description
168
description = newDescription; // set new descrioption to the new node
169
if ( oldDescription.htmlHeader != null && !oldDescription.htmlHeader.equals(description.htmlHeader)) {
170             // Different headers => we need to fire displayname change
171
fireDisplayNameChange(oldDescription.htmlHeader, description.htmlHeader);
172         }
173         if( oldDescription.modifiers != null && !oldDescription.modifiers.equals(newDescription.modifiers)) {
174             fireIconChange();
175             fireOpenedIconChange();
176         }
177     }
178     
179     public Description getDescritption() {
180         return description;
181     }
182     
183     private static final class ElementChilren extends Children.Keys<Description> {
184             
185         public ElementChilren(List JavaDoc<Description> descriptions, ClassMemberFilters filters ) {
186             resetKeys( descriptions, filters );
187         }
188         
189         protected Node[] createNodes(Description key) {
190             return new Node[] {new ElementNode(key)};
191         }
192         
193         void resetKeys( List JavaDoc<Description> descriptions, ClassMemberFilters filters ) {
194             setKeys( filters.filter(descriptions) );
195         }
196         
197         
198                         
199     }
200                        
201     /** Stores all interesting data about given element.
202      */

203     static class Description {
204         
205         public static final Comparator JavaDoc<Description> ALPHA_COMPARATOR =
206             new DescriptionComparator(true);
207         public static final Comparator JavaDoc<Description> POSITION_COMPARATOR =
208             new DescriptionComparator(false);
209         
210         ClassMemberPanelUI ui;
211                 
212         FileObject fileObject; // For the root description
213

214         final String JavaDoc name;
215         final ElementHandle<? extends Element> elementHandle;
216         final ElementKind kind;
217         Set JavaDoc<Modifier> modifiers;
218         List JavaDoc<Description> subs;
219         String JavaDoc htmlHeader;
220         long pos;
221         
222         Description( ClassMemberPanelUI ui ) {
223             this.ui = ui;
224             this.name = null;
225             this.elementHandle = null;
226             this.kind = null;
227         }
228          
229         Description(ClassMemberPanelUI ui,
230                     String JavaDoc name,
231                     ElementHandle<? extends Element> elementHandle,
232                     ElementKind kind ) {
233             this.ui = ui;
234             this.name = name;
235             this.elementHandle = elementHandle;
236             this.kind = kind;
237         }
238
239         
240         
241         @Override JavaDoc
242         public boolean equals(Object JavaDoc o) {
243                         
244             if ( o == null ) {
245                 //System.out.println("- f nul");
246
return false;
247             }
248             
249             if ( !(o instanceof Description)) {
250                 // System.out.println("- not a desc");
251
return false;
252             }
253             
254             Description d = (Description)o;
255             
256             if ( kind != d.kind ) {
257                 // System.out.println("- kind");
258
return false;
259             }
260             
261             if ( !name.equals(d.name) ) {
262                 // System.out.println("- name");
263
return false;
264             }
265             
266             if ( !this.elementHandle.signatureEquals(d.elementHandle) ) {
267                 return false;
268             }
269             
270             /*
271             if ( !modifiers.equals(d.modifiers)) {
272                 // E.println("- modifiers");
273                 return false;
274             }
275             */

276             
277             // System.out.println("Equals called");
278
return true;
279         }
280         
281         
282         public int hashCode() {
283             int hash = 7;
284
285             hash = 29 * hash + (this.name != null ? this.name.hashCode() : 0);
286             hash = 29 * hash + (this.kind != null ? this.kind.hashCode() : 0);
287             // hash = 29 * hash + (this.modifiers != null ? this.modifiers.hashCode() : 0);
288
return hash;
289         }
290         
291         private static class DescriptionComparator implements Comparator JavaDoc<Description> {
292             
293             boolean alpha;
294             
295             DescriptionComparator( boolean alpha ) {
296                 this.alpha = alpha;
297             }
298             
299             public int compare(Description d1, Description d2) {
300                 
301                 if ( alpha ) {
302                     if ( k2i(d1.kind) != k2i(d2.kind) ) {
303                         return k2i(d1.kind) - k2i(d2.kind);
304                     }
305                     
306                     return d1.name.compareTo(d2.name);
307                 }
308                 else {
309                     return d1.pos == d2.pos ? 0 : d1.pos < d2.pos ? -1 : 1;
310                 }
311             }
312             
313             int k2i( ElementKind kind ) {
314                 switch( kind ) {
315                     case CONSTRUCTOR:
316                         return 1;
317                     case METHOD:
318                         return 2;
319                     case FIELD:
320                         return 3;
321                     case CLASS:
322                     case INTERFACE:
323                     case ENUM:
324                     case ANNOTATION_TYPE:
325                         return 4;
326                     default:
327                         return 100;
328                 }
329             }
330             
331         }
332         
333     }
334         
335     private static class WaitNode extends AbstractNode {
336         
337         private Image JavaDoc waitIcon = Utilities.loadImage("org/netbeans/modules/java/navigation/resources/wait.gif"); // NOI18N
338

339         WaitNode( ) {
340             super( Children.LEAF );
341         }
342         
343         @Override JavaDoc
344         public Image JavaDoc getIcon(int type) {
345              return waitIcon;
346         }
347
348         @Override JavaDoc
349         public Image JavaDoc getOpenedIcon(int type) {
350             return getIcon(type);
351         }
352
353         @java.lang.Override JavaDoc
354         public java.lang.String JavaDoc getDisplayName() {
355             return "Please Wait...";
356         }
357         
358     }
359     
360     
361 }
362
Popular Tags