KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > settings > convertors > SerialDataNode


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.settings.convertors;
21
22 import java.awt.Graphics JavaDoc;
23 import java.awt.GraphicsEnvironment JavaDoc;
24 import java.awt.Image JavaDoc;
25 import java.awt.Transparency JavaDoc;
26 import java.awt.image.BufferedImage JavaDoc;
27 import java.awt.image.ColorModel JavaDoc;
28 import java.beans.BeanDescriptor JavaDoc;
29 import java.beans.BeanInfo JavaDoc;
30 import java.beans.EventSetDescriptor JavaDoc;
31 import java.beans.IntrospectionException JavaDoc;
32 import java.beans.PropertyChangeEvent JavaDoc;
33 import java.beans.PropertyChangeListener JavaDoc;
34 import java.beans.PropertyEditor JavaDoc;
35 import java.beans.beancontext.BeanContext JavaDoc;
36 import java.beans.beancontext.BeanContextProxy JavaDoc;
37 import java.beans.beancontext.BeanContextMembershipEvent JavaDoc;
38 import java.beans.beancontext.BeanContextMembershipListener JavaDoc;
39 import java.beans.beancontext.BeanContextSupport JavaDoc;
40 import java.lang.reflect.InvocationTargetException JavaDoc;
41 import java.lang.reflect.Method JavaDoc;
42 import java.io.IOException JavaDoc;
43 import java.lang.ref.Reference JavaDoc;
44 import java.lang.ref.WeakReference JavaDoc;
45 import java.lang.reflect.Modifier JavaDoc;
46 import java.util.Arrays JavaDoc;
47 import java.util.List JavaDoc;
48 import java.util.ArrayList JavaDoc;
49 import java.util.Collection JavaDoc;
50 import java.util.Collections JavaDoc;
51 import java.util.Enumeration JavaDoc;
52 import java.util.logging.Level JavaDoc;
53 import java.util.logging.Logger JavaDoc;
54 import javax.swing.Action JavaDoc;
55 import javax.swing.Icon JavaDoc;
56 import javax.swing.ImageIcon JavaDoc;
57 import org.openide.actions.ToolsAction;
58 import org.openide.cookies.InstanceCookie;
59 import org.openide.filesystems.FileStateInvalidException;
60 import org.openide.filesystems.FileSystem;
61 import org.openide.loaders.DataNode;
62 import org.openide.loaders.DataObject;
63 import org.openide.loaders.InstanceDataObject;
64 import org.openide.nodes.BeanChildren;
65 import org.openide.nodes.BeanNode;
66 import org.openide.nodes.Children;
67 import org.openide.nodes.Node;
68 import org.openide.nodes.Node.Property;
69 import org.openide.nodes.Sheet;
70 import org.openide.util.Exceptions;
71 import org.openide.util.NbBundle;
72 import org.openide.util.SharedClassObject;
73 import org.openide.util.Utilities;
74 import org.openide.util.WeakListeners;
75 import org.openide.util.actions.SystemAction;
76
77 /** Node to represent a .settings file.
78  * @author Jan Pokorsky
79  */

80 public final class SerialDataNode extends DataNode {
81     /** listener for properties */
82     private PropL propertyChangeListener = null;
83     /** bean info is not used only if the file specifies
84      * <attr name="beaninfo" booleanvalue="false" />
85      */

86     private boolean noBeanInfo = false;
87     private final SerialDataConvertor convertor;
88     private WeakReference JavaDoc<Object JavaDoc> settingInstance = new WeakReference JavaDoc<Object JavaDoc>(null);
89     private boolean isNameChanged = false;
90     /** true after passing the constructors code
91      * @see #getName
92      */

93     private final Boolean JavaDoc isAfterNodeConstruction;
94
95     static final String JavaDoc ATTR_DISPLAY_NAME = "SerialDataNode_DisplayName";//NOI18N
96

97     /** used by general setting objects */
98     public SerialDataNode(DataObject dobj) {
99         this(null, dobj, Boolean.FALSE.equals(dobj.
100             getPrimaryFile().getAttribute("beaninfo"))); // NOI18N
101
}
102     
103     /** used by old serialdata settings */
104     public SerialDataNode(SerialDataConvertor conv) {
105         this (conv, conv.getDataObject(), Boolean.FALSE.equals(conv.getDataObject().
106             getPrimaryFile().getAttribute("beaninfo"))); // NOI18N
107
}
108      
109     /** @param obj the object to use
110      * @param noBeanInfo info to use
111      */

112     private SerialDataNode(SerialDataConvertor conv, DataObject dobj, boolean noBeanInfo) {
113         super (dobj, getChildren(dobj, noBeanInfo));
114         
115         this.convertor = conv;
116         this.noBeanInfo = noBeanInfo;
117         isAfterNodeConstruction = Boolean.TRUE;
118     }
119     
120     private static Children getChildren(DataObject dobj, boolean noBeanInfo) {
121         if (noBeanInfo) {
122             return Children.LEAF;
123         }
124         InstanceCookie inst = (InstanceCookie)dobj.getCookie(InstanceCookie.class);
125         if (inst == null) return Children.LEAF;
126         try {
127             Class JavaDoc clazz = inst.instanceClass();
128             if (BeanContext JavaDoc.class.isAssignableFrom(clazz) ||
129                 BeanContextProxy JavaDoc.class.isAssignableFrom(clazz)) {
130                 return new InstanceChildren ();
131             } else {
132                 return Children.LEAF;
133             }
134         } catch (Exception JavaDoc ex) {
135             return Children.LEAF;
136         }
137     }
138     
139     /** Getter for instance data object.
140      * @return instance data object
141      */

142     private InstanceDataObject i () {
143         return (InstanceDataObject)getDataObject ();
144     }
145     
146     private InstanceCookie.Of ic () {
147         return (InstanceCookie.Of) getDataObject().getCookie(InstanceCookie.Of.class);
148     }
149     
150     private SerialDataConvertor getConvertor() {
151         return convertor;
152     }
153     
154     /** get cached setting object; can be null */
155     private Object JavaDoc getSettingInstance() {
156         return settingInstance.get();
157     }
158     /** cache setting object */
159     private void setSettingsInstance(Object JavaDoc obj) {
160         if (obj == settingInstance.get()) return;
161         isNameChanged = false;
162         settingInstance = new WeakReference JavaDoc<Object JavaDoc>(obj);
163     }
164     
165     /** Find an icon for this node (in the closed state).
166     * @param type constant from {@link java.beans.BeanInfo}
167     * @return icon to use to represent the node
168     */

169     public Image JavaDoc getIcon (int type) {
170         if (noBeanInfo) return super.getIcon(type);
171         Image JavaDoc img = null;
172         try {
173             DataObject dobj = getDataObject();
174             img = dobj.getPrimaryFile().getFileSystem().getStatus().
175                 annotateIcon (img, type, dobj.files ());
176         } catch (FileStateInvalidException e) {
177             // no fs, do nothing
178
}
179         
180         if (img == null) img = initIcon(type);
181         if (img == null) img = super.getIcon(type);
182         return img;
183     }
184
185     /** Find an icon for this node (in the open state).
186     * This icon is used when the node may have children and is expanded.
187     *
188     * @param type constant from {@link java.beans.BeanInfo}
189     * @return icon to use to represent the node when open
190     */

191     public Image JavaDoc getOpenedIcon (int type) {
192         return getIcon (type);
193     }
194     
195     public String JavaDoc getHtmlDisplayName() {
196         return null;
197     }
198     
199     /** here should be decided if some change was fired by the setting object
200      * or the node should notify convertor about the change. This is just
201      * workaround ensuring backward compatibility for archaic settings from
202      * the "store everything at shutdown" ages and newly writtten setting should
203      * not rely on it.
204      */

205     private void resolvePropertyChange() {
206         if (propertyChangeListener != null &&
207             propertyChangeListener.getChangeAndReset()) return;
208         
209         if (notifyResolvePropertyChange && propertyChangeListener != null ) {
210             notifyResolvePropertyChange = false;
211             XMLSettingsSupport.err.warning(
212                 "Warning: no PropertyChangeEvent fired from settings stored in " +// NOI18N
213
getDataObject());
214         }
215         SerialDataConvertor c = getConvertor();
216         if (c != null) {
217             c.handleUnfiredChange();
218         }
219     }
220     
221     private boolean notifyResolvePropertyChange = true;
222         
223
224     /** try to register PropertyChangeListener to instance to fire its changes.
225      * @param bean */

226     private void initPList (Object JavaDoc bean, BeanInfo JavaDoc bInfo, BeanNode.Descriptor descr) {
227         EventSetDescriptor JavaDoc[] descs = bInfo.getEventSetDescriptors();
228         try {
229             Method JavaDoc setter = null;
230             for (int i = 0; descs != null && i < descs.length; i++) {
231                 setter = descs[i].getAddListenerMethod();
232                 if (setter != null && setter.getName().equals("addPropertyChangeListener")) { // NOI18N
233
propertyChangeListener = new PropL(createSupportedPropertyNames(descr));
234                     setter.invoke(bean, new Object JavaDoc[] {WeakListeners.propertyChange(propertyChangeListener, bean)});
235                     setSettingsInstance(bean);
236                 }
237             }
238         } catch (Exception JavaDoc ex) {
239             // ignore
240
}
241     }
242
243     private Collection JavaDoc<String JavaDoc> createSupportedPropertyNames(BeanNode.Descriptor descr) {
244         ArrayList JavaDoc<String JavaDoc> supportedPropertyNames = new ArrayList JavaDoc<String JavaDoc>();
245         if (descr.property != null) {
246             for (int i = 0; i < descr.property.length; i++) {
247                 Node.Property property = descr.property[i];
248                 supportedPropertyNames.add(property.getName());
249             }
250         }
251
252         if (descr.expert != null) {
253             for (int i = 0; i < descr.expert.length; i++) {
254                 Property property = descr.property[i];
255                 supportedPropertyNames.add(property.getName());
256             }
257         }
258
259         return supportedPropertyNames;
260     }
261
262     private Image JavaDoc initIcon (int type) {
263         Image JavaDoc beanInfoIcon = null;
264         try {
265             InstanceCookie ic = ic();
266             if (ic == null) return null;
267             Class JavaDoc<?> clazz = ic.instanceClass();
268             //Fixed bug #5610
269
//Class javax.swing.JToolBar$Separator does not have icon
270
//we will use temporarily icon from javax.swing.JSeparator
271
//New icon is requested.
272

273             String JavaDoc className = clazz.getName ();
274             BeanInfo JavaDoc bi;
275             if (
276                 className.equals ("javax.swing.JSeparator") || // NOI18N
277
className.equals ("javax.swing.JToolBar$Separator") // NOI18N
278
) {
279                 Class JavaDoc clazzTmp = Class.forName ("javax.swing.JSeparator"); // NOI18N
280
bi = Utilities.getBeanInfo (clazzTmp);
281             } else {
282                 bi = Utilities.getBeanInfo (clazz);
283             }
284
285             if (bi != null) {
286                 beanInfoIcon = bi.getIcon (type);
287                 if (beanInfoIcon != null) {
288                     beanInfoIcon = toBufferedImage(beanInfoIcon, true);
289                 }
290             }
291             // Also specially handle SystemAction's.
292
if (SystemAction.class.isAssignableFrom (clazz)) {
293                 SystemAction action = SystemAction.get (clazz.asSubclass(SystemAction.class));
294                 if (beanInfoIcon == null) {
295                     Icon JavaDoc icon = action.getIcon ();
296                     if (icon != null) {
297                         beanInfoIcon = Utilities.icon2Image(icon);
298                     }
299                 }
300             }
301         } catch (Exception JavaDoc e) {
302             // Problem ==>> use default icon
303
Logger.getLogger(SerialDataNode.class.getName()).log(Level.WARNING, null, e);
304         }
305
306         return beanInfoIcon;
307     }
308
309     /** Try to get display name of the bean.
310      */

311     private String JavaDoc getNameForBean() {
312         try {
313             InstanceCookie ic = ic();
314             if (ic == null) {
315                 // it must be unrecognized setting
316
return NbBundle.getMessage(SerialDataNode.class,
317                     "LBL_BrokenSettings"); //NOI18N
318
}
319             Class JavaDoc<?> clazz = ic.instanceClass();
320             Method JavaDoc nameGetter;
321             Class JavaDoc[] param = new Class JavaDoc [0];
322             try {
323                 nameGetter = clazz.getMethod ("getName", param); // NOI18N
324
if (nameGetter.getReturnType () != String JavaDoc.class) throw new NoSuchMethodException JavaDoc ();
325             } catch (NoSuchMethodException JavaDoc e) {
326                 try {
327                     nameGetter = clazz.getMethod ("getDisplayName", param); // NOI18N
328
if (nameGetter.getReturnType () != String JavaDoc.class) throw new NoSuchMethodException JavaDoc ();
329                 } catch (NoSuchMethodException JavaDoc ee) {
330                     return null;
331                 }
332             }
333             Object JavaDoc bean = ic.instanceCreate();
334             setSettingsInstance(bean);
335             return (String JavaDoc) nameGetter.invoke (bean);
336         } catch (Exception JavaDoc ex) {
337             // ignore
338
return null;
339         }
340     }
341     
342     /** try to find setter setName/setDisplayName, if none declared return null */
343     private Method JavaDoc getDeclaredSetter() {
344         Method JavaDoc nameSetter = null;
345         try {
346             InstanceCookie ic = ic();
347             if (ic == null) return null;
348             Class JavaDoc<?> clazz = ic.instanceClass();
349             Class JavaDoc[] param = new Class JavaDoc[] {String JavaDoc.class};
350             // find the setter for the name
351
try {
352                 nameSetter = clazz.getMethod ("setName", param); // NOI18N
353
} catch (NoSuchMethodException JavaDoc e) {
354                 nameSetter = clazz.getMethod ("setDisplayName", param); // NOI18N
355
}
356             if (!Modifier.isPublic(nameSetter.getModifiers())) {
357                 nameSetter = null;
358             }
359         } catch (Exception JavaDoc ex) {
360             // ignore
361
}
362         return nameSetter;
363     }
364     
365     public void setName(String JavaDoc name) {
366         String JavaDoc old = getName();
367         if (old != null && old.equals(name)) return;
368         InstanceCookie ic = ic();
369         if (ic == null) {
370             return;
371         }
372         
373         Method JavaDoc nameSetter = getDeclaredSetter();
374         if (nameSetter != null) {
375             try {
376                 Object JavaDoc bean = ic.instanceCreate();
377                 setSettingsInstance(bean);
378                 nameSetter.invoke(bean, new Object JavaDoc[] {name});
379                 isNameChanged = true;
380                 getDataObject().getPrimaryFile().setAttribute(ATTR_DISPLAY_NAME, name);
381                 resolvePropertyChange();
382                 return;
383             } catch (IOException JavaDoc ex) {
384                 Exceptions.printStackTrace(ex);
385             } catch (ClassNotFoundException JavaDoc ex) {
386                 Exceptions.printStackTrace(ex);
387             } catch (IllegalAccessException JavaDoc ex) {
388                 Exceptions.attachLocalizedMessage(ex, getDataObject().toString());
389                 Exceptions.printStackTrace(ex);
390             } catch (IllegalArgumentException JavaDoc ex) {
391                 Exceptions.attachLocalizedMessage(ex, getDataObject().toString());
392                 Exceptions.printStackTrace(ex);
393             } catch (InvocationTargetException JavaDoc ex) {
394                 Exceptions.attachLocalizedMessage(ex, getDataObject().toString());
395                 Exceptions.printStackTrace(ex);
396             }
397         }
398     }
399     
400     public String JavaDoc getName() {
401         // the fix of #17247; DataNode performs some weird initialization of
402
// the name in its constructor so SDN delegates to lazy getDisplayName
403
// impl when it is really necessary to prevent useless creating of
404
// the setting object.
405
if (isAfterNodeConstruction == null) return super.getName();
406         return getDisplayName();
407     }
408     
409     /** Get the display name for the node.
410      * A filesystem may {@link org.openide.filesystems.FileSystem#getStatus specially alter} this.
411      * @return the desired name
412     */

413     public String JavaDoc getDisplayName () {
414         String JavaDoc name;
415         Object JavaDoc setting = getSettingInstance();
416         if (setting != null && isNameChanged) {
417             // due to async storing ask a bean for name first
418
name = getNameForBean();
419             if (name != null) {
420                 return name;
421             }
422         }
423         
424         
425         name = (String JavaDoc) getDataObject().getPrimaryFile().
426             getAttribute(SerialDataNode.ATTR_DISPLAY_NAME);
427         if (name == null) {
428             try {
429                 String JavaDoc def = "\b"; // NOI18N
430
FileSystem.Status fsStatus = getDataObject().getPrimaryFile().
431                     getFileSystem().getStatus();
432                 name = fsStatus.annotateName(def, getDataObject().files());
433                 if (name.indexOf(def) < 0) {
434                     return name;
435                 } else {
436                     name = getNameForBean();
437                     if (name != null) {
438                         name = fsStatus.annotateName (name, getDataObject().files());
439                     } else {
440                         name = fsStatus.annotateName (getDataObject().getName(),
441                             getDataObject().files());
442                     }
443                 }
444             } catch (FileStateInvalidException e) {
445                 // no fs, do nothing
446
}
447         }
448         return name;
449     }
450     
451     protected Sheet createSheet () {
452         Sheet retVal = new Sheet();
453         InstanceCookie ic = ic();
454
455         if (ic != null) {
456             
457             try {
458                 Class JavaDoc instanceClass = ic.instanceClass ();
459                 Object JavaDoc bean = ic.instanceCreate ();
460                 BeanInfo JavaDoc beanInfo = Utilities.getBeanInfo (instanceClass);
461                 
462                 BeanNode.Descriptor descr = BeanNode.computeProperties (bean, beanInfo);
463                 BeanDescriptor JavaDoc bd = beanInfo.getBeanDescriptor();
464                 
465                 initPList(bean, beanInfo, descr);
466                 
467                 retVal.put (createPropertiesSet(descr, bd));
468
469                 if (descr.expert != null && descr.expert.length != 0) {
470                     retVal.put (createExpertSet(descr, bd));
471                 }
472                 
473             } catch (ClassNotFoundException JavaDoc ex) {
474                 Logger.getLogger(SerialDataNode.class.getName()).log(Level.WARNING, null, ex);
475             } catch (IOException JavaDoc ex) {
476                 Logger.getLogger(SerialDataNode.class.getName()).log(Level.WARNING, null, ex);
477             } catch (IntrospectionException JavaDoc ex) {
478                 Logger.getLogger(SerialDataNode.class.getName()).log(Level.WARNING, null, ex);
479             }
480         }
481
482         return retVal;
483     }
484
485
486     private Sheet.Set createExpertSet(BeanNode.Descriptor descr, BeanDescriptor JavaDoc bd) {
487         Sheet.Set p = Sheet.createExpertSet();
488         convertProps (p, descr.expert, this);
489         if (bd != null) {
490             Object JavaDoc helpID = bd.getValue("expertHelpID"); // NOI18N
491
if (helpID != null && helpID instanceof String JavaDoc) {
492                 p.setValue("helpID", helpID); // NOI18N
493
}
494         }
495         return p;
496     }
497
498     private Sheet.Set createPropertiesSet(BeanNode.Descriptor descr, BeanDescriptor JavaDoc bd) {
499         Sheet.Set props;
500         props = Sheet.createPropertiesSet();
501         if (descr.property != null) {
502             convertProps (props, descr.property, this);
503         }
504         if (bd != null) {
505             // #29550: help from the beaninfo on property tabs
506
Object JavaDoc helpID = bd.getValue("propertiesHelpID"); // NOI18N
507
if (helpID != null && helpID instanceof String JavaDoc) {
508                 props.setValue("helpID", helpID); // NOI18N
509
}
510         }
511         return props;
512     }
513
514
515     /** Method that converts properties of an object.
516      * @param set set to add properties to
517      * @param arr array of Node.Property and Node.IndexedProperty
518      * @param ido provides task to invoke when a property changes
519      */

520     private static final void convertProps (
521         Sheet.Set set, Node.Property<?>[] arr, SerialDataNode ido
522     ) {
523         for (int i = 0; i < arr.length; i++) {
524             if (arr[i] instanceof Node.IndexedProperty) {
525                 set.put (new I ((Node.IndexedProperty)arr[i], ido));
526             } else {
527                 set.put (new P (arr[i], ido));
528             }
529         }
530     }
531     
532     /** The method creates a BufferedImage which represents the same Image as the
533      * parameter but consumes less memory.
534      */

535     private static final Image JavaDoc toBufferedImage(Image JavaDoc img, boolean load) {
536         // load the image
537
if (load) {
538             new ImageIcon JavaDoc(img);
539         }
540         
541         BufferedImage JavaDoc rep = createBufferedImage();
542         Graphics JavaDoc g = rep.createGraphics();
543         g.drawImage(img, 0, 0, null);
544         g.dispose();
545         img.flush();
546         return rep;
547     }
548
549     /** Creates BufferedImage 16x16 and Transparency.BITMASK */
550     private static final BufferedImage JavaDoc createBufferedImage() {
551         ColorModel JavaDoc model = GraphicsEnvironment.getLocalGraphicsEnvironment().
552                                           getDefaultScreenDevice().getDefaultConfiguration().getColorModel(Transparency.BITMASK);
553         BufferedImage JavaDoc buffImage = new BufferedImage JavaDoc(model,
554                 model.createCompatibleWritableRaster(16, 16), model.isAlphaPremultiplied(), null);
555         return buffImage;
556     }
557     
558     /** Indicate whether the node may be renamed.
559      * @return tests {@link DataObject#isRenameAllowed}
560      */

561     public boolean canRename() {
562         return getDeclaredSetter() != null;
563     }
564     
565     /** Indicate whether the node may be destroyed.
566      * @return tests {@link DataObject#isDeleteAllowed}
567      */

568     public boolean canDestroy() {
569         try {
570             InstanceCookie ic = ic();
571             if (ic == null) return true;
572             Class JavaDoc clazz = ic.instanceClass();
573             return (!SharedClassObject.class.isAssignableFrom(clazz));
574         } catch (Exception JavaDoc ex) {
575             return true;
576         }
577     }
578     
579     public boolean canCut() {
580         try {
581             InstanceCookie ic = ic();
582             if (ic == null) return false;
583             Class JavaDoc clazz = ic.instanceClass();
584             return (!SharedClassObject.class.isAssignableFrom(clazz));
585         } catch (Exception JavaDoc ex) {
586             return false;
587         }
588     }
589     
590     public boolean canCopy() {
591         try {
592             InstanceCookie ic = ic();
593             if (ic == null) return false;
594             Class JavaDoc clazz = ic.instanceClass();
595             return (!SharedClassObject.class.isAssignableFrom(clazz));
596         } catch (Exception JavaDoc ex) {
597             return false;
598         }
599     }
600     
601     /** Gets the short description of this feature. */
602     public String JavaDoc getShortDescription() {
603         if (noBeanInfo) return super.getShortDescription();
604         
605         try {
606             InstanceCookie ic = ic();
607             if (ic == null) {
608                 // it must be unrecognized instance
609
return getDataObject().getPrimaryFile().toString();
610             }
611             
612             Class JavaDoc clazz = ic.instanceClass();
613             BeanDescriptor JavaDoc bd = Utilities.getBeanInfo(clazz).getBeanDescriptor();
614             String JavaDoc desc = bd.getShortDescription();
615             return (desc.equals(bd.getDisplayName()))? getDisplayName(): desc;
616         } catch (Exception JavaDoc ex) {
617             return super.getShortDescription();
618         }
619     }
620     
621     /* do not want CustomizeBean to be invoked on double-click */
622     public Action JavaDoc getPreferredAction() {
623         return null;
624     }
625     
626     //
627
// inner classes - properties
628
//
629

630     /** A property that delegates every call to original property
631      * but when modified, also starts a saving task.
632      */

633     private static final class P extends Node.Property {
634         /** delegate */
635         private Node.Property del;
636         /** task to executed */
637         private SerialDataNode t;
638
639         public P (Node.Property del, SerialDataNode t) {
640             super (del.getValueType ());
641             this.del = del;
642             this.t = t;
643         }
644
645         public void setName(java.lang.String JavaDoc str) {
646             del.setName(str);
647         }
648
649         public void restoreDefaultValue() throws IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
650             del.restoreDefaultValue();
651         }
652
653         public void setValue(String JavaDoc str, Object JavaDoc obj) {
654             del.setValue(str, obj);
655         }
656
657         public boolean supportsDefaultValue() {
658             return del.supportsDefaultValue();
659         }
660
661         public boolean canRead() {
662             return del.canRead ();
663         }
664
665         public PropertyEditor JavaDoc getPropertyEditor() {
666             return del.getPropertyEditor();
667         }
668
669         public boolean isHidden() {
670             return del.isHidden();
671         }
672
673         public Object JavaDoc getValue() throws IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
674             return del.getValue ();
675         }
676
677         public void setExpert(boolean param) {
678             del.setExpert(param);
679         }
680
681         /** Delegates the set value and also saves the bean.
682          */

683         public void setValue(Object JavaDoc val) throws IllegalAccessException JavaDoc, IllegalArgumentException JavaDoc, InvocationTargetException JavaDoc {
684             del.setValue (val);
685             t.resolvePropertyChange();
686         }
687
688         public void setShortDescription(String JavaDoc str) {
689             del.setShortDescription(str);
690         }
691
692         public boolean isExpert() {
693             return del.isExpert();
694         }
695
696         public boolean canWrite() {
697             return del.canWrite ();
698         }
699
700         public Class JavaDoc getValueType() {
701             return del.getValueType();
702         }
703
704         public String JavaDoc getDisplayName() {
705             return del.getDisplayName();
706         }
707
708         public Enumeration JavaDoc<String JavaDoc> attributeNames() {
709             return del.attributeNames();
710         }
711
712         public String JavaDoc getShortDescription() {
713             return del.getShortDescription();
714         }
715
716         public String JavaDoc getName() {
717             return del.getName();
718         }
719
720         public void setHidden(boolean param) {
721             del.setHidden(param);
722         }
723
724         public void setDisplayName(String JavaDoc str) {
725             del.setDisplayName(str);
726         }
727
728         public boolean isPreferred() {
729             return del.isPreferred();
730         }
731
732         public Object JavaDoc getValue(String JavaDoc str) {
733             return del.getValue(str);
734         }
735
736         public void setPreferred(boolean param) {
737             del.setPreferred(param);
738         }
739
740     } // end of P
741

742     /** A property that delegates every call to original property
743      * but when modified, also starts a saving task.
744      */

745     private static final class I extends Node.IndexedProperty {
746         /** delegate */
747         private Node.IndexedProperty del;
748         /** task to executed */
749         private SerialDataNode t;
750
751         public I (Node.IndexedProperty del, SerialDataNode t) {
752             super (del.getValueType (), del.getElementType ());
753             this.del = del;
754             this.t = t;
755         }
756
757         public void setName(java.lang.String JavaDoc str) {
758             del.setName(str);
759         }
760
761         public void restoreDefaultValue() throws IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
762             del.restoreDefaultValue();
763         }
764
765         public void setValue(String JavaDoc str, Object JavaDoc obj) {
766             del.setValue(str, obj);
767         }
768
769         public boolean supportsDefaultValue() {
770             return del.supportsDefaultValue();
771         }
772
773         public boolean canRead() {
774             return del.canRead ();
775         }
776
777         public PropertyEditor JavaDoc getPropertyEditor() {
778             return del.getPropertyEditor();
779         }
780
781         public boolean isHidden() {
782             return del.isHidden();
783         }
784
785         public Object JavaDoc getValue() throws IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
786             return del.getValue ();
787         }
788
789         public void setExpert(boolean param) {
790             del.setExpert(param);
791         }
792
793         /** Delegates the set value and also saves the bean.
794          */

795         public void setValue(Object JavaDoc val) throws IllegalAccessException JavaDoc, IllegalArgumentException JavaDoc, InvocationTargetException JavaDoc {
796             del.setValue (val);
797             t.resolvePropertyChange();
798         }
799
800         public void setShortDescription(String JavaDoc str) {
801             del.setShortDescription(str);
802         }
803
804         public boolean isExpert() {
805             return del.isExpert();
806         }
807
808         public boolean canWrite() {
809             return del.canWrite ();
810         }
811
812         public Class JavaDoc getValueType() {
813             return del.getValueType();
814         }
815
816         public String JavaDoc getDisplayName() {
817             return del.getDisplayName();
818         }
819
820         public Enumeration JavaDoc<String JavaDoc> attributeNames() {
821             return del.attributeNames();
822         }
823
824         public String JavaDoc getShortDescription() {
825             return del.getShortDescription();
826         }
827
828         public String JavaDoc getName() {
829             return del.getName();
830         }
831
832         public void setHidden(boolean param) {
833             del.setHidden(param);
834         }
835
836         public void setDisplayName(String JavaDoc str) {
837             del.setDisplayName(str);
838         }
839
840         public boolean isPreferred() {
841             return del.isPreferred();
842         }
843
844         public Object JavaDoc getValue(String JavaDoc str) {
845             return del.getValue(str);
846         }
847
848         public void setPreferred(boolean param) {
849             del.setPreferred(param);
850         }
851
852         public boolean canIndexedRead () {
853             return del.canIndexedRead ();
854         }
855
856         public Class JavaDoc getElementType () {
857             return del.getElementType ();
858         }
859
860         public Object JavaDoc getIndexedValue (int index) throws
861         IllegalAccessException JavaDoc, IllegalArgumentException JavaDoc, InvocationTargetException JavaDoc {
862             return del.getIndexedValue (index);
863         }
864
865         public boolean canIndexedWrite () {
866             return del.canIndexedWrite ();
867         }
868
869         public void setIndexedValue (int indx, Object JavaDoc val) throws
870         IllegalAccessException JavaDoc, IllegalArgumentException JavaDoc, InvocationTargetException JavaDoc {
871             del.setIndexedValue (indx, val);
872             t.resolvePropertyChange();
873         }
874
875         public PropertyEditor JavaDoc getIndexedPropertyEditor () {
876             return del.getIndexedPropertyEditor ();
877         }
878     } // end of I
879

880     /** Derived from BeanChildren and allow replace beancontext. */
881     private final static class InstanceChildren extends Children.Keys {
882         SerialDataNode task;
883         DataObject dobj;
884         Object JavaDoc bean;
885         ContextL contextL = null;
886         
887         public InstanceChildren() {
888         }
889         
890         protected void addNotify () {
891             super.addNotify();
892             
893             task = (SerialDataNode) getNode();
894             dobj = task.getDataObject();
895             // attaches a listener to the bean
896
contextL = new ContextL (this);
897             init();
898         }
899         
900         protected void removeNotify () {
901             if (contextL != null && bean != null)
902                 ((BeanContext JavaDoc) bean).removeBeanContextMembershipListener (contextL);
903             contextL = null;
904             
905             setKeys(Collections.emptySet());
906         }
907         
908         private void init() {
909             try {
910                 InstanceCookie ic = (InstanceCookie) dobj.getCookie(InstanceCookie.class);
911                 if (ic == null) {
912                     bean = null;
913                     return;
914                 }
915                 Class JavaDoc clazz = ic.instanceClass();
916                 if (BeanContext JavaDoc.class.isAssignableFrom(clazz)) {
917                     bean = ic.instanceCreate();
918                 } else if (BeanContextProxy JavaDoc.class.isAssignableFrom(clazz)) {
919                     bean = ((BeanContextProxy JavaDoc) ic.instanceCreate()).getBeanContextProxy();
920                 } else {
921                     bean = null;
922                 }
923             } catch (Exception JavaDoc ex) {
924                 bean = null;
925                 Exceptions.printStackTrace(ex);
926             }
927             if (bean != null) {
928                 // attaches a listener to the bean
929
((BeanContext JavaDoc) bean).addBeanContextMembershipListener (contextL);
930             }
931             updateKeys();
932         }
933         
934         private void updateKeys() {
935             if (bean == null) {
936                 setKeys(Collections.emptySet());
937             } else {
938                 setKeys(((BeanContext JavaDoc) bean).toArray());
939             }
940         }
941         
942         /** Create nodes for a given key.
943          * @param key the key
944          * @return child nodes for this key or null if there should be no
945          * nodes for this key
946          */

947         protected Node[] createNodes(Object JavaDoc key) {
948             Object JavaDoc ctx = bean;
949             if (bean == null) return new Node[0];
950             
951             try {
952                 if (key instanceof BeanContextSupport JavaDoc) {
953                     BeanContextSupport JavaDoc bcs = (BeanContextSupport JavaDoc)key;
954
955                     if (((BeanContext JavaDoc) ctx).contains (bcs.getBeanContextPeer())) {
956                         // sometimes a BeanContextSupport occures in the list of
957
// beans children even there is its peer. we think that
958
// it is desirable to hide the context if the peer is
959
// also present
960
return new Node[0];
961                     }
962                 }
963
964                 return new Node[] { new BeanContextNode (key, task) };
965             } catch (IntrospectionException JavaDoc ex) {
966                 // ignore the exception
967
return new Node[0];
968             }
969         }
970         
971         /** Context listener.
972         */

973         private static final class ContextL implements BeanContextMembershipListener JavaDoc {
974             /** weak reference to the BeanChildren object */
975             private final Reference JavaDoc<InstanceChildren> ref;
976
977             /** Constructor */
978             ContextL (InstanceChildren bc) {
979                 ref = new WeakReference JavaDoc<InstanceChildren> (bc);
980             }
981
982             /** Listener method that is called when a bean is added to
983             * the bean context.
984             * @param bcme event describing the action
985             */

986             public void childrenAdded (BeanContextMembershipEvent JavaDoc bcme) {
987                 InstanceChildren bc = ref.get ();
988                 if (bc != null) {
989                     bc.updateKeys();
990                 }
991             }
992
993             /** Listener method that is called when a bean is removed to
994             * the bean context.
995             * @param bcme event describing the action
996             */

997             public void childrenRemoved (BeanContextMembershipEvent JavaDoc bcme) {
998                 InstanceChildren bc = ref.get ();
999                 if (bc != null) {
1000                    bc.updateKeys ();
1001                }
1002            }
1003        }
1004    }
1005    
1006    /** Creates BeanContextNode for each bean
1007    */

1008    private static class BeanFactoryImpl implements BeanChildren.Factory {
1009        SerialDataNode task;
1010        public BeanFactoryImpl(SerialDataNode task) {
1011            this.task = task;
1012        }
1013        
1014        /** @return bean node */
1015        public Node createNode (Object JavaDoc bean) throws IntrospectionException JavaDoc {
1016            return new BeanContextNode (bean, task);
1017        }
1018    }
1019    
1020    private static class BeanContextNode extends BeanNode<Object JavaDoc> {
1021        public BeanContextNode(Object JavaDoc bean, SerialDataNode task) throws IntrospectionException JavaDoc {
1022            super(bean, getChildren(bean, task));
1023            changeSheet(getSheet(), task);
1024        }
1025        
1026        private void changeSheet(Sheet orig, SerialDataNode task) {
1027            Sheet.Set props = orig.get (Sheet.PROPERTIES);
1028            if (props != null) {
1029                convertProps (props, props.getProperties(), task);
1030            }
1031
1032            props = orig.get(Sheet.EXPERT);
1033            if (props != null) {
1034                convertProps (props, props.getProperties(), task);
1035            }
1036        }
1037        private static Children getChildren (Object JavaDoc bean, SerialDataNode task) {
1038            if (bean instanceof BeanContext JavaDoc)
1039                return new BeanChildren ((BeanContext JavaDoc)bean, new BeanFactoryImpl(task));
1040            if (bean instanceof BeanContextProxy JavaDoc) {
1041                java.beans.beancontext.BeanContextChild JavaDoc bch = ((BeanContextProxy JavaDoc)bean).getBeanContextProxy();
1042                if (bch instanceof BeanContext JavaDoc)
1043                    return new BeanChildren ((BeanContext JavaDoc)bch, new BeanFactoryImpl(task));
1044            }
1045            return Children.LEAF;
1046        }
1047        
1048        // #7925
1049
public boolean canDestroy() {
1050            return false;
1051        }
1052
1053        public Action JavaDoc[] getActions(boolean context) {
1054            return removeActions(super.getActions(context), new Action JavaDoc[] {SystemAction.get(ToolsAction.class)});
1055        }
1056        
1057        private static Action JavaDoc[] removeActions(Action JavaDoc[] allActions, Action JavaDoc[] toDeleteActions) {
1058            Action JavaDoc[] retVal = allActions;
1059            List JavaDoc<Action JavaDoc> actions = Arrays.asList(allActions);
1060            for (int i = 0; i < toDeleteActions.length; i++) {
1061                Action JavaDoc a = toDeleteActions[i];
1062                if(actions.contains(a)) {
1063                    actions = new ArrayList JavaDoc<Action JavaDoc>(actions); // to be mutable
1064
actions.remove(a);
1065                    retVal = actions.toArray(new Action JavaDoc[0]);
1066                }
1067            }
1068            return retVal;
1069        }
1070    }
1071    
1072    /** Property change listener to update the properties of the node and
1073    * also the name of the node (sometimes)
1074    */

1075    private final class PropL extends Object JavaDoc implements PropertyChangeListener JavaDoc {
1076        private Collection JavaDoc<String JavaDoc> supportedPropertyNames;
1077        PropL(Collection JavaDoc<String JavaDoc> supportedPropertyNames) {
1078            this.supportedPropertyNames = supportedPropertyNames;
1079        }
1080        
1081        private boolean isChanged = false;
1082        public void propertyChange(PropertyChangeEvent JavaDoc e) {
1083            isChanged = true;
1084            String JavaDoc name = e.getPropertyName();
1085
1086            if (isSupportedName(name)) {
1087                firePropertyChange (name, e.getOldValue (), e.getNewValue ());
1088            
1089                if (name.equals("name")) { // NOI18N
1090
SerialDataNode.this.isNameChanged = true;
1091                    // ensure the display name is updated also for ServiceTypes
1092
SerialDataNode.this.fireDisplayNameChange(null, null);
1093                } else if (name.equals("displayName")) { // NOI18N
1094
SerialDataNode.this.isNameChanged = true;
1095                }
1096            }
1097        }
1098
1099        private boolean isSupportedName(String JavaDoc name) {
1100            return name != null && supportedPropertyNames.contains(name);
1101        }
1102
1103        public boolean getChangeAndReset() {
1104            boolean wasChanged = isChanged;
1105            isChanged = false;
1106            return wasChanged;
1107        }
1108    }
1109        
1110}
1111
Popular Tags