1 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 29 30 public class CreationDescriptor { 31 32 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 [] getParameterTypes(); 41 42 public Class [] getExceptionTypes(); 43 44 public String [] getPropertyNames(); 45 46 public Object createInstance(FormProperty[] props) 47 throws InstantiationException , IllegalAccessException , 48 IllegalArgumentException , InvocationTargetException; 49 50 public Object createInstance(Object [] paramValues) 51 throws InstantiationException , IllegalAccessException , 52 IllegalArgumentException , InvocationTargetException; 53 54 public String getJavaCreationCode(FormProperty[] props, Class expressionType); 56 57 public CodeExpressionOrigin getCodeOrigin(CodeExpression[] params); 58 } 59 60 private Class describedClass; 61 private ArrayList creators = new ArrayList(10); 62 private Object [] defaultParams; 63 private Creator defaultCreator; 64 65 private static final Class [] emptyTypes = { }; 66 private static final String [] emptyNames = { }; 67 private static final Object [] emptyParams = { }; 68 69 public CreationDescriptor() { 70 } 71 72 public CreationDescriptor(Class descClass, 73 Class [][] constrParamTypes, 74 String [][] constrPropNames, 75 Object [] defParams) 76 throws NoSuchMethodException , IllegalArgumentException 78 { 79 addConstructorCreators(descClass, constrParamTypes, constrPropNames, defParams); 80 } 81 82 public CreationDescriptor(Class factoryClass, 83 Class descClass, 84 String methodName, 85 Class [][] constrParamTypes, 86 String [][] constrPropNames, 87 CreationFactory.PropertyParameters[] propertyParameters, 88 Object [] defParams) 89 throws NoSuchMethodException , IllegalArgumentException 91 { 92 addMethodCreators(factoryClass, descClass, methodName, constrParamTypes, 93 constrPropNames, propertyParameters, defParams); 94 } 95 96 public void addConstructorCreators(Class descClass, 97 Class [][] constrParamTypes, 98 String [][] constrPropNames, 99 Object [] defParams) 100 throws NoSuchMethodException { 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 factoryClass, 115 Class descClass, 116 String methodName, 117 Class [][] constrParamTypes, 118 String [][] constrPropNames, 119 CreationFactory.PropertyParameters[] propertyParameters, 120 Object [] defParams) 121 throws NoSuchMethodException { 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 descClass) throws IllegalArgumentException { 155 if(describedClass==null){ 156 describedClass = descClass; 157 } else if (describedClass!=descClass) { 158 throw new IllegalArgumentException (); 159 } 160 } 161 162 public CreationDescriptor(Class descClass) { 163 describedClass = descClass; 165 166 try { 167 ConstructorCreator creator = new ConstructorCreator(describedClass, 168 emptyTypes, 169 emptyNames); 170 creators.add( creator ); 171 } 172 catch (NoSuchMethodException ex) { if (Boolean.getBoolean("netbeans.debug.exceptions")) { System.out.println("[WARNING] No default constructor for "+descClass.getName()); ex.printStackTrace(); 176 } 177 } 178 179 defaultParams = emptyParams; 180 } 181 182 184 public Class 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 createDefaultInstance() throws InstantiationException , 205 IllegalAccessException , 206 IllegalArgumentException , 207 InvocationTargetException, 208 NoSuchMethodException 209 { 210 return getDefaultCreator().createInstance(defaultParams); 211 } 212 213 private Creator getDefaultCreator() throws NoSuchMethodException { 214 if( defaultCreator == null ) { 215 defaultCreator = findDefaultCreator(); 216 } 217 return defaultCreator; 218 } 219 221 private Creator findDefaultCreator() throws NoSuchMethodException { 223 for (Iterator it = creators.iterator(); it.hasNext();) { 224 225 Creator creator = (Creator) it.next(); 226 Class [] paramTypes = creator.getParameterTypes(); 227 228 if (paramTypes.length == defaultParams.length) { 229 int ii; 230 for (ii=0; ii < paramTypes.length; ii++) { 231 Class cls = paramTypes[ii]; 232 Object param = defaultParams[ii]; 233 234 if (cls.isPrimitive()) { 235 if (param == null 236 || (param instanceof Integer && cls != Integer.TYPE) 237 || (param instanceof Boolean && cls != Boolean.TYPE) 238 || (param instanceof Double && cls != Double.TYPE) 239 || (param instanceof Long && cls != Long.TYPE) 240 || (param instanceof Float && cls != Float.TYPE) 241 || (param instanceof Short && cls != Short.TYPE) 242 || (param instanceof Byte && cls != Byte.TYPE) 243 || (param instanceof Character && 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 (); 255 } 256 257 259 static class ConstructorCreator implements Creator { 260 private Class theClass; 261 private Constructor constructor; 262 private String [] constructorPropNames; 264 265 ConstructorCreator(Class cls, Class [] paramTypes, String [] propNames) 266 throws NoSuchMethodException 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 (); 274 275 constructor = cls.getConstructor(paramTypes); 276 theClass = cls; 277 constructorPropNames = propNames; 279 } 280 281 public final int getParameterCount() { 282 return constructorPropNames.length; } 284 285 public final Class [] getParameterTypes() { 286 return constructor.getParameterTypes(); } 288 289 public final Class [] getExceptionTypes() { 290 return constructor.getExceptionTypes(); 291 } 292 293 public final String [] getPropertyNames() { 294 return constructorPropNames; 295 } 296 297 public Object createInstance(FormProperty[] props) 298 throws InstantiationException , IllegalAccessException , 299 IllegalArgumentException , InvocationTargetException 300 { 301 Object [] paramValues = new Object [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; 310 paramValues[i] = prop.getRealValue(); 311 } 312 } 313 catch (Exception ex) { 314 if (Boolean.getBoolean("netbeans.debug.exceptions")) ex.printStackTrace(); 316 throw new InstantiationException (ex.getMessage()); 317 } 318 319 return constructor.newInstance(paramValues); 320 } 321 322 public Object createInstance(Object [] paramValues) 323 throws InstantiationException , IllegalAccessException , 324 IllegalArgumentException , InvocationTargetException 325 { 326 return constructor.newInstance(paramValues); 327 } 328 329 public String getJavaCreationCode(FormProperty[] props, Class expressionType) { 330 StringBuffer buf = new StringBuffer (); 331 buf.append("new "); buf.append(theClass.getName().replace('$', '.')); 333 buf.append("("); 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; 341 buf.append(prop.getJavaInitializationString()); 342 if (i+1 < constructorPropNames.length) 343 buf.append(", "); } 345 346 buf.append(")"); 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 factoryClass; 357 private Class describedClass; 358 private Method method; 359 private CreationFactory.Property2ParametersMapper[] properties; 360 private String [] propertyNames; 361 362 MethodCreator(Class factoryClass, Class describedClass, String methodName, CreationFactory.Property2ParametersMapper[] properties) 363 throws NoSuchMethodException 364 { 365 366 ArrayList paramTypesList = new ArrayList(); 367 propertyNames = new String [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 [] paramTypes = (Class []) paramTypesList.toArray(new Class [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 [] getParameterTypes() { 392 return method.getParameterTypes(); 393 } 394 395 public final Class [] getExceptionTypes() { 396 return method.getExceptionTypes(); 397 } 398 399 public final String [] getPropertyNames() { 400 return propertyNames; 401 } 402 403 public Object createInstance(FormProperty[] props) 404 throws InstantiationException , IllegalAccessException , 405 IllegalArgumentException , 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; 415 Object [] 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 ex) { 422 if (Boolean.getBoolean("netbeans.debug.exceptions")) ex.printStackTrace(); 424 throw new InstantiationException (ex.getMessage()); 425 } 426 427 Object [] paramValues = paramValuesList.toArray(new Object [paramValuesList.size()]); 428 429 Object ret = method.invoke(null, paramValues); 430 if(ret.getClass() != describedClass) { 431 throw new IllegalArgumentException (); 432 } 433 return ret; 434 } 435 436 public Object createInstance(Object [] paramValues) 437 throws InstantiationException , IllegalAccessException , 438 IllegalArgumentException , InvocationTargetException 439 { 440 441 Object ret = method.invoke(null, paramValues); 442 if(ret.getClass() != describedClass) { 443 throw new IllegalArgumentException (); 444 } 445 return ret; 446 } 447 448 public String getJavaCreationCode(FormProperty[] props, Class expressionType) { 449 StringBuffer buf = new StringBuffer (); 450 if (expressionType == null) expressionType = describedClass; 451 if (!expressionType.isAssignableFrom(method.getReturnType())) { buf.append('(').append(expressionType.getName()).append(')'); 453 } 454 buf.append(factoryClass.getName()); buf.append("."); buf.append(method.getName()); 457 buf.append("("); 459 460 for (int i=0; i < properties.length; i++) { 461 462 String name = properties[i].getPropertyName(); 463 FormProperty prop = CreationFactory.findProperty(name, props); 464 465 if (prop == null) 466 return null; 468 buf.append(properties[i].getJavaParametersString(prop)); 469 470 if (i+1 < properties.length) 471 buf.append(", "); } 473 474 buf.append(")"); return buf.toString(); 476 } 477 478 public CodeExpressionOrigin getCodeOrigin(CodeExpression[] params) { 479 return null; 481 } 482 } 483 484 } 485 | Popular Tags |