KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > schema > ui > nodes > categorized > CategoryNode


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-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.xml.schema.ui.nodes.categorized;
21
22 import java.awt.Image JavaDoc;
23 import java.awt.datatransfer.Transferable JavaDoc;
24 import java.util.HashSet JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.LinkedList JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.MissingResourceException JavaDoc;
29 import java.util.Set JavaDoc;
30 import javax.swing.Action JavaDoc;
31 import org.netbeans.modules.xml.schema.model.SchemaComponent;
32 import org.netbeans.modules.xml.schema.model.SchemaComponentReference;
33 import org.netbeans.modules.xml.schema.model.SchemaModel;
34 import org.netbeans.modules.xml.schema.ui.nodes.DefaultExpandedCookie;
35 import org.netbeans.modules.xml.schema.ui.nodes.ReadOnlyCookie;
36 import org.netbeans.modules.xml.schema.ui.nodes.RefreshableChildren;
37 import org.netbeans.modules.xml.schema.ui.nodes.SchemaUIContext;
38 import org.netbeans.modules.xml.xam.Component;
39 import org.netbeans.modules.xml.xam.ComponentEvent;
40 import org.netbeans.modules.xml.xam.ComponentListener;
41 import org.netbeans.modules.xml.xam.ui.ComponentPasteType;
42 import org.netbeans.modules.xml.xam.ui.XAMUtils;
43 import org.netbeans.modules.xml.xam.ui.cookies.CountChildrenCookie;
44 import org.netbeans.modules.xml.xam.ui.highlight.Highlight;
45 import org.netbeans.modules.xml.xam.ui.highlight.Highlighted;
46 import org.netbeans.modules.xml.xam.ui.highlight.HighlightManager;
47 import org.openide.actions.NewAction;
48 import org.openide.actions.PasteAction;
49 import org.openide.filesystems.FileObject;
50 import org.openide.filesystems.Repository;
51 import org.openide.loaders.DataObject;
52 import org.openide.loaders.DataObjectNotFoundException;
53 import org.openide.nodes.AbstractNode;
54 import org.openide.nodes.Children;
55 import org.openide.nodes.Index;
56 import org.openide.nodes.Node;
57 import org.openide.util.HelpCtx;
58 import org.openide.util.Lookup;
59 import org.openide.util.NbBundle;
60 import org.openide.util.Utilities;
61 import org.openide.util.WeakListeners;
62 import org.openide.util.actions.SystemAction;
63 import org.openide.util.datatransfer.NewType;
64 import org.openide.util.datatransfer.PasteType;
65 import org.openide.util.lookup.AbstractLookup;
66 import org.openide.util.lookup.InstanceContent;
67 import org.openide.util.lookup.Lookups;
68 import org.openide.util.lookup.ProxyLookup;
69
70 /**
71  *
72  * @author Todd Fast, todd.fast@sun.com
73  */

74 public class CategoryNode extends AbstractNode
75         implements Node.Cookie, ComponentListener, Highlighted,
76         CountChildrenCookie {
77
78     /**
79      *
80      *
81      */

82     public CategoryNode(SchemaUIContext context,
83         SchemaComponentReference<? extends SchemaComponent> parentReference,
84         Class JavaDoc<? extends SchemaComponent> childType,
85         RefreshableChildren children)
86     {
87         this(context,parentReference,childType,children,new InstanceContent());
88     }
89
90
91     /**
92      * Constructor HACK to allow creation of our own lookup
93      *
94      */

95     private CategoryNode(SchemaUIContext context,
96         SchemaComponentReference<? extends SchemaComponent> parentReference,
97         Class JavaDoc<? extends SchemaComponent> childType,
98         Children children,
99         InstanceContent contents)
100     {
101         super(children, createLookup(context, contents));
102         this.context=context;
103         this.reference=parentReference;
104         this.childType=childType;
105         this.lookupContents=contents;
106
107         // Add various objects to the lookup
108
try {
109                     // Include the data object in order for the Navigator to
110
// show the structure of the current document.
111
FileObject fobj = (FileObject) reference.get().getModel().
112                             getModelSource().getLookup().lookup(FileObject.class);
113                     if (fobj != null) {
114                         contents.add(DataObject.find(fobj));
115                     }
116                 } catch (DataObjectNotFoundException donfe) {
117                 }
118         contents.add(this);
119         contents.add(context);
120
121         // Expand all nodes except the "All" node by default
122
contents.add(new DefaultExpandedCookie(true));
123                 // For the 'All Components' node, allow reordering of the nodes.
124
if (childType.equals(SchemaComponent.class) &&
125                         children instanceof Index) {
126                     contents.add(children);
127                 }
128
129         // Get the name based on the child types this node will show
130
String JavaDoc name=childType.getName();
131         // Find a friendly name
132
try
133         {
134             name = NbBundle.getMessage(CategoryNode.class,
135                 "LBL_CategoryNode_" + name);
136         }
137         catch (MissingResourceException JavaDoc e)
138         {
139             assert false: e;
140         }
141         
142         setName(name);
143         setDisplayName(name);
144
145         // TODO: Need to allow the children object to do the work here
146
SchemaModel model = parentReference.get().getModel();
147                 weakComponentListener = (ComponentListener) WeakListeners.create(
148                         ComponentListener.class, this, model);
149                 model.addComponentListener(weakComponentListener);
150
151                 referenceSet = new HashSet JavaDoc<Component>();
152                 highlights = new LinkedList JavaDoc<Highlight>();
153                 HighlightManager hm = HighlightManager.getDefault();
154                 // Must check for the existence of the highlight manager
155
// since the component selection panel does not highlight.
156
SchemaComponent comp = (SchemaComponent) reference.get();
157                 List JavaDoc<? extends SchemaComponent> subcomps = comp.getChildren(childType);
158                 Iterator JavaDoc<? extends SchemaComponent> iter = subcomps.iterator();
159                 while (iter.hasNext()) {
160                     referenceSet.add(iter.next());
161                 }
162                 hm.addHighlighted(this);
163     }
164
165         /**
166          * Create a lookup for this node, based on the given contents.
167          *
168          * @param context from which a Lookup is retrieved.
169          * @param contents the basis of our new lookup.
170          */

171         private static Lookup createLookup(SchemaUIContext context,
172                 InstanceContent contents) {
173             // We want our lookup to be based on the lookup from the context,
174
// which provides a few necessary objects, such as a SaveCookie.
175
// However, we do not want the Nodes or DataObjects, since we
176
// provide our own.
177
return new ProxyLookup(new Lookup[] {
178                 Lookups.exclude(context.getLookup(), new Class JavaDoc[] {
179                     Node.class,
180                     DataObject.class,
181                 }),
182                 new AbstractLookup(contents),
183             });
184         }
185
186         @Override JavaDoc
187         public boolean equals(Object JavaDoc o) {
188             // Without this, the tree view collapses when nodes are changed.
189
if (o instanceof CategoryNode) {
190                 CategoryNode cn = (CategoryNode) o;
191                 String JavaDoc name = getName();
192                 String JavaDoc oname = cn.getName();
193                 if (name != null && oname != null) {
194                     SchemaComponentReference scr = cn.getReference();
195                     return name.equals(oname) && scr.equals(reference);
196                 }
197             }
198             return false;
199         }
200
201     /**
202      *
203      *
204      */

205     public int hashCode() {
206         // Without this, the tree view collapses when nodes are changed.
207
return getName().hashCode();
208     }
209
210         public int getChildCount() {
211             return getReference().get().getChildren(getChildType()).size();
212         }
213
214     /**
215      *
216      *
217      */

218     public SchemaUIContext getContext()
219     {
220         return context;
221     }
222
223
224     /**
225      *
226      *
227      */

228     public SchemaComponentReference<? extends SchemaComponent> getReference()
229     {
230         return reference;
231     }
232
233
234     /**
235      *
236      *
237      */

238     public Class JavaDoc<? extends SchemaComponent> getChildType()
239     {
240         return childType;
241     }
242
243
244     /**
245      * Returns the contents of the lookup. All cookies and other objects that
246      * should be findable via the lookup should be added to this.
247      *
248      */

249     protected InstanceContent getLookupContents()
250     {
251         return lookupContents;
252     }
253
254
255     /**
256      *
257      *
258      */

259     public boolean isDefaultExpanded()
260     {
261         DefaultExpandedCookie cookie=(DefaultExpandedCookie)
262             getCookie(DefaultExpandedCookie.class);
263         if (cookie!=null)
264             return cookie.isDefaultExpanded();
265         else
266             return false;
267     }
268
269
270     /**
271      *
272      *
273      */

274     public void setDefaultExpanded(boolean value)
275     {
276         DefaultExpandedCookie cookie=(DefaultExpandedCookie)
277             getCookie(DefaultExpandedCookie.class);
278         if (cookie!=null)
279             cookie.setDefaultExpanded(value);
280     }
281
282
283
284
285     ////////////////////////////////////////////////////////////////////////////
286
// Node methods
287
////////////////////////////////////////////////////////////////////////////
288

289     /**
290      *
291      *
292      */

293     @Override JavaDoc
294     public HelpCtx getHelpCtx()
295     {
296         return new HelpCtx(getClass());
297     }
298
299
300     /**
301      *
302      *
303      */

304     @Override JavaDoc
305     public boolean canCut()
306     {
307         return false;
308     }
309
310
311     /**
312      *
313      *
314      */

315     @Override JavaDoc
316     public boolean canCopy()
317     {
318         return false;
319     }
320
321         @SuppressWarnings JavaDoc("unchecked")
322         protected void createPasteTypes(Transferable JavaDoc transferable, List JavaDoc list) {
323             if (isValid() && isEditable()) {
324                 PasteType type = ComponentPasteType.getPasteType(
325                         reference.get(), transferable, childType);
326                 if (type != null) {
327                     list.add(type);
328                 }
329             }
330         }
331
332         @Override JavaDoc
333         public PasteType getDropType(Transferable JavaDoc transferable, int action, int index) {
334             if (isValid() && isEditable()) {
335                 PasteType type = ComponentPasteType.getDropType(
336                         reference.get(), transferable, childType, action, index);
337                 if (type != null) {
338                     return type;
339                 }
340             }
341             return null;
342         }
343
344     /**
345      *
346      *
347      */

348     @Override JavaDoc
349     public boolean canDestroy()
350     {
351         return false;
352     }
353
354
355     /**
356      *
357      *
358      */

359     @Override JavaDoc
360     public boolean canRename()
361     {
362         return false;
363     }
364
365
366     /**
367      *
368      *
369      */

370     @Override JavaDoc
371         public Action JavaDoc[] getActions(boolean b)
372         {
373             ReadOnlyCookie roc = (ReadOnlyCookie) getContext().getLookup().lookup(
374                     ReadOnlyCookie.class);
375             if (roc != null && roc.isReadOnly()) {
376                 return ACTIONS_READONLY;
377             } else {
378                 return ACTIONS;
379             }
380         }
381
382
383     /**
384      *
385      *
386      */

387     public NewType[] getNewTypes()
388     {
389         SchemaModel model = getReference().get().getModel();
390         if(model!=null && isEditable())
391         {
392             return new AdvancedNewTypesFactory().getNewTypes(getReference(),
393                     getChildType());
394         }
395         return new NewType[0];
396     }
397
398
399
400
401     ////////////////////////////////////////////////////////////////////////////
402
// Listener methods
403
////////////////////////////////////////////////////////////////////////////
404

405         public boolean isValid() {
406             return getReference().get() != null && getReference().get().getModel() != null;
407         }
408         
409     protected boolean isEditable() {
410         SchemaModel model = getReference().get().getModel();
411         return model != null && model == getContext().getModel() &&
412                 XAMUtils.isWritable(model);
413     }
414     
415     /**
416      *
417      *
418      */

419     public void childrenAdded(ComponentEvent evt) {
420              if (! isValid()) return;
421         if (evt.getSource() == getReference().get()) {
422             ((RefreshableChildren) getChildren()).refreshChildren();
423         }
424     }
425
426
427     /**
428      *
429      *
430      */

431     public void childrenDeleted(ComponentEvent evt) {
432              if (! isValid()) return;
433         if (evt.getSource() == getReference().get()) {
434             ((RefreshableChildren) getChildren()).refreshChildren();
435         }
436     }
437
438
439     /**
440      *
441      *
442      */

443     public void valueChanged(ComponentEvent evt) {
444              if (! isValid()) return;
445         // Do nothing
446
}
447
448         public Set JavaDoc<Component> getComponents() {
449             return referenceSet;
450         }
451
452         public void highlightAdded(Highlight hl) {
453             highlights.add(hl);
454             fireDisplayNameChange("TempName", getDisplayName());
455         }
456
457         public void highlightRemoved(Highlight hl) {
458             highlights.remove(hl);
459             fireDisplayNameChange("TempName", getDisplayName());
460         }
461
462         /**
463          * Given a display name, add the appropriate HTML tags to highlight
464          * the display name as dictated by any Highlights associated with
465          * this node.
466          *
467          * @param name current display name.
468          * @return marked up display name.
469          */

470         protected String JavaDoc applyHighlights(String JavaDoc name) {
471             int count = highlights.size();
472             if (count > 0) {
473                 // Apply the last highlight that was added to our list.
474
String JavaDoc code = null;
475                 Highlight hl = highlights.get(count - 1);
476                 String JavaDoc type = hl.getType();
477                 if (type.equals(Highlight.SEARCH_RESULT) ||
478                         type.equals(Highlight.SEARCH_RESULT_PARENT)) {
479                     // Always use the parent color for search results, as
480
// a category cannot possibly be a search result.
481
code = "ffc73c";
482                 }
483                 else if (type.equals(Highlight.FIND_USAGES_RESULT) ||
484                         type.equals(Highlight.FIND_USAGES_RESULT_PARENT)) {
485                     // Always use the parent color for search results, as
486
// a category cannot possibly be a search result.
487
// color = chartreuse
488
code = "c7ff3c";
489                 }
490                 
491                 name = "<strong><font color=\"#" + code + "\">" + name +
492                     "</font></strong>";
493             }
494             return name;
495         }
496
497     private Node getFolderNode() {
498         FileObject fo =
499         Repository.getDefault().getDefaultFileSystem().getRoot();
500         Node n = null;
501         try {
502         DataObject dobj = DataObject.find(fo);
503         n = dobj.getNodeDelegate();
504         } catch (DataObjectNotFoundException ex) {
505         // cannot get the node for this, this shouldn't happen
506
// so just ignore
507
}
508         
509         return n;
510     }
511     
512     @Override JavaDoc
513     public Image JavaDoc getIcon(int type) {
514         Node n = getFolderNode();
515         Image JavaDoc i = super.getIcon(type);
516         if (n != null) {
517         i = n.getIcon(type);
518         }
519         return badgeImage(i);
520     }
521
522     @Override JavaDoc
523     public Image JavaDoc getOpenedIcon(int type) {
524         Node n = getFolderNode();
525         Image JavaDoc i = super.getOpenedIcon(type);
526         if (n != null) {
527         i = n.getOpenedIcon(type);
528         }
529         return badgeImage(i);
530     }
531     
532     private Image JavaDoc badgeImage(Image JavaDoc main) {
533         Image JavaDoc rv = main;
534         if (badge != null) {
535         Image JavaDoc badgeImage = Utilities.loadImage(badge);
536         rv = Utilities.mergeImages(main, badgeImage, 8, 8);
537         }
538         return rv;
539     }
540     
541     public void setBadge(String JavaDoc badge) {
542         this.badge = badge;
543     }
544     
545         public String JavaDoc getHtmlDisplayName() {
546             String JavaDoc name = getDisplayName();
547             // Need to escape any HTML meta-characters in the name.
548
name = name.replace("<", "&lt;").replace(">", "&gt;");
549             return applyHighlights(name);
550         }
551
552     ////////////////////////////////////////////////////////////////////////////
553
// Class members
554
////////////////////////////////////////////////////////////////////////////
555

556     private static final SystemAction[] ACTIONS=
557         new SystemAction[]
558         {
559                         SystemAction.get(PasteAction.class),
560                         null,
561             SystemAction.get(NewAction.class),
562         };
563
564         private static final SystemAction[] ACTIONS_READONLY =
565                 new SystemAction[] {
566         };
567
568     ////////////////////////////////////////////////////////////////////////////
569
// Instance variables
570
////////////////////////////////////////////////////////////////////////////
571

572     private SchemaUIContext context;
573     private SchemaComponentReference<? extends SchemaComponent> reference;
574         private Set JavaDoc<Component> referenceSet;
575         /** Ordered list of highlights applied to this node. */
576         private List JavaDoc<Highlight> highlights;
577     private Class JavaDoc<? extends SchemaComponent> childType;
578     private InstanceContent lookupContents;
579         private ComponentListener weakComponentListener;
580     private String JavaDoc badge;
581     
582 }
583
Popular Tags