KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > ui > nodes > elements > 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
20 package org.netbeans.modules.java.ui.nodes.elements;
21
22 import java.beans.*;
23 import java.io.IOException JavaDoc;
24 import java.lang.reflect.InvocationTargetException JavaDoc;
25 import java.lang.ref.WeakReference JavaDoc;
26 import java.lang.ref.Reference JavaDoc;
27 import java.lang.ref.SoftReference JavaDoc;
28 import java.util.*;
29
30 import org.openide.nodes.*;
31 import org.openide.util.*;
32 import org.openide.util.lookup.InstanceContent;
33 import org.openide.util.lookup.AbstractLookup;
34 import org.openide.util.actions.SystemAction;
35 import org.openide.ErrorManager;
36 import org.openide.text.PositionBounds;
37 import org.openide.cookies.OpenCookie;
38 import org.openide.cookies.SaveCookie;
39 import org.openide.loaders.DataObject;
40 import org.openide.src.ElementProperties;
41 import org.netbeans.modules.java.ui.nodes.editors.*;
42 import org.netbeans.modules.java.JavaEditor;
43 import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
44 import org.netbeans.jmi.javamodel.*;
45 import org.netbeans.jmi.javamodel.Type;
46 import org.netbeans.api.mdr.events.MDRChangeListener;
47 import org.netbeans.api.mdr.events.MDRChangeEvent;
48 import org.netbeans.api.mdr.events.AttributeEvent;
49 import org.netbeans.api.mdr.events.MDRChangeSource;
50
51 import javax.jmi.reflect.JmiException;
52 import javax.swing.*;
53
54 /** Superclass of nodes representing elements in the source hierarchy.
55 * <p>Element nodes generally:
56 * <ul>
57 * <li>Have an associated icon, according to {@link #resolveIconBase}.
58 * <li>Have a display name based on the element's properties, using {@link #elementFormat};
59 * changes to {@link org.openide.src.ElementFormat#dependsOnProperty relevant} element properties
60 * automatically affect the display name.
61 * <li>Have some node properties (displayable on the property sheet), according to
62 * the element's properties, and with suitable editors.
63 * <li>Permit renames and deletes, if a member element and writeable.
64 * <li>As permitted by the element, and a writable flag in the node,
65 * permit cut/copy/paste operations, as well as creation of new members.
66 * </ul>
67 *
68 * @author Petr Hamernik, Jan Pokorsky
69 */

70 public abstract class ElementNode extends AbstractNode implements IconStrings, ElementProperties2 {
71     
72     private static ElementFormat invalidFormat;
73
74     /** Default return value of getIconAffectingProperties method. */
75     private static final String JavaDoc[] ICON_AFFECTING_PROPERTIES = new String JavaDoc[] {
76                 PROP_MODIFIERS
77             };
78
79     /** Associated element. */
80     protected Element element;
81
82     /** Format for {@link java.beans.FeatureDescriptor#getDisplayName}. */
83     protected ElementFormat elementFormat = new ElementFormat (""); // NOI18N
84

85     /** Is this node read-only or are modifications permitted? */
86     protected boolean writeable;
87
88     private SystemAction preferredAction;
89     
90     private JMIElementListener wElementL;
91     
92     private final InstanceContent lkpContent;
93     
94     /** Create a new element node.
95     *
96     * @param element element to represent
97      * @param children child nodes
98      * @param writeable <code>true</code> if this node should allow modifications.
99     * These include writable properties, clipboard operations, deletions, etc.
100      */

101     public ElementNode(Element element, Children children, boolean writeable) {
102         this(element, children, writeable, new InstanceContent());
103     }
104     
105     private ElementNode(Element element, Children children, boolean writeable, InstanceContent ic) {
106         super(children, new AbstractLookup(ic));
107         this.element = element;
108         this.writeable = writeable;
109         this.lkpContent = ic;
110         setIconBase(resolveIconBase());
111         setDisplayName(getElementFormat().format(element));
112         setShortDescription(getHintElementFormat().format(element));
113         if (element instanceof MDRChangeSource) {
114             wElementL = (JMIElementListener) createJMIElementListener();
115             ((MDRChangeSource) element).addListener(wElementL);
116         }
117         displayFormat = null;
118         
119         ic.add(new OpenCookieImpl(this)); // OpenCookie
120
ic.add(element); // Element
121

122         Resource r = this.element.getResource();
123         DataObject dobj = JavaMetamodel.getManager().getDataObject(r);
124         if (dobj != null) {
125             ic.add(dobj); // DataObject
126
dobj.addPropertyChangeListener(new DOListener(this, dobj)); // SaveCookie
127
}
128     }
129     
130     public void destroy() throws IOException JavaDoc {
131         boolean fail = true;
132         try {
133             JavaMetamodel.getDefaultRepository().beginTrans(true);
134             try {
135                 element.refDelete();
136                 fail = false;
137             } finally {
138                 JavaMetamodel.getDefaultRepository().endTrans(fail);
139             }
140         } catch (JmiException e) {
141             IOException JavaDoc ioe = new IOException JavaDoc();
142             ioe.initCause(e);
143             throw ioe;
144         }
145         super.destroy();
146     }
147
148     /** Get the currently appropriate icon base.
149     * Subclasses should make this sensitive to the state of the element--for example,
150     * a private variable may have a different icon than a public one.
151     * The icon will be automatically changed whenever a
152     * {@link #getIconAffectingProperties relevant} change is made to the element.
153     * @return icon base
154     * @see org.openide.nodes.AbstractNode#setIconBase
155     */

156     abstract protected String JavaDoc resolveIconBase();
157
158     /** Get the names of all element properties which might affect the choice of icon.
159     * The default implementation just returns {@link #PROP_MODIFIERS}.
160     * @return the property names, from {@link org.openide.src.ElementProperties}
161     */

162     protected String JavaDoc[] getIconAffectingProperties() {
163         return ICON_AFFECTING_PROPERTIES;
164     }
165
166     /** Get a format for the element's display name.
167     * The display name will be automatically updated whenever a
168     * {@link ElementFormat#dependsOnProperty relevant}
169     * change is made to the element.
170     * @return the format
171     */

172     public final ElementFormat getElementFormat() {
173         return elementFormat;
174     }
175
176     /** Set the format for the display name.
177     * @param elementFormat the new format
178     * @throws java.lang.IllegalArgumentException if the format object is inappropriate
179     * for this type of Element. No assignment is made in such case.
180     */

181     public final void setElementFormat(ElementFormat elementFormat) {
182         setDisplayName(elementFormat.format(this.element));
183         this.elementFormat = elementFormat;
184     }
185     
186     /**
187      * subclasses implement this to supply persistent format
188      * @return element format
189      * @see SourceOptions
190      */

191     protected abstract ElementFormat getElementFormatProperty();
192
193     final void setElementFormat0(ElementFormat elementFormat) {
194         try {
195             setElementFormat(elementFormat);
196         } catch (IllegalArgumentException JavaDoc iae) {
197             setElementFormat(getInvalidFormat());
198         }
199     }
200     
201     static ElementFormat getInvalidFormat() {
202         if (invalidFormat != null)
203             return invalidFormat;
204         return invalidFormat = new ElementFormat(getString("FMT_InvalidFormat")); // NOI18N
205
}
206     
207     /** Get a format for creating this node's
208     * {@link java.beans.FeatureDescriptor#getShortDescription short description}.
209     */

210     abstract protected ElementFormat getHintElementFormat();
211
212     /**
213     * Rename is a job for refactoring, so this implementation does not allow to rename node.
214     *
215     * @return <code>false</code>
216     */

217     public boolean canRename() {
218         return false;
219     }
220
221     /** Test whether this node can be deleted.
222     * The default implementation assumes it can if this node is {@link #writeable}.
223     *
224     * @return <code>true</code> if this node can be renamed
225     */

226     public boolean canDestroy () {
227         return isWriteable();
228     }
229
230     /** Test whether this node can be copied.
231     * The default implementation returns <code>true</code>.
232     * @return <code>true</code> if it can
233     */

234     public boolean canCopy () {
235         return false;
236     }
237
238     /** Test whether this node can be cut.
239     * The default implementation assumes it can if this node is {@link #writeable}.
240     * @return <code>true</code> if it can
241     */

242     public boolean canCut () {
243         return false;
244 // return isWriteable();
245
}
246
247     /** Set all actions for this node.
248     * @param actions new list of actions
249     * @param preferred default action
250     */

251     public void setActions(SystemAction[] actions, SystemAction preferred) {
252         systemActions = actions;
253         this.preferredAction = preferred;
254     }
255
256     public Action getPreferredAction() {
257         Action a = preferredAction;
258         if (a == null) {
259             a = super.getPreferredAction();
260         }
261         return a;
262     }
263
264     /** Calls super.fireCookieChange. The reason why is redefined
265     * is only to allow the access from this package.
266     */

267     void superFireCookieChange() {
268         fireCookieChange();
269     }
270
271     /** Test for equality.
272     * @return <code>true</code> if the represented {@link org.openide.src.Element}s are equal
273     */

274     public boolean equals (Object JavaDoc o) {
275         return (o instanceof ElementNode) && (element.equals (((ElementNode)o).element));
276     }
277
278     /** Get a hash code.
279     * @return the hash code from the represented {@link org.openide.src.Element}
280     */

281     public int hashCode () {
282         return element.hashCode ();
283     }
284
285     boolean isWriteable() {
286         return writeable && SourceEditSupport.isWriteable(element);
287     }
288
289     void superSetName(String JavaDoc name) {
290         super.setName(name);
291     }
292
293     void superPropertyChange (String JavaDoc name, Object JavaDoc o, Object JavaDoc n) {
294         super.firePropertyChange (name, o, n);
295     }
296
297     void superShortDescriptionChange (String JavaDoc o, String JavaDoc n) {
298         super.fireShortDescriptionChange(o, n);
299     }
300
301     MDRChangeListener createJMIElementListener() {
302         JMIElementListener l = new JMIElementListener(this);
303         return l;
304     }
305     
306     /**
307      * subclasses can extend default behavior that cares about displayName, name, shortDescription, iconBase using methods
308      * {@link ElementFormat#dependsOnProperty}, {@link #getIconAffectingProperties} and mapAttributeName.
309      * The method is run inside the read-only JMI transaction.
310      * @param ae attribute change event
311      * @return descriptor of changes
312      */

313     protected ChangeDescriptor handleAttributeChange(AttributeEvent ae) {
314         final Object JavaDoc src = ae.getSource();
315         ChangeDescriptor cd = new ChangeDescriptor();
316         if (src != element || !((Element) src).isValid()) {
317             return cd;
318         }
319                 
320 // System.out.println("##ElementNode: " + ae.getAttributeName() + ", el: " + src.getClass() + ", lsnr: " + System.identityHashCode(this));
321

322         String JavaDoc attrName = ae.getAttributeName();
323         String JavaDoc propName = mapAttributeName(attrName);
324         if (propName == null) {
325             cd.displayName = getElementFormat().format(element);
326             cd.shortDescription = getHintElementFormat().format(element);
327             cd.iconBase = resolveIconBase();
328         } else {
329             // display name
330
if (getElementFormat().dependsOnProperty(propName)) {
331                 cd.displayName = getElementFormat().format(element);
332             }
333
334             // icon
335
String JavaDoc[] iconProps = getIconAffectingProperties();
336             for (int i = 0; i < iconProps.length; i++) {
337                 if (iconProps[i].equals(propName)) {
338                     cd.iconBase = resolveIconBase();
339                     break;
340                 }
341             }
342                     
343             if (propName.equals(ElementProperties.PROP_NAME)) {
344                 cd.name = ((NamedElement) element).getName();
345             }
346                     
347             // tool tip
348
if (getHintElementFormat().dependsOnProperty(propName)) {
349                 cd.shortDescription = getHintElementFormat().format(element);
350             }
351         }
352         return cd;
353     }
354     
355     /**
356      * subclasses can extend default behavior that cares about displayName, name, shortDescription, iconBase.
357      * The method is run inside AWT-event thread
358      * @param desc descriptor of changes
359      * @see #handleAttributeChange
360      */

361     protected void processChange(ChangeDescriptor desc) {
362         if (desc.displayName != null)
363             setDisplayName(desc.displayName);
364         if (desc.iconBase != null)
365             setIconBase(desc.iconBase);
366         if (desc.name != null)
367             superSetName(desc.name);
368         if (desc.shortDescription != null)
369             setShortDescription(desc.shortDescription);
370         if (desc.sheet != null) {
371             setSheet(desc.sheet);
372         }
373     }
374     
375     /**
376      * register property name to allow notification of its changes
377      * @return map of jmi attribute names to property names
378      */

379     protected abstract Map getAttributeNameMap();
380     
381     /** maps JMI attribute name to property name ({@link org.openide.src.ElementProperties}) */
382     final String JavaDoc mapAttributeName(String JavaDoc name) {
383         assert name != null;
384         String JavaDoc property = (String JavaDoc) getAttributeNameMap().get(name);
385         return (property == null)? name: property;
386     }
387     
388     static String JavaDoc getString(String JavaDoc key) {
389         return NbBundle.getMessage(ElementNode.class, key);
390     }
391         
392     private static void fireChangesInAWTThread(final ElementNode n, final ChangeDescriptor cd) {
393         Mutex.EVENT.writeAccess(new Runnable JavaDoc() {
394             public void run() {
395                 n.processChange(cd);
396             }
397         });
398     }
399     
400     private DataObject getDataObject() {
401         return (DataObject) this.getCookie(DataObject.class);
402     }
403     
404     // ================== Element listener =================================
405

406     static final class JMIElementListener extends WeakReference JavaDoc implements MDRChangeListener, Runnable JavaDoc {
407         
408         private final Element element;
409         
410         public JMIElementListener(ElementNode referent) {
411             super(referent, Utilities.activeReferenceQueue());
412             this.element = referent.element;
413         }
414
415         public void change(MDRChangeEvent e) {
416             final ElementNode n = (ElementNode) get();
417             if (n == null) return;
418             if (!e.isOfType(AttributeEvent.EVENTMASK_ATTRIBUTE)) return;
419             final AttributeEvent ae = (AttributeEvent) e;
420             
421             String JavaDoc attrName = ae.getAttributeName();
422             try {
423                 JavaMetamodel.getDefaultRepository().beginTrans(false);
424                 ChangeDescriptor cd;
425                 try {
426                     cd = n.handleAttributeChange(ae);
427                 } finally {
428                     JavaMetamodel.getDefaultRepository().endTrans(false);
429                 }
430                 
431                 assert cd != null;
432                 fireChangesInAWTThread(n, cd);
433                 fireRegisteredProperties(attrName);
434             } catch (JmiException ex) {
435                 ErrorManager.getDefault().notify(ErrorManager.WARNING, ex);
436             }
437         }
438
439         public void run() {
440             ((MDRChangeSource) this.element).removeListener(this);
441         }
442         
443         private void fireRegisteredProperties(String JavaDoc name) {
444             final ElementNode n = (ElementNode) get();
445             if (n == null) return;
446             if (name == null || (name = (String JavaDoc) n.getAttributeNameMap().get(name)) != null) {
447                 n.superPropertyChange(name, null, null);
448             }
449         }
450
451     }
452     
453     final static class ChangeDescriptor {
454         String JavaDoc displayName;
455         String JavaDoc name;
456         String JavaDoc iconBase;
457         String JavaDoc shortDescription;
458         /** recreate property sheet */
459         Sheet sheet;
460
461         public ChangeDescriptor(String JavaDoc displayName, String JavaDoc iconBase, String JavaDoc name, String JavaDoc shortDescription) {
462             this.displayName = displayName;
463             this.iconBase = iconBase;
464             this.name = name;
465             this.shortDescription = shortDescription;
466             this.sheet = null;
467         }
468
469         public ChangeDescriptor() {
470         }
471     }
472     
473     // ================== Property support for element nodes =================
474

475     /** Property support for element nodes properties.
476     */

477     static abstract class ElementProp extends PropertySupport {
478         
479         /** caches a reference to the property editor */
480         private Reference JavaDoc editor = null;
481         
482         /** Constructs a new ElementProp - support for properties of
483         * element hierarchy nodes.
484         *
485         * @param name The name of the property
486         * @param type The class type of the property
487         * @param canW The canWrite flag of the property
488         */

489         public ElementProp(String JavaDoc name, java.lang.Class JavaDoc type, boolean canW) {
490             super(name, type,
491                   getString("PROP_" + name), // NOI18N
492
getString("HINT_" + name), // NOI18N
493
true, canW);
494         }
495
496         /** Setter for the value. This implementation only tests
497         * if the setting is possible.
498         *
499         * @param val the value of the property
500         * @exception java.lang.IllegalAccessException when this ElementProp was constructed
501         * like read-only.
502         */

503         public void setValue (Object JavaDoc val) throws IllegalArgumentException JavaDoc,
504                 IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
505             if (!canWrite())
506                 throw new IllegalAccessException JavaDoc(getString("MSG_Cannot_Write")); // NOI18N
507
}
508             
509         public final PropertyEditor getPropertyEditor() {
510             PropertyEditor pe;
511             if (editor == null || (pe = (PropertyEditor) editor.get()) == null) {
512                 pe = createPropertyEditor();
513                 editor = new SoftReference JavaDoc(pe);
514             }
515             return pe;
516         }
517         
518         /**
519          * override just to provide own property editor.
520          * @return own property editor
521          */

522         protected PropertyEditor createPropertyEditor() {
523             return super.getPropertyEditor();
524         }
525
526     }
527     
528     /** creates a read-only node property for class member name.
529      * @param element class memeber
530      * @return the property
531      */

532     public static Node.Property createNameProperty(NamedElement element) {
533         Node.Property prop = new NameProperty(element);
534         return prop;
535     }
536     
537     /** creates a node property for constructor or method parameters.
538      * @param element element owning parameters
539      * @param canW <code>false</code> to force property to be read-only
540      * @return the property
541      */

542     public static Node.Property createParametersProperty(CallableFeature element, boolean canW) {
543         Node.Property prop = new ParametersProperty(element, canW);
544         setModel(element, prop);
545         return prop;
546     }
547     
548     /** creates a node property for constructor or method exceptions.
549      * @param element element owning exceptions
550      * @param canW <code>false</code> to force property to be read-only
551      * @return the property
552      */

553     public static Node.Property createExceptionsProperty(CallableFeature element, boolean canW) {
554         Node.Property prop = new ExceptionsProperty(element, canW);
555         setModel(element, prop);
556         return prop;
557     }
558     
559     /** creates a node property for field type or method return type.
560      * @param name property name
561      * @param element element
562      * @param canW <code>false</code> to force property to be read-only
563      * @return the property
564      */

565     public static Node.Property createTypeProperty(String JavaDoc name, TypedElement element, boolean canW) {
566         Node.Property prop = new TypeProperty(name, element, canW);
567         setModel(element, prop);
568         return prop;
569     }
570     
571     /** creates a node property for generic type type.
572      * @param name property name
573      * @param element element
574      * @param canW <code>false</code> to force property to be read-only
575      * @return the property
576      */

577     public static Node.Property createTypeParametersProperty(String JavaDoc name, GenericElement element, boolean canW) {
578         Node.Property prop = new TypeParametersProperty(name, element, canW);
579         setModel(element, prop);
580         return prop;
581     }
582     
583     /** creates a node property for element modifiers.
584      * @param element element owning modifiers
585      * @param canW <code>false</code> to force property to be read-only
586      * @return the property
587      */

588     public static Node.Property createModifiersProperty(ClassMember element, boolean canW) {
589         int mask;
590         try {
591             mask = SourceEditSupport.getModifiersMask(element);
592         } catch (JmiException e) {
593             ErrorManager.getDefault().notify(ErrorManager.WARNING, e);
594             mask = 0xFFFF;
595         }
596         return createModifiersProperty(element, canW, mask);
597     }
598     
599     /** creates a node property for element modifiers.
600      * @param element element owning modifiers
601      * @param canW <code>false</code> to force property to be read-only
602      * @param mask mask of modifiers to change
603      * @return the property
604      */

605     public static Node.Property createModifiersProperty(ClassMember element, boolean canW, int mask) {
606         Node.Property prop = new ModifiersProperty(element, canW, mask);
607         setModel(element, prop);
608         return prop;
609     }
610     
611     /** @see #getModel */
612     public static void setModel(org.netbeans.jmi.javamodel.Element el, FeatureDescriptor fd) {
613         JavaModelPackage model = JavaMetamodel.getManager().getJavaExtent(el);
614         fd.setValue("JavaModelPackage", model); // NOI18N
615
}
616     
617     /** extracts model from descriptor or provides default one if custom not exists*/
618     public static JavaModelPackage getModel(FeatureDescriptor fd) {
619         JavaModelPackage model = (JavaModelPackage) fd.getValue("JavaModelPackage"); // NOI18N
620
if (model == null) {
621             model = JavaMetamodel.getManager().getDefaultExtent();
622             ErrorManager.getDefault().notify(
623                     ErrorManager.INFORMATIONAL,
624                     new IllegalStateException JavaDoc("missing JavaModelPackage")); // NOI18N
625
}
626         return model;
627     }
628
629     /** Create a node property for the modifiers of the element.
630     * This property will typically display with a custom editor
631     * allowing individual modifiers to be examined.
632     * @param canW if <code>false</code>, the property will be read-only irrespective of
633     * the underlying element's ability to change the modifiers
634     * @return the property
635     */

636     protected Node.Property createModifiersProperty(boolean canW) {
637         Node.Property p = createModifiersProperty((ClassMember) element, canW);
638         p.setValue("changeImmediate" /* PropertyEnv.PROP_CHANGE_IMMEDIATE */,Boolean.FALSE); // NOI18N
639
return p;
640     }
641
642     /** Options for the display name format. */
643     protected static SourceOptions getSourceOptions() {
644         return SourceOptions.getInstance();
645     }
646
647     private final static class ParametersProperty extends ElementProp {
648         
649         private final CallableFeature element;
650         
651         private ParametersProperty(CallableFeature element, boolean canW) {
652             super(PROP_PARAMETERS, Parameter[].class, canW);
653             this.element = element;
654         }
655
656         public Object JavaDoc getValue() {
657             List l = element.getParameters();
658             return (Parameter[]) l.toArray(new Parameter[l.size()]);
659         }
660
661         public PropertyEditor createPropertyEditor() {
662             return new MethodParameterArrayEditor(canWrite());
663         }
664
665         public void setValue(final Object JavaDoc val) throws IllegalArgumentException JavaDoc,
666                        IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
667             
668             super.setValue(val);
669             if (!(val instanceof Parameter[]))
670                 throw new IllegalArgumentException JavaDoc();
671             
672             boolean fail = true;
673             try {
674                 JavaMetamodel.getDefaultRepository().beginTrans(true);
675                 try {
676                     List l = element.getParameters();
677                     l.clear();
678                     l.addAll(Arrays.asList((Parameter[]) val));
679                     fail = false;
680                 } finally {
681                     JavaMetamodel.getDefaultRepository().endTrans(fail);
682                 }
683             } catch (JmiException e) {
684                 IllegalArgumentException JavaDoc iae = new IllegalArgumentException JavaDoc();
685                 iae.initCause(e);
686                 throw iae;
687             }
688         }
689         
690     }
691
692     private final static class ExceptionsProperty extends ElementProp {
693         
694         private final CallableFeature element;
695         
696         public ExceptionsProperty(CallableFeature element, boolean canW) {
697             super(PROP_EXCEPTIONS, MultipartId[].class, canW);
698             this.element = element;
699         }
700
701         protected PropertyEditor createPropertyEditor() {
702             return new IdentifierArrayEditor();
703         }
704
705         public Object JavaDoc getValue () {
706             Object JavaDoc ret = null;
707             try {
708                 JavaMetamodel.getDefaultRepository().beginTrans(false);
709                 try {
710                     if (element.isValid()) {
711                         List l = element.getExceptionNames();
712                         ret = l.toArray(new MultipartId[l.size()]);
713                     }
714                 } finally {
715                     JavaMetamodel.getDefaultRepository().endTrans();
716                 }
717             } catch (JmiException e) {
718                 ErrorManager.getDefault().notify(e);
719             }
720             return ret;
721         }
722
723         public void setValue(final Object JavaDoc val) throws IllegalArgumentException JavaDoc,
724                 IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
725             super.setValue(val);
726             if (!(val instanceof MultipartId[]))
727                 throw new IllegalArgumentException JavaDoc();
728                        
729             boolean fail = true;
730             try {
731                 JavaMetamodel.getDefaultRepository().beginTrans(true);
732                 try {
733                     List exs = element.getExceptionNames();
734                     exs.clear();
735                     exs.addAll(Arrays.asList((MultipartId[]) val));
736                     fail = false;
737                 } finally {
738                     JavaMetamodel.getDefaultRepository().endTrans(fail);
739                 }
740             } catch (JmiException e) {
741                 IllegalArgumentException JavaDoc iae = new IllegalArgumentException JavaDoc();
742                 iae.initCause(e);
743                 throw iae;
744             }
745         }
746     }
747
748     private final static class TypeProperty extends ElementProp {
749         
750         private final TypedElement element;
751         
752         public TypeProperty(String JavaDoc propName, TypedElement element, boolean canW) {
753             super(propName, Type.class, canW);
754             this.element = element;
755         }
756
757         public PropertyEditor createPropertyEditor() {
758             return new TypeEditor();
759         }
760
761         public Object JavaDoc getValue () {
762             return element.getType();
763         }
764
765         public void setValue(Object JavaDoc val) throws IllegalArgumentException JavaDoc,
766                IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
767                 
768             super.setValue(val);
769             if (!(val instanceof Type))
770                throw new IllegalArgumentException JavaDoc();
771                 
772             Type type = (Type) val;
773                 
774             boolean fail = true;
775             try {
776                 JavaMetamodel.getDefaultRepository().beginTrans(true);
777                 try {
778                     element.setType(type);
779                     fail = false;
780                 } finally {
781                     JavaMetamodel.getDefaultRepository().endTrans(fail);
782                 }
783             } catch (JmiException e) {
784                 IllegalArgumentException JavaDoc iae = new IllegalArgumentException JavaDoc();
785                 iae.initCause(e);
786                 ErrorManager.getDefault().annotate(iae, ErrorManager.USER, null,
787                         NbBundle.getMessage(FieldNode.class, "MSG_InvalidTypeDecl"), null, null); // NOI18N
788
throw iae;
789             }
790         }
791     }
792     
793     private final static class TypeParametersProperty extends ElementProp {
794         
795         private final GenericElement element;
796         
797         public TypeParametersProperty(String JavaDoc name, GenericElement element, boolean canW) {
798             super(name, TypeParameter[].class, false);
799             this.element = element;
800         }
801
802         protected PropertyEditor createPropertyEditor() {
803             return new TypeParameterArrayEditor();
804         }
805
806         public Object JavaDoc getValue() throws IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
807             return element.getTypeParameters().toArray(new TypeParameter[0]);
808         }
809
810         public void setValue(Object JavaDoc val) throws IllegalArgumentException JavaDoc,
811                 IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
812             throw new InvocationTargetException JavaDoc(new UnsupportedOperationException JavaDoc());
813         }
814     }
815
816     private final static class ModifiersProperty extends ElementProp {
817         
818         private final ClassMember element;
819         private final int mask;
820         
821         private ModifiersProperty(ClassMember element, boolean canW, int mask) {
822             super(PROP_MODIFIERS, Integer JavaDoc.class, canW);
823             this.element = element;
824             this.mask = mask;
825         }
826
827         /** Gets the value */
828         public Object JavaDoc getValue () {
829             return new Integer JavaDoc(element.getModifiers());
830         }
831
832         /** Sets the value */
833         public void setValue(final Object JavaDoc val) throws IllegalArgumentException JavaDoc,
834                 IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
835             super.setValue(val);
836
837             if (!(val instanceof Integer JavaDoc))
838                 throw new IllegalArgumentException JavaDoc();
839             
840             int m = ((Integer JavaDoc) val).intValue();
841             int oldVal = element.getModifiers();
842             int newVal = (m & mask) + (oldVal & ~mask);
843             element.setModifiers(newVal);
844         }
845
846         /** Define property editor for this property. */
847         public PropertyEditor createPropertyEditor () {
848             // XXX see http://www.netbeans.org/issues/show_bug.cgi?id=42155
849
return new ModifierEditor(mask);
850         }
851     }
852
853     private static final class NameProperty extends ElementProp {
854         
855         private final NamedElement element;
856         
857         public NameProperty(NamedElement element) {
858             super(ElementProperties.PROP_NAME, String JavaDoc.class, false);
859             this.element = element;
860         }
861
862         public Object JavaDoc getValue () {
863             return element.getName();
864         }
865     }
866     
867     private static final class OpenCookieImpl implements OpenCookie {
868
869         private final ElementNode node;
870         
871         public OpenCookieImpl(ElementNode node) {
872             this.node = node;
873         }
874
875         public void open() {
876             try {
877                 DataObject d = node.getDataObject();
878                 PositionBounds bounds = JavaMetamodel.getManager().getElementPosition(node.element);
879                 if (bounds == null)
880                     return;
881                 ((JavaEditor) d.getCookie(JavaEditor.class)).openAt(bounds.getBegin());
882             } catch (javax.jmi.reflect.InvalidObjectException e) {
883             }
884         }
885         
886     }
887     
888     private static final class DOListener extends WeakReference JavaDoc implements PropertyChangeListener, Runnable JavaDoc {
889         
890         private DataObject dobj;
891         
892         public DOListener(ElementNode referent, DataObject dobj) {
893             super(referent, Utilities.activeReferenceQueue());
894             this.dobj = dobj;
895             updateCookies(dobj, referent);
896         }
897         
898         public void initialize() {
899         }
900
901         public void propertyChange(PropertyChangeEvent evt) {
902             String JavaDoc pname = evt.getPropertyName();
903             ElementNode en = (ElementNode) get();
904             if (en == null) {
905                 return;
906             }
907             if (pname == null || DataObject.PROP_COOKIE.equals(pname)) {
908                 updateCookies(dobj, en);
909             }
910         }
911         
912         private static void updateCookies(DataObject dobj, ElementNode en) {
913             SaveCookie dsc = (SaveCookie) dobj.getCookie(SaveCookie.class);
914             SaveCookie nsc = (SaveCookie) en.getLookup().lookup(SaveCookie.class);
915             if (dsc != nsc) {
916                 if (nsc != null) {
917                     en.lkpContent.remove(nsc);
918                 }
919                 if (dsc != null) {
920                     en.lkpContent.add(dsc);
921                 }
922             }
923         }
924
925         public void run() {
926             dobj.removePropertyChangeListener(this);
927         }
928
929     }
930 }
931
Popular Tags