KickJava   Java API By Example, From Geeks To Geeks.

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


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.form;
21
22 import java.util.*;
23 import java.lang.reflect.*;
24 import org.netbeans.modules.form.codestructure.*;
25
26 /**
27  * @author Tomas Pavek
28  */

29
30 public class CreationDescriptor {
31
32     // style flags - for finding best creator for a set or properties
33
public static final int CHANGED_ONLY = 1;
34     public static final int PLACE_ALL = 2;
35
36     public interface Creator {
37
38         public int getParameterCount();
39
40         public Class JavaDoc[] getParameterTypes();
41
42         public Class JavaDoc[] getExceptionTypes();
43
44         public String JavaDoc[] getPropertyNames();
45
46         public Object JavaDoc createInstance(FormProperty[] props)
47             throws InstantiationException JavaDoc, IllegalAccessException JavaDoc,
48                    IllegalArgumentException JavaDoc, InvocationTargetException;
49
50         public Object JavaDoc createInstance(Object JavaDoc[] paramValues)
51             throws InstantiationException JavaDoc, IllegalAccessException JavaDoc,
52                    IllegalArgumentException JavaDoc, InvocationTargetException;
53         
54         // [this will become useless when we can rely on getCodeOrigin(...)]
55
public String JavaDoc getJavaCreationCode(FormProperty[] props, Class JavaDoc expressionType);
56
57         public CodeExpressionOrigin getCodeOrigin(CodeExpression[] params);
58     }
59
60     private Class JavaDoc describedClass;
61     private ArrayList creators = new ArrayList(10);
62     private Object JavaDoc[] defaultParams;
63     private Creator defaultCreator;
64
65     private static final Class JavaDoc[] emptyTypes = { };
66     private static final String JavaDoc[] emptyNames = { };
67     private static final Object JavaDoc[] emptyParams = { };
68
69     public CreationDescriptor() {
70     }
71
72     public CreationDescriptor(Class JavaDoc descClass,
73                               Class JavaDoc[][] constrParamTypes,
74                               String JavaDoc[][] constrPropNames,
75                               Object JavaDoc[] defParams)
76     throws NoSuchMethodException JavaDoc, // if some constructor is not found
77
IllegalArgumentException JavaDoc
78     {
79         addConstructorCreators(descClass, constrParamTypes, constrPropNames, defParams);
80     }
81     
82     public CreationDescriptor(Class JavaDoc factoryClass,
83                               Class JavaDoc descClass,
84                               String JavaDoc methodName,
85                               Class JavaDoc[][] constrParamTypes,
86                               String JavaDoc[][] constrPropNames,
87                               CreationFactory.PropertyParameters[] propertyParameters,
88                               Object JavaDoc[] defParams)
89     throws NoSuchMethodException JavaDoc, // if some method is not found
90
IllegalArgumentException JavaDoc
91     {
92         addMethodCreators(factoryClass, descClass, methodName, constrParamTypes,
93                           constrPropNames, propertyParameters, defParams);
94     }
95     
96     public void addConstructorCreators(Class JavaDoc descClass,
97                                        Class JavaDoc[][] constrParamTypes,
98                                        String JavaDoc[][] constrPropNames,
99                                        Object JavaDoc[] defParams)
100     throws NoSuchMethodException JavaDoc // if some constructor is not found
101
{
102         setDescribedClass(descClass);
103         if (constrParamTypes != null && constrParamTypes.length > 0) {
104             
105             for (int i=0; i < constrParamTypes.length; i++)
106                 creators.add( new ConstructorCreator(describedClass,
107                                                          constrParamTypes[i],
108                                                          constrPropNames[i]) );;
109         }
110
111         defaultParams = defParams == null ? emptyParams : defParams;
112     }
113
114     public void addMethodCreators(Class JavaDoc factoryClass,
115                                   Class JavaDoc descClass,
116                                   String JavaDoc methodName,
117                                   Class JavaDoc[][] constrParamTypes,
118                                   String JavaDoc[][] constrPropNames,
119                                   CreationFactory.PropertyParameters[] propertyParameters,
120                                   Object JavaDoc[] defParams)
121     throws NoSuchMethodException JavaDoc // if some method is not found
122
{
123         setDescribedClass(descClass);
124         
125         if (constrParamTypes != null && constrParamTypes.length > 0) {
126             
127             CreationFactory.Property2ParametersMapper[] properties;
128             for (int i=0; i < constrParamTypes.length; i++) {
129                 
130                 properties = new CreationFactory.Property2ParametersMapper[constrParamTypes[i].length];
131                 for (int j = 0; j < constrParamTypes[i].length; j++) {
132                     properties[j] = new CreationFactory.Property2ParametersMapper(constrParamTypes[i][j], constrPropNames[i][j]);
133                     if(propertyParameters != null && propertyParameters.length > 0) {
134                         for (int ppi = 0; ppi < propertyParameters.length; ppi++) {
135                             if( propertyParameters[ppi].getPropertyName().equals(constrPropNames[i][j]) ) {
136                                 properties[j].setPropertyParameters(propertyParameters[ppi]);
137                             }
138                         }
139                     }
140                 }
141                 
142                 creators.add( new MethodCreator(factoryClass,
143                                                describedClass,
144                                                methodName,
145                                                properties));
146                 
147             }
148             
149         }
150         
151         defaultParams = defParams == null ? emptyParams : defParams;
152     }
153
154     private void setDescribedClass(Class JavaDoc descClass) throws IllegalArgumentException JavaDoc {
155         if(describedClass==null){
156             describedClass = descClass;
157         } else if (describedClass!=descClass) {
158             throw new IllegalArgumentException JavaDoc();
159         }
160     }
161     
162     public CreationDescriptor(Class JavaDoc descClass) {
163 // throws NoSuchMethodException // if public empty constructor doesn't exist
164
describedClass = descClass;
165
166         try {
167             ConstructorCreator creator = new ConstructorCreator(describedClass,
168                                                                 emptyTypes,
169                                                                 emptyNames);
170             creators.add( creator );
171         }
172         catch (NoSuchMethodException JavaDoc ex) { // ignore
173
if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
174
System.out.println("[WARNING] No default constructor for "+descClass.getName()); // NOI18N
175
ex.printStackTrace();
176             }
177         }
178
179         defaultParams = emptyParams;
180     }
181
182     // ---------
183

184     public Class JavaDoc getDescribedClass() {
185         return describedClass;
186     }
187
188     public Creator[] getCreators() {
189         return (Creator[]) creators.toArray(new Creator[creators.size()]);
190     }
191
192     public Creator findBestCreator(FormProperty[] properties, int style) {
193         if (creators == null)
194             return null;
195
196         Creator[] allCreators = getCreators();
197         int[] evals = CreationFactory.evaluateCreators(
198                         allCreators , properties, (style & CHANGED_ONLY) != 0);
199         int best = CreationFactory.getBestCreator(
200                      allCreators , properties, evals, (style & PLACE_ALL) != 0);
201         return allCreators [best];
202     }
203
204     public Object JavaDoc createDefaultInstance() throws InstantiationException JavaDoc,
205                                                  IllegalAccessException JavaDoc,
206                                                  IllegalArgumentException JavaDoc,
207                                                  InvocationTargetException,
208                                                  NoSuchMethodException JavaDoc
209     {
210         return getDefaultCreator().createInstance(defaultParams);
211     }
212
213     private Creator getDefaultCreator() throws NoSuchMethodException JavaDoc {
214         if( defaultCreator == null ) {
215             defaultCreator = findDefaultCreator();
216         }
217         return defaultCreator;
218     }
219     // ----------
220

221     // finds first constructor that matches defaultConstrParams
222
private Creator findDefaultCreator() throws NoSuchMethodException JavaDoc {
223         for (Iterator it = creators.iterator(); it.hasNext();) {
224             
225             Creator creator = (Creator) it.next();
226             Class JavaDoc[] paramTypes = creator.getParameterTypes();
227             
228             if (paramTypes.length == defaultParams.length) {
229                 int ii;
230                 for (ii=0; ii < paramTypes.length; ii++) {
231                     Class JavaDoc cls = paramTypes[ii];
232                     Object JavaDoc param = defaultParams[ii];
233
234                     if (cls.isPrimitive()) {
235                         if (param == null
236                             || (param instanceof Integer JavaDoc && cls != Integer.TYPE)
237                             || (param instanceof Boolean JavaDoc && cls != Boolean.TYPE)
238                             || (param instanceof Double JavaDoc && cls != Double.TYPE)
239                             || (param instanceof Long JavaDoc && cls != Long.TYPE)
240                             || (param instanceof Float JavaDoc && cls != Float.TYPE)
241                             || (param instanceof Short JavaDoc && cls != Short.TYPE)
242                             || (param instanceof Byte JavaDoc && cls != Byte.TYPE)
243                             || (param instanceof Character JavaDoc && cls != Character.TYPE))
244                         break;
245                     }
246                     else if (param != null && !cls.isInstance(param))
247                         break;
248                 }
249                 if (ii == paramTypes.length) {
250                     return creator;
251                 }
252             }
253         }
254         throw new NoSuchMethodException JavaDoc();
255     }
256
257     // ----------
258

259     static class ConstructorCreator implements Creator {
260         private Class JavaDoc theClass;
261         private Constructor constructor;
262 // private Class[] constructorParamTypes;
263
private String JavaDoc[] constructorPropNames;
264
265         ConstructorCreator(Class JavaDoc cls, Class JavaDoc[] paramTypes, String JavaDoc[] propNames)
266             throws NoSuchMethodException JavaDoc
267         {
268             if (paramTypes == null)
269                 paramTypes = emptyTypes;
270             if (propNames == null)
271                 propNames = emptyNames;
272             if (paramTypes.length != propNames.length)
273                 throw new IllegalArgumentException JavaDoc();
274
275             constructor = cls.getConstructor(paramTypes);
276             theClass = cls;
277 // constructorParamTypes = paramTypes;
278
constructorPropNames = propNames;
279         }
280
281         public final int getParameterCount() {
282             return constructorPropNames.length; //constructorParamTypes.length;
283
}
284
285         public final Class JavaDoc[] getParameterTypes() {
286             return constructor.getParameterTypes(); //constructorParamTypes;
287
}
288
289         public final Class JavaDoc[] getExceptionTypes() {
290             return constructor.getExceptionTypes();
291         }
292
293         public final String JavaDoc[] getPropertyNames() {
294             return constructorPropNames;
295         }
296
297         public Object JavaDoc createInstance(FormProperty[] props)
298             throws InstantiationException JavaDoc, IllegalAccessException JavaDoc,
299                    IllegalArgumentException JavaDoc, InvocationTargetException
300         {
301             Object JavaDoc[] paramValues = new Object JavaDoc[constructorPropNames.length];
302
303             try {
304                 for (int i=0; i < constructorPropNames.length; i++) {
305                     FormProperty prop = CreationFactory.findProperty(
306                                             constructorPropNames[i], props);
307                     if (prop == null)
308                         return null; // should not happen
309

310                     paramValues[i] = prop.getRealValue();
311                 }
312             }
313             catch (Exception JavaDoc ex) {
314                 if (Boolean.getBoolean("netbeans.debug.exceptions")) // NOI18N
315
ex.printStackTrace();
316                 throw new InstantiationException JavaDoc(ex.getMessage());
317             }
318
319             return constructor.newInstance(paramValues);
320         }
321
322         public Object JavaDoc createInstance(Object JavaDoc[] paramValues)
323             throws InstantiationException JavaDoc, IllegalAccessException JavaDoc,
324                    IllegalArgumentException JavaDoc, InvocationTargetException
325         {
326             return constructor.newInstance(paramValues);
327         }
328         
329         public String JavaDoc getJavaCreationCode(FormProperty[] props, Class JavaDoc expressionType) {
330             StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
331             buf.append("new "); // NOI18N
332
buf.append(theClass.getName().replace('$', '.'));
333             buf.append("("); // NOI18N
334

335             for (int i=0; i < constructorPropNames.length; i++) {
336                 FormProperty prop = CreationFactory.findProperty(
337                                         constructorPropNames[i], props);
338                 if (prop == null)
339                     return null; // should not happen
340

341                 buf.append(prop.getJavaInitializationString());
342                 if (i+1 < constructorPropNames.length)
343                     buf.append(", "); // NOI18N
344
}
345
346             buf.append(")"); // NOI18N
347
return buf.toString();
348         }
349
350         public CodeExpressionOrigin getCodeOrigin(CodeExpression[] params) {
351             return CodeStructure.createOrigin(constructor, params);
352         }
353     }
354     
355     static class MethodCreator implements Creator {
356         private Class JavaDoc factoryClass;
357         private Class JavaDoc describedClass;
358         private Method method;
359         private CreationFactory.Property2ParametersMapper[] properties;
360         private String JavaDoc[] propertyNames;
361         
362         MethodCreator(Class JavaDoc factoryClass, Class JavaDoc describedClass, String JavaDoc methodName, CreationFactory.Property2ParametersMapper[] properties)
363             throws NoSuchMethodException JavaDoc
364         {
365                         
366             ArrayList paramTypesList = new ArrayList();
367             propertyNames = new String JavaDoc[properties.length];
368             
369             for (int i = 0; i < properties.length; i++) {
370                 for (int j = 0; j < properties[i].getPropertyTypes().length; j++) {
371                     paramTypesList.add(properties[i].getPropertyTypes()[j]);
372                 }
373                 propertyNames[i] = properties[i].getPropertyName();
374             }
375                                     
376             Class JavaDoc[] paramTypes = (Class JavaDoc[]) paramTypesList.toArray(new Class JavaDoc[paramTypesList.size()]);
377
378             method = factoryClass.getMethod(methodName, paramTypes);
379                 
380             this.factoryClass = factoryClass;
381             this.describedClass = describedClass;
382             this.properties = properties;
383             
384         }
385     
386             
387         public final int getParameterCount() {
388             return propertyNames.length;
389         }
390
391         public final Class JavaDoc[] getParameterTypes() {
392             return method.getParameterTypes();
393         }
394
395         public final Class JavaDoc[] getExceptionTypes() {
396             return method.getExceptionTypes();
397         }
398
399         public final String JavaDoc[] getPropertyNames() {
400             return propertyNames;
401         }
402
403         public Object JavaDoc createInstance(FormProperty[] props)
404             throws InstantiationException JavaDoc, IllegalAccessException JavaDoc,
405                    IllegalArgumentException JavaDoc, InvocationTargetException
406         {
407                                 
408             ArrayList paramValuesList = new ArrayList();
409             try {
410                 for (int i=0; i < properties.length; i++) {
411                     FormProperty prop = CreationFactory.findProperty(properties[i].getPropertyName(), props);
412                     if (prop == null)
413                         return null; // should not happen
414

415                     Object JavaDoc[] propertyParameters = properties[i].getPropertyParametersValues(prop);
416                     for (int j = 0; j < propertyParameters.length; j++) {
417                         paramValuesList.add(propertyParameters[j]);
418                     }
419                 }
420             }
421             catch (Exception JavaDoc ex) {
422                 if (Boolean.getBoolean("netbeans.debug.exceptions")) // NOI18N
423
ex.printStackTrace();
424                 throw new InstantiationException JavaDoc(ex.getMessage());
425             }
426             
427             Object JavaDoc[] paramValues = paramValuesList.toArray(new Object JavaDoc[paramValuesList.size()]);
428             
429             Object JavaDoc ret = method.invoke(null, paramValues);
430             if(ret.getClass() != describedClass) {
431                 throw new IllegalArgumentException JavaDoc();
432             }
433             return ret;
434         }
435
436         public Object JavaDoc createInstance(Object JavaDoc[] paramValues)
437             throws InstantiationException JavaDoc, IllegalAccessException JavaDoc,
438                    IllegalArgumentException JavaDoc, InvocationTargetException
439         {
440             
441             Object JavaDoc ret = method.invoke(null, paramValues);
442             if(ret.getClass() != describedClass) {
443                 throw new IllegalArgumentException JavaDoc();
444             }
445             return ret;
446         }
447         
448         public String JavaDoc getJavaCreationCode(FormProperty[] props, Class JavaDoc expressionType) {
449             StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
450             if (expressionType == null) expressionType = describedClass;
451             if (!expressionType.isAssignableFrom(method.getReturnType())) { // Issue 71220
452
buf.append('(').append(expressionType.getName()).append(')');
453             }
454             buf.append(factoryClass.getName()); // NOI18N
455
buf.append("."); // NOI18N
456
buf.append(method.getName());
457             buf.append("("); // NOI18N
458

459
460             for (int i=0; i < properties.length; i++) {
461                 
462                 String JavaDoc name = properties[i].getPropertyName();
463                 FormProperty prop = CreationFactory.findProperty(name, props);
464                 
465                 if (prop == null)
466                     return null; // should not happen
467

468                     buf.append(properties[i].getJavaParametersString(prop));
469
470                 if (i+1 < properties.length)
471                     buf.append(", "); // NOI18N
472
}
473
474             buf.append(")"); // NOI18N
475
return buf.toString();
476         }
477
478         public CodeExpressionOrigin getCodeOrigin(CodeExpression[] params) {
479             // nobody cares ...
480
return null;
481         }
482     }
483
484 }
485
Popular Tags