KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > form > RADConnectionPropertyEditor


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
21 package org.netbeans.modules.form;
22
23 import java.awt.*;
24 import java.beans.*;
25
26 import org.openide.explorer.propertysheet.*;
27 import org.openide.explorer.propertysheet.editors.*;
28
29 /**
30  * RADConnectionPropertyEditor is a special property editor that can set
31  * properties (of any type) indirectly - e.g. as a property of some bean
32  * or as the result of a method call or as a code entered by the user, etc.
33  * Only the source code is generated for such property (usually) so it
34  * doesn't take effect until runtime.
35  *
36  * @author Ian Formanek
37  */

38
39 public class RADConnectionPropertyEditor
40     implements PropertyEditor,
41                FormAwareEditor,
42                XMLPropertyEditor,
43                NamedPropertyEditor
44 {
45     protected PropertyChangeSupport support;
46     private Class JavaDoc propertyType;
47     private FormModel formModel = null;
48     private RADConnectionDesignValue designValue = null;
49     private Object JavaDoc realValue = null;
50
51     /** Creates a new RADConnectionPropertyEditor */
52     public RADConnectionPropertyEditor(Class JavaDoc propertyType) {
53         support = new PropertyChangeSupport(this);
54         this.propertyType = propertyType;
55     }
56
57     /** If a property editor or customizer implements the FormAwareEditor
58      * interface, this method is called immediately after the PropertyEditor
59      * instance is created or the Customizer is obtained from getCustomizer().
60      * @param model The FormModel representing data of opened form.
61      */

62     public void setFormModel(FormModel model) {
63         formModel = model;
64     }
65
66     // -----------------------------------------------------------------------------
67
// PropertyEditor implementation
68

69     public Object JavaDoc getValue() {
70         
71         return designValue != null ? designValue : realValue;
72     }
73
74     public void setValue(Object JavaDoc value) {
75         
76
77         if (value instanceof RADConnectionDesignValue) {
78             designValue =(RADConnectionDesignValue)value;
79         } else {
80             designValue = null;
81             realValue = value;
82         }
83         support.firePropertyChange("", null, null); // NOI18N
84
}
85
86     public void setAsText(String JavaDoc string) {
87     }
88
89     public String JavaDoc getAsText() {
90         return null;
91     }
92
93     public String JavaDoc[] getTags() {
94         return null;
95     }
96
97     public boolean isPaintable() {
98         return true;
99     }
100
101     public void paintValue(Graphics g, Rectangle rectangle) {
102         FontMetrics fm = g.getFontMetrics();
103         g.drawString(getValueString(), rectangle.x,
104                             rectangle.y + (rectangle.height - fm.getHeight()) / 2 + fm.getAscent());
105     }
106
107     public boolean supportsCustomEditor() {
108         return true;
109     }
110
111     public java.awt.Component JavaDoc getCustomEditor() {
112         ParametersPicker pp = new ParametersPicker(formModel, propertyType);
113         pp.setPropertyValue(designValue, realValue);
114         return pp;
115     }
116
117     public String JavaDoc getJavaInitializationString() {
118         if (designValue != null) {
119             if (designValue.needsInit)
120                 designValue.initialize();
121
122             if (designValue.type == RADConnectionDesignValue.TYPE_VALUE) {
123                 if ("java.lang.String".equals(designValue.requiredTypeName)) // NOI18N
124
return "\""+designValue.value+"\""; // NOI18N
125
else if ("long".equals(designValue.requiredTypeName)) // NOI18N
126
return designValue.value+"L"; // NOI18N
127
else if ("float".equals(designValue.requiredTypeName)) // NOI18N
128
return designValue.value+"F"; // NOI18N
129
else if ("double".equals(designValue.requiredTypeName)) // NOI18N
130
return designValue.value+"D"; // NOI18N
131
else if ("char".equals(designValue.requiredTypeName)) // NOI18N
132
return "\'"+designValue.value+"\'"; // NOI18N
133
else return designValue.value;
134             }
135             else if (designValue.type == RADConnectionDesignValue.TYPE_CODE)
136                 return designValue.userCode;
137             else {
138                 if (designValue.radComponent == null
139                         || designValue.radComponent.getCodeExpression() == null)
140                     return null; // invalid component (probably deleted)
141

142                 if (designValue.type == RADConnectionDesignValue.TYPE_PROPERTY) {
143                     PropertyDescriptor pd = designValue.getProperty();
144                     if (pd == null) return null; // failed to initialize => do not generate code
145
else {
146                         if (designValue.radComponent == formModel.getTopRADComponent()) {
147                             return pd.getReadMethod().getName() + "()"; // [FUTURE: Handle indexed properties] // NOI18N
148
} else {
149                             return designValue.radComponent.getName() + "." + pd.getReadMethod().getName() + "()"; // [FUTURE: Handle indexed properties] // NOI18N
150
}
151                     }
152                 }
153                 else if (designValue.type == RADConnectionDesignValue.TYPE_METHOD) {
154                     if (designValue.radComponent == formModel.getTopRADComponent()) {
155                         return designValue.methodName + "()"; // NOI18N
156
} else {
157                         return designValue.radComponent.getName() + "." + designValue.methodName + "()"; // NOI18N
158
}
159                 }
160                 else if (designValue.type == RADConnectionDesignValue.TYPE_BEAN) {
161                     if (designValue.radComponent == formModel.getTopRADComponent()) {
162                         return "this"; // NOI18N
163
} else {
164                         return designValue.radComponent.getName();
165                     }
166                 }
167             }
168         }
169         return null;
170     }
171
172     public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener) {
173         support.addPropertyChangeListener(propertyChangeListener);
174     }
175
176     public void removePropertyChangeListener(PropertyChangeListener propertyChangeListener) {
177         support.removePropertyChangeListener(propertyChangeListener);
178     }
179
180     // ------------------------------------------
181
// NamedPropertyEditor implementation
182

183     /** @return display name of the property editor */
184     public String JavaDoc getDisplayName() {
185         return FormUtils.getBundleString("CTL_RADConn_DisplayName"); // NOI18N
186
}
187
188     // ------------------------------------------
189
private String JavaDoc getValueString() {
190         String JavaDoc str;
191         if (designValue != null) {
192             str = designValue.getName();
193         }
194         else if (realValue != null) {
195             if (realValue instanceof Number JavaDoc
196                   || realValue instanceof Boolean JavaDoc
197                   || realValue instanceof String JavaDoc
198                   || realValue instanceof Character JavaDoc)
199                 str = realValue.toString();
200             else
201                 str = realValue.getClass().isArray() ?
202                         "[" + FormUtils.getBundleString("CTL_ArrayOf") + " " // NOI18N
203
+ realValue.getClass().getComponentType().getName() + "]" // NOI18N
204
:
205                         "["+org.openide.util.Utilities.getShortClassName(realValue.getClass())+"]"; // NOI18N
206
}
207         else str = "null"; // NOI18N
208

209         return str;
210     }
211
212
213     // ------------------------------------------
214
// implementation class for FormDesignValue
215

216     public static class RADConnectionDesignValue implements FormDesignValue { //, java.io.Serializable {
217
public final static int TYPE_PROPERTY = 0;
218         public final static int TYPE_METHOD = 1;
219         public final static int TYPE_CODE = 2;
220         public final static int TYPE_VALUE = 3;
221         public final static int TYPE_BEAN = 4;
222
223         /** Determines the type of connection design value */
224         int type;
225
226         private transient RADComponent radComponent = null; // used if type = TYPE_PROPERTY or TYPE_METHOD or TYPE_BEAN
227
String JavaDoc radComponentName = null; // used if type = TYPE_PROPERTY or TYPE_METHOD
228

229         private transient MethodDescriptor method = null; // used if type = TYPE_METHOD
230
String JavaDoc methodName = null; // used if type = TYPE_METHOD
231
private transient PropertyDescriptor property = null; // used if type = TYPE_PROPERTY
232
String JavaDoc propertyName = null; // used if type = TYPE_PROPERTY
233
String JavaDoc userCode = null; // used if type = TYPE_CODE
234
String JavaDoc value = null; // used if type = TYPE_VALUE
235
String JavaDoc requiredTypeName = null; // used if type = TYPE_VALUE
236

237         transient private boolean needsInit = false; // used for deserialization init if type = TYPE_PROPERTY or TYPE_METHOD or TYPE_BEAN
238
transient private FormModel formModel; // used for deserialization init if type = TYPE_PROPERTY or TYPE_METHOD or TYPE_BEAN
239

240         static final long serialVersionUID =147134837271021412L;
241         RADConnectionDesignValue(RADComponent comp) {
242             radComponent = comp;
243             radComponentName = radComponent.getName();
244             type = TYPE_BEAN;
245         }
246
247         RADConnectionDesignValue(RADComponent comp, MethodDescriptor md) {
248             radComponent = comp;
249             radComponentName = radComponent.getName();
250             method = md;
251             methodName = md.getName();
252             type = TYPE_METHOD;
253         }
254
255         RADConnectionDesignValue(RADComponent comp, PropertyDescriptor pd) {
256             radComponent = comp;
257             radComponentName = radComponent.getName();
258             property = pd;
259             propertyName = pd.getName();
260             type = TYPE_PROPERTY;
261         }
262
263         RADConnectionDesignValue(String JavaDoc reqTypeName, String JavaDoc valueText) {
264             this.requiredTypeName = reqTypeName;
265             this.value = valueText;
266             type = TYPE_VALUE;
267         }
268
269         private RADConnectionDesignValue(String JavaDoc compName, int valueType, String JavaDoc name, FormModel manager) {
270             radComponentName = compName;
271             formModel = manager;
272             if (valueType == TYPE_PROPERTY) {
273                 needsInit = true;
274                 type = TYPE_PROPERTY;
275                 propertyName = name;
276             } else if (valueType == TYPE_METHOD) {
277                 needsInit = true;
278                 type = TYPE_METHOD;
279                 methodName = name;
280             } else if (valueType == TYPE_BEAN) {
281                 needsInit = true;
282                 type = TYPE_BEAN;
283             } else throw new IllegalArgumentException JavaDoc();
284         }
285
286         public RADConnectionDesignValue(Class JavaDoc requiredType, String JavaDoc valueText) {
287             this.requiredTypeName = requiredType.getName();
288             this.value = valueText;
289             type = TYPE_VALUE;
290         }
291
292         public RADConnectionDesignValue(String JavaDoc userCode) {
293             this.userCode = userCode;
294             type = TYPE_CODE;
295         }
296
297         public FormDesignValue copy(FormProperty formProperty) {
298             switch(type) {
299                 case TYPE_CODE:
300                     return new RADConnectionDesignValue(userCode);
301                 case TYPE_VALUE:
302                     return new RADConnectionDesignValue(requiredTypeName, value);
303             }
304             return null;
305         }
306         
307         String JavaDoc getName() {
308             if (needsInit)
309                 initialize();
310
311             if (type == TYPE_VALUE)
312                 return FormUtils.getFormattedBundleString("FMT_VALUE_CONN", // NOI18N
313
new Object JavaDoc[] { value });
314             else if (type == TYPE_CODE)
315                 return FormUtils.getBundleString("CTL_CODE_CONN"); // NOI18N
316
else {
317                 if (radComponent == null || radComponent.getCodeExpression() == null)
318                     return FormUtils.getBundleString("CTL_CONNECTION_INVALID"); // NOI18N
319

320                 if (radComponent == null)
321                     return null;
322
323                 if (type == TYPE_PROPERTY)
324                     return FormUtils.getFormattedBundleString(
325                         "FMT_PROPERTY_CONN", // NOI18N
326
new Object JavaDoc[] { radComponent.getName(), propertyName });
327                 else if (type == TYPE_METHOD)
328                     return FormUtils.getFormattedBundleString(
329                         "FMT_METHOD_CONN", // NOI18N
330
new Object JavaDoc[] { radComponent.getName(), methodName });
331                 else if (type == TYPE_BEAN)
332                      return FormUtils.getFormattedBundleString(
333                          "FMT_BEAN_CONN", // NOI18N
334
new Object JavaDoc[] { radComponent.getName() });
335             }
336
337             throw new IllegalStateException JavaDoc();
338         }
339
340         public PropertyDescriptor getProperty() {
341             if (needsInit) {
342                 if (!initialize()) return null;
343             }
344             return property;
345         }
346
347         public MethodDescriptor getMethod() {
348             if (needsInit) {
349                 if (!initialize()) return null;
350             }
351             return method;
352         }
353
354         public String JavaDoc getCode() {
355             if (needsInit) {
356                 if (!initialize()) return null;
357             }
358             return userCode;
359         }
360
361         public String JavaDoc getValue() {
362             if (needsInit) {
363                 if (!initialize()) return null;
364             }
365             return value;
366         }
367
368         public RADComponent getRADComponent() {
369             if (needsInit) {
370                 if (!initialize()) return null;
371             }
372             return radComponent;
373         }
374
375         private boolean initialize() {
376             boolean retVal = false;
377             radComponent = formModel.findRADComponent(radComponentName);
378             if (radComponent != null) {
379                 if (type == TYPE_BEAN) { // bean
380
retVal = true;
381                 } else if (type == TYPE_PROPERTY) { // property
382
PropertyDescriptor[] componentsProps = radComponent.getBeanInfo().getPropertyDescriptors();
383                     for (int i = 0; i < componentsProps.length; i++) {
384                         if (componentsProps[i].getName().equals(propertyName)) {
385                             property = componentsProps[i];
386                             retVal = true;
387                             break;
388                         }
389                     } // if the property of given name cannot be found => ignore
390
} else { // method
391
MethodDescriptor[] componentMethods = radComponent.getBeanInfo().getMethodDescriptors();
392                     for (int i = 0; i < componentMethods.length; i++) {
393                         if (componentMethods[i].getName().equals(methodName)) {
394                             method = componentMethods[i];
395                             retVal = true;
396                             break;
397                         }
398                     } // if the property of given name cannot be found => ignore
399
}
400             } // if the component cannot be found, simply ignore it
401
if (retVal) needsInit = false;
402             return retVal;
403         }
404
405         /** Provides a value which should be used during design-time
406          * as the real property value on the bean instance.
407          * E.g. the ResourceBundle String would provide the real value
408          * of the String from the resource bundle, so that the design-time
409          * representation reflects the real code being generated.
410          * @param radComponent the radComponent in which this property is used
411          * @return the real property value to be used during design-time
412          */

413         public Object JavaDoc getDesignValue() { //RADComponent radComponent) {
414
/* if (needsInit) {
415                     if (!initialize()) {
416                     return IGNORED_VALUE; // failed to initialize
417                     }
418                     } */

419             switch (type) {
420                 case TYPE_PROPERTY:
421                     try {
422                         Object JavaDoc value = getProperty().getReadMethod().invoke(getRADComponent().getBeanInstance(), new Object JavaDoc[0]);
423                         return value;
424                     } catch (Exception JavaDoc e) {
425                         // in case of failure do not provide the value during design time
426
return FormDesignValue.IGNORED_VALUE;
427                     }
428                 case TYPE_METHOD:
429                     try {
430                         Object JavaDoc value = getMethod().getMethod().invoke(getRADComponent().getBeanInstance(), new Object JavaDoc[0]);
431                         return value;
432                     } catch (Exception JavaDoc e) {
433                         // in case of failure do not provide the value during design time
434
return FormDesignValue.IGNORED_VALUE;
435                     }
436                 case TYPE_VALUE:
437                     return parseValue(requiredTypeName, value);
438                 case TYPE_BEAN:
439                     RADComponent comp = getRADComponent();
440                     return (comp == null) ? FormDesignValue.IGNORED_VALUE : comp.getBeanInstance();
441                 case TYPE_CODE:
442                     return FormDesignValue.IGNORED_VALUE;
443                 default:
444                     return FormDesignValue.IGNORED_VALUE;
445             }
446         }
447
448         public String JavaDoc getDescription() {
449             return getName();
450         }
451
452         /** Returns type of this connection design value.
453          */

454         public int getType() {
455             return type;
456         }
457     } // end of inner class
458

459     private static Object JavaDoc parseValue(String JavaDoc typeName, String JavaDoc value) {
460         try {
461             if ("java.lang.String".equals(typeName)) { // NOI18N
462
return value;
463             } else if ("int".equals(typeName)) { // NOI18N
464
return Integer.valueOf(value);
465             } else if ("short".equals(typeName)) { // NOI18N
466
return Short.valueOf(value);
467             } else if ("long".equals(typeName)) { // NOI18N
468
return Long.valueOf(value);
469             } else if ("byte".equals(typeName)) { // NOI18N
470
return Byte.valueOf(value);
471             } else if ("float".equals(typeName)) { // NOI18N
472
return Float.valueOf(value);
473             } else if ("double".equals(typeName)) { // NOI18N
474
return Double.valueOf(value);
475             } else if ("boolean".equals(typeName)) { // NOI18N
476
return Boolean.valueOf(value);
477             } else if ("char".equals(typeName)) { // NOI18N
478
if (value.length() > 0) return new Character JavaDoc(value.charAt(0));
479             }
480             return FormDesignValue.IGNORED_VALUE;
481         } catch (Exception JavaDoc e) {
482             // some problem => use ignored value
483
return FormDesignValue.IGNORED_VALUE;
484         }
485     }
486
487     //--------------------------------------------------------------------------
488
// XMLPropertyEditor implementation
489

490     public static final String JavaDoc XML_CONNECTION = "Connection"; // NOI18N
491

492     public static final String JavaDoc ATTR_TYPE = "type"; // NOI18N
493
public static final String JavaDoc ATTR_COMPONENT = "component"; // NOI18N
494
public static final String JavaDoc ATTR_NAME = "name"; // NOI18N
495
public static final String JavaDoc ATTR_CODE = "code"; // NOI18N
496
public static final String JavaDoc ATTR_VALUE = "value"; // NOI18N
497
public static final String JavaDoc ATTR_REQUIRED_TYPE = "valueType"; // NOI18N
498

499     public static final String JavaDoc VALUE_VALUE = "value"; // NOI18N
500
public static final String JavaDoc VALUE_PROPERTY = "property"; // NOI18N
501
public static final String JavaDoc VALUE_METHOD = "method"; // NOI18N
502
public static final String JavaDoc VALUE_BEAN = "bean"; // NOI18N
503
public static final String JavaDoc VALUE_CODE = "code"; // NOI18N
504

505     /** Called to load property value from specified XML subtree. If succesfully loaded,
506      * the value should be available via the getValue method.
507      * An IOException should be thrown when the value cannot be restored from the specified XML element
508      * @param element the XML DOM element representing a subtree of XML from which the value should be loaded
509      * @exception IOException thrown when the value cannot be restored from the specified XML element
510      */

511     public void readFromXML(org.w3c.dom.Node JavaDoc element) throws java.io.IOException JavaDoc {
512         if (!XML_CONNECTION.equals(element.getNodeName())) {
513             throw new java.io.IOException JavaDoc();
514         }
515         org.w3c.dom.NamedNodeMap JavaDoc attributes = element.getAttributes();
516         try {
517             String JavaDoc typeString = attributes.getNamedItem(ATTR_TYPE).getNodeValue();
518             if (VALUE_VALUE.equals(typeString)) {
519                 String JavaDoc value = attributes.getNamedItem(ATTR_VALUE).getNodeValue();
520                 String JavaDoc valueType = attributes.getNamedItem(ATTR_REQUIRED_TYPE).getNodeValue();
521                 setValue(new RADConnectionDesignValue(valueType, value));
522
523             } else if (VALUE_PROPERTY.equals(typeString)) {
524                 String JavaDoc component = attributes.getNamedItem(ATTR_COMPONENT).getNodeValue();
525                 String JavaDoc name = attributes.getNamedItem(ATTR_NAME).getNodeValue();
526                 setValue(new RADConnectionDesignValue(component, RADConnectionDesignValue.TYPE_PROPERTY, name, formModel)); //rcomponent.getFormModel()));
527

528             } else if (VALUE_METHOD.equals(typeString)) {
529                 String JavaDoc component = attributes.getNamedItem(ATTR_COMPONENT).getNodeValue();
530                 String JavaDoc name = attributes.getNamedItem(ATTR_NAME).getNodeValue();
531                 setValue(new RADConnectionDesignValue(component, RADConnectionDesignValue.TYPE_METHOD, name, formModel)); //rcomponent.getFormModel()));
532

533             } else if (VALUE_BEAN.equals(typeString)) {
534                 String JavaDoc component = attributes.getNamedItem(ATTR_COMPONENT).getNodeValue();
535                 setValue(new RADConnectionDesignValue(component, RADConnectionDesignValue.TYPE_BEAN, null, formModel)); //rcomponent.getFormModel()));
536

537             } else {
538                 String JavaDoc code = attributes.getNamedItem(ATTR_CODE).getNodeValue();
539                 setValue(new RADConnectionDesignValue(code));
540             }
541         } catch (NullPointerException JavaDoc e) {
542             if (System.getProperty("netbeans.debug.exceptions") != null) {
543                 e.printStackTrace();
544             }
545             throw new java.io.IOException JavaDoc();
546         }
547     }
548
549     /** Called to store current property value into XML subtree. The property
550      * value should be set using the setValue method prior to calling this method.
551      * @param doc The XML document to store the XML in - should be used for creating nodes only
552      * @return the XML DOM element representing a subtree of XML from which the
553      * value should be loaded
554      */

555
556     public org.w3c.dom.Node JavaDoc storeToXML(org.w3c.dom.Document JavaDoc doc) {
557         if (designValue == null)
558             return null;
559
560         String JavaDoc componentName = designValue.radComponent != null ?
561                                    designValue.radComponent.getName() :
562                                    designValue.radComponentName;
563
564         if (componentName == null && designValue.radComponent != null)
565             return null; // invalid component (probably deleted)
566

567         org.w3c.dom.Element JavaDoc el = doc.createElement(XML_CONNECTION);
568         String JavaDoc typeString;
569         switch (designValue.type) {
570             case RADConnectionDesignValue.TYPE_VALUE: typeString = VALUE_VALUE; break;
571             case RADConnectionDesignValue.TYPE_PROPERTY: typeString = VALUE_PROPERTY; break;
572             case RADConnectionDesignValue.TYPE_METHOD: typeString = VALUE_METHOD; break;
573             case RADConnectionDesignValue.TYPE_BEAN: typeString = VALUE_BEAN; break;
574             case RADConnectionDesignValue.TYPE_CODE:
575             default:
576                 typeString = VALUE_CODE; break;
577         }
578         el.setAttribute(ATTR_TYPE, typeString);
579         switch (designValue.type) {
580             case RADConnectionDesignValue.TYPE_VALUE:
581                 el.setAttribute(ATTR_VALUE, designValue.value);
582                 el.setAttribute(ATTR_REQUIRED_TYPE, designValue.requiredTypeName);
583                 break;
584             case RADConnectionDesignValue.TYPE_PROPERTY:
585                 el.setAttribute(ATTR_COMPONENT, componentName);
586                 el.setAttribute(ATTR_NAME, designValue.propertyName);
587                 break;
588             case RADConnectionDesignValue.TYPE_METHOD:
589                 el.setAttribute(ATTR_COMPONENT, componentName);
590                 el.setAttribute(ATTR_NAME, designValue.methodName);
591                 break;
592             case RADConnectionDesignValue.TYPE_BEAN:
593                 el.setAttribute(ATTR_COMPONENT, componentName);
594                 break;
595             case RADConnectionDesignValue.TYPE_CODE:
596                 el.setAttribute(ATTR_CODE, designValue.userCode);
597                 break;
598         }
599
600         return el;
601     }
602 }
603
Popular Tags