1 42 43 package org.jfree.xml.util; 44 45 import java.beans.BeanInfo ; 46 import java.beans.IntrospectionException ; 47 import java.beans.Introspector ; 48 import java.beans.PropertyDescriptor ; 49 import java.lang.reflect.Constructor ; 50 import java.lang.reflect.Method ; 51 import java.util.HashMap ; 52 53 57 public final class GenericObjectFactory { 58 59 60 private final ConstructorDefinition[] constructorDefinitions; 61 62 63 private final PropertyDefinition[] propertyDefinitions; 64 65 66 private final LookupDefinition[] lookupDefinitions; 67 68 69 private final AttributeDefinition[] attributeDefinitions; 70 71 72 private final String [] orderedPropertyNames; 73 74 75 private final HashMap propertyInfos; 76 77 78 private final HashMap propertyValues; 79 80 81 private final Class baseClass; 82 83 84 private final String registerName; 85 86 100 public GenericObjectFactory(final Class c, 101 final String registerName, 102 final ConstructorDefinition[] constructors, 103 final PropertyDefinition[] propertyDefinitions, 104 final LookupDefinition[] lookupDefinitions, 105 final AttributeDefinition[] attributeDefinitions, 106 final String [] orderedPropertyNames) 107 throws ObjectDescriptionException { 108 109 if (c == null) { 110 throw new NullPointerException ("BaseClass cannot be null."); 111 } 112 this.baseClass = c; 113 this.registerName = registerName; 114 115 this.propertyInfos = new HashMap (); 116 this.propertyValues = new HashMap (); 117 118 this.constructorDefinitions = constructors; 119 this.propertyDefinitions = propertyDefinitions; 120 this.lookupDefinitions = lookupDefinitions; 121 this.attributeDefinitions = attributeDefinitions; 122 this.orderedPropertyNames = orderedPropertyNames; 123 124 try { 125 final BeanInfo chartBeaninfo = Introspector.getBeanInfo(c, Object .class); 126 final PropertyDescriptor [] pd = chartBeaninfo.getPropertyDescriptors(); 127 for (int i = 0; i < pd.length; i++) { 128 this.propertyInfos.put(pd[i].getName(), pd[i]); 129 } 130 } 131 catch (IntrospectionException ioe) { 132 throw new ObjectDescriptionException( 133 "This is an ugly solution right now ... dirty hack attack" 134 ); 135 } 136 } 137 138 143 private GenericObjectFactory (final GenericObjectFactory factory) { 144 this.baseClass = factory.baseClass; 145 this.propertyValues = new HashMap (); 146 this.orderedPropertyNames = factory.orderedPropertyNames; 147 this.constructorDefinitions = factory.constructorDefinitions; 148 this.propertyDefinitions = factory.propertyDefinitions; 149 this.attributeDefinitions = factory.attributeDefinitions; 150 this.propertyInfos = factory.propertyInfos; 151 this.registerName = factory.registerName; 152 this.lookupDefinitions = factory.lookupDefinitions; 153 } 154 155 160 public GenericObjectFactory getInstance () { 161 return new GenericObjectFactory(this); 162 } 163 164 169 public String getRegisterName() { 170 return this.registerName; 171 } 172 173 180 private PropertyDescriptor getPropertyDescriptor(final String propertyName) { 181 return (PropertyDescriptor ) this.propertyInfos.get(propertyName); 182 } 183 184 193 public Class getTypeForTagName(final String tagName) throws ObjectDescriptionException { 194 final PropertyDefinition pdef = getPropertyDefinitionByTagName(tagName); 195 final PropertyDescriptor pdescr = getPropertyDescriptor(pdef.getPropertyName()); 196 if (pdescr == null) { 197 throw new ObjectDescriptionException("Invalid Definition: " + pdef.getPropertyName()); 198 } 199 return pdescr.getPropertyType(); 200 } 201 202 209 public boolean isPropertyDefinition (final String propertyName) { 210 for (int i = 0; i < this.propertyDefinitions.length; i++) { 211 final PropertyDefinition pdef = this.propertyDefinitions[i]; 212 if (pdef.getPropertyName().equals(propertyName)) { 213 return true; 214 } 215 } 216 return false; 217 } 218 219 228 public PropertyDefinition getPropertyDefinitionByPropertyName(final String propertyName) 229 throws ObjectDescriptionException { 230 for (int i = 0; i < this.propertyDefinitions.length; i++) { 231 final PropertyDefinition pdef = this.propertyDefinitions[i]; 232 if (pdef.getPropertyName().equals(propertyName)) { 233 return pdef; 234 } 235 } 236 throw new ObjectDescriptionException( 237 "This property is not defined for this kind of object. : " + propertyName 238 ); 239 } 240 241 250 public PropertyDefinition getPropertyDefinitionByTagName(final String tagName) 251 throws ObjectDescriptionException { 252 for (int i = 0; i < this.propertyDefinitions.length; i++) { 253 final PropertyDefinition pdef = this.propertyDefinitions[i]; 254 if (pdef.getElementName().equals(tagName)) { 255 return pdef; 256 } 257 } 258 throw new ObjectDescriptionException( 259 "This tag is not defined for this kind of object. : " + tagName 260 ); 261 } 262 263 268 public ConstructorDefinition[] getConstructorDefinitions() { 269 return this.constructorDefinitions; 270 } 271 272 277 public AttributeDefinition[] getAttributeDefinitions() { 278 return this.attributeDefinitions; 279 } 280 281 286 public PropertyDefinition[] getPropertyDefinitions() { 287 return this.propertyDefinitions; 288 } 289 290 295 public String [] getOrderedPropertyNames() { 296 return this.orderedPropertyNames; 297 } 298 299 304 public LookupDefinition[] getLookupDefinitions() { 305 return this.lookupDefinitions; 306 } 307 308 315 public Object getProperty(final String name) { 316 return this.propertyValues.get(name); 317 } 318 319 326 public Object createObject() throws ObjectDescriptionException { 327 final Class [] cArgs = new Class [this.constructorDefinitions.length]; 328 final Object [] oArgs = new Object [this.constructorDefinitions.length]; 329 for (int i = 0; i < cArgs.length; i++) { 330 final ConstructorDefinition cDef = this.constructorDefinitions[i]; 331 cArgs[i] = cDef.getType(); 332 if (cDef.isNull()) { 333 oArgs[i] = null; 334 } 335 else { 336 oArgs[i] = getProperty(cDef.getPropertyName()); 337 } 338 } 339 340 try { 341 final Constructor constr = this.baseClass.getConstructor(cArgs); 342 final Object o = constr.newInstance(oArgs); 343 return o; 344 } 345 catch (Exception e) { 346 throw new ObjectDescriptionException("Ugh! Constructor made a buuuh!", e); 347 } 348 } 349 350 358 public void setProperty(final String propertyName, final Object value) 359 throws ObjectDescriptionException { 360 final PropertyDescriptor pdesc = getPropertyDescriptor(propertyName); 361 if (pdesc == null) { 362 throw new ObjectDescriptionException("Unknown property " + propertyName); 363 } 364 365 if (!isAssignableOrPrimitive(pdesc.getPropertyType(), value.getClass())) { 366 throw new ObjectDescriptionException( 367 "Invalid value: " + pdesc.getPropertyType() + " vs. " + value.getClass() 368 ); 369 } 370 371 this.propertyValues.put(propertyName, value); 372 } 373 374 382 private boolean isAssignableOrPrimitive(final Class baseType, final Class valueType) { 383 if (BasicTypeSupport.isBasicDataType(baseType)) { 384 return true; 385 } 386 return baseType.isAssignableFrom(valueType); 388 } 389 390 397 private boolean isConstructorProperty(final String propertyName) { 398 for (int i = 0; i < this.constructorDefinitions.length; i++) { 399 final ConstructorDefinition cDef = this.constructorDefinitions[i]; 400 if (propertyName.equals(cDef.getPropertyName())) { 401 return true; 402 } 403 } 404 return false; 405 } 406 407 414 public void writeObjectProperties(final Object object) throws ObjectDescriptionException { 415 for (int i = 0; i < this.orderedPropertyNames.length; i++) { 417 try { 418 final String name = this.orderedPropertyNames[i]; 419 if (isConstructorProperty(name)) { 420 continue; 421 } 422 final Object value = getProperty(name); 423 if (value == null) { 424 continue; 426 } 427 final PropertyDescriptor pdescr = getPropertyDescriptor(name); 428 final Method setter = pdescr.getWriteMethod(); 429 setter.invoke(object, new Object []{value}); 430 } 431 catch (Exception e) { 432 throw new ObjectDescriptionException( 433 "Failed to set properties." + getBaseClass(), e 434 ); 435 } 436 } 437 } 438 439 446 public void readProperties(final Object object) throws ObjectDescriptionException { 447 for (int i = 0; i < this.orderedPropertyNames.length; i++) { 449 try { 450 final String name = this.orderedPropertyNames[i]; 451 final PropertyDescriptor pdescr = getPropertyDescriptor(name); 452 if (pdescr == null) { 453 throw new IllegalStateException ("No property defined: " + name); 454 } 455 final Method setter = pdescr.getReadMethod(); 456 final Object value = setter.invoke(object, new Object [0]); 457 if (value == null) { 458 continue; 460 } 461 setProperty(name, value); 462 } 463 catch (Exception e) { 464 throw new ObjectDescriptionException("Failed to set properties.", e); 465 } 466 } 467 } 468 469 474 public Class getBaseClass() { 475 return this.baseClass; 476 } 477 478 } 479 | Popular Tags |