1 17 18 package org.apache.geronimo.gbean.runtime; 19 20 import java.lang.reflect.Method ; 21 22 import org.apache.geronimo.gbean.DynamicGAttributeInfo; 23 import org.apache.geronimo.gbean.DynamicGBean; 24 import org.apache.geronimo.gbean.GAttributeInfo; 25 import org.apache.geronimo.gbean.InvalidConfigurationException; 26 import org.apache.geronimo.kernel.ClassLoading; 27 28 31 public class GBeanAttribute { 32 private final GBeanInstance gbeanInstance; 33 34 private final String name; 35 36 private final Class type; 37 38 private final boolean readable; 39 40 private final MethodInvoker getInvoker; 41 42 private final boolean writable; 43 44 private final MethodInvoker setInvoker; 45 46 private final boolean isConstructorArg; 47 48 private final boolean persistent; 49 50 private final boolean manageable; 51 52 private Object persistentValue; 53 54 59 private final boolean special; 60 61 private final boolean framework; 62 63 private final boolean dynamic; 64 65 private final GAttributeInfo attributeInfo; 66 67 static GBeanAttribute createSpecialAttribute(GBeanAttribute attribute, GBeanInstance gbeanInstance, String name, Class type, Object value) { 68 return new GBeanAttribute(attribute, gbeanInstance, name, type, value); 69 } 70 71 private GBeanAttribute(GBeanAttribute attribute, GBeanInstance gbeanInstance, String name, Class type, Object value) { 72 this.special = true; 73 this.framework = false; 74 this.dynamic = false; 75 76 if (gbeanInstance == null || name == null || type == null) { 77 throw new IllegalArgumentException ("null param(s) supplied"); 78 } 79 80 if (attribute != null) { 82 assert (gbeanInstance == attribute.gbeanInstance); 83 assert (name.equals(attribute.name)); 84 if (type != attribute.type) { 85 throw new InvalidConfigurationException("Special attribute " + name + 86 " must have the type " + type.getName() + ", but is " + 87 attribute.type.getName() + ": targetClass=" + gbeanInstance.getType().getName()); 88 } 89 if (attribute.isPersistent()) { 90 throw new InvalidConfigurationException("Special attributes must not be persistent:" + 91 " name=" + name + ", targetClass=" + gbeanInstance.getType().getName()); 92 } 93 } 94 95 this.gbeanInstance = gbeanInstance; 96 this.name = name; 97 this.type = type; 98 99 this.getInvoker = null; 101 this.readable = true; 102 103 if (attribute != null) { 105 this.setInvoker = attribute.setInvoker; 106 this.isConstructorArg = attribute.isConstructorArg; 107 } else { 108 this.setInvoker = null; 109 this.isConstructorArg = false; 110 } 111 this.writable = false; 112 113 this.persistent = false; 115 initializePersistentValue(value); 116 117 this.manageable = false; 119 120 if (attribute != null) { 122 GAttributeInfo attributeInfo = attribute.getAttributeInfo(); 123 this.attributeInfo = new GAttributeInfo(this.name, 124 this.type.getName(), 125 this.persistent, 126 this.manageable, 127 this.readable, 128 this.writable, 129 attributeInfo.getGetterName(), 130 attributeInfo.getSetterName()); 131 } else { 132 this.attributeInfo = new GAttributeInfo(this.name, 133 this.type.getName(), 134 this.persistent, 135 this.manageable, 136 this.readable, 137 this.writable, 138 null, 139 null); 140 } 141 } 142 143 static GBeanAttribute createFrameworkAttribute(GBeanInstance gbeanInstance, String name, Class type, MethodInvoker getInvoker) { 144 return new GBeanAttribute(gbeanInstance, name, type, getInvoker, null, false, null, true); 145 } 146 147 static GBeanAttribute createFrameworkAttribute(GBeanInstance gbeanInstance, String name, Class type, MethodInvoker getInvoker, MethodInvoker setInvoker, boolean persistent, Object persistentValue, boolean manageable) { 148 return new GBeanAttribute(gbeanInstance, name, type, getInvoker, setInvoker, persistent, persistentValue, manageable); 149 } 150 151 private GBeanAttribute(GBeanInstance gbeanInstance, String name, Class type, MethodInvoker getInvoker, MethodInvoker setInvoker, boolean persistent, Object persistentValue, boolean manageable) { 152 this.special = false; 153 this.framework = true; 154 this.dynamic = false; 155 156 if (gbeanInstance == null || name == null || type == null) { 157 throw new IllegalArgumentException ("null param(s) supplied"); 158 } 159 160 this.gbeanInstance = gbeanInstance; 161 this.name = name; 162 this.type = type; 163 164 this.getInvoker = getInvoker; 166 this.readable = (this.getInvoker != null); 167 168 this.setInvoker = setInvoker; 170 this.isConstructorArg = false; 171 this.writable = (this.setInvoker != null); 172 173 this.persistent = persistent; 175 initializePersistentValue(persistentValue); 176 177 this.manageable = manageable; 179 180 attributeInfo = new GAttributeInfo(this.name, 182 this.type.getName(), 183 this.persistent, 184 this.manageable, 185 this.readable, 186 this.writable, 187 null, 188 null); 189 } 190 191 public GBeanAttribute(GBeanInstance gbeanInstance, GAttributeInfo attributeInfo, boolean isConstructorArg) throws InvalidConfigurationException { 192 this.special = false; 193 this.framework = false; 194 195 if (gbeanInstance == null || attributeInfo == null) { 196 throw new IllegalArgumentException ("null param(s) supplied"); 197 } 198 if (!attributeInfo.isReadable() && !attributeInfo.isWritable() && !attributeInfo.isPersistent() && !isConstructorArg) 199 { 200 throw new InvalidConfigurationException("An attribute must be readable, writable, persistent or a constructor arg: " + 201 " name=" + attributeInfo.getName() + " targetClass=" + gbeanInstance.getType().getName()); 202 } 203 this.gbeanInstance = gbeanInstance; 204 this.attributeInfo = attributeInfo; 205 this.name = attributeInfo.getName(); 206 this.isConstructorArg = isConstructorArg; 207 try { 208 this.type = ClassLoading.loadClass(attributeInfo.getType(), gbeanInstance.getClassLoader()); 209 } catch (ClassNotFoundException e) { 210 throw new InvalidConfigurationException("Could not load attribute class: " + attributeInfo.getType()); 211 } 212 this.persistent = attributeInfo.isPersistent(); 213 this.manageable = attributeInfo.isManageable(); 214 215 readable = attributeInfo.isReadable(); 216 writable = attributeInfo.isWritable(); 217 218 if (attributeInfo instanceof DynamicGAttributeInfo) { 221 this.dynamic = true; 222 if (readable) { 223 getInvoker = new DynamicGetterMethodInvoker(name); 224 } else { 225 getInvoker = null; 226 } 227 if (writable) { 228 setInvoker = new DynamicSetterMethodInvoker(name); 229 } else { 230 setInvoker = null; 231 } 232 } else { 233 this.dynamic = false; 234 if (attributeInfo.getGetterName() != null) { 235 try { 236 String getterName = attributeInfo.getGetterName(); 237 Method getterMethod = gbeanInstance.getType().getMethod(getterName, null); 238 239 if (!getterMethod.getReturnType().equals(type)) { 240 if (getterMethod.getReturnType().getName().equals(type.getName())) { 241 throw new InvalidConfigurationException("Getter return type in wrong classloader: type: " + type + " wanted in classloader: " + type.getClassLoader() + " actual: " + getterMethod.getReturnType().getClassLoader()); 242 } else { 243 throw new InvalidConfigurationException("Getter method of wrong type: " + getterMethod.getReturnType() + " expected " + getDescription()); 244 } 245 } 246 if (AbstractGBeanReference.NO_PROXY) { 247 getInvoker = new ReflectionMethodInvoker(getterMethod); 248 } else { 249 getInvoker = new FastMethodInvoker(getterMethod); 250 } 251 } catch (NoSuchMethodException e) { 252 throw new InvalidConfigurationException("Getter method not found " + getDescription()); 253 } 254 } else { 255 getInvoker = null; 256 } 257 258 if (attributeInfo.getSetterName() != null) { 261 try { 262 String setterName = attributeInfo.getSetterName(); 263 Method setterMethod = gbeanInstance.getType().getMethod(setterName, new Class []{type}); 264 if (AbstractGBeanReference.NO_PROXY) { 265 setInvoker = new ReflectionMethodInvoker(setterMethod); 266 } else { 267 setInvoker = new FastMethodInvoker(setterMethod); 268 } 269 } catch (NoSuchMethodException e) { 270 throw new InvalidConfigurationException("Setter method not found " + getDescription()); 271 } 272 } else { 273 setInvoker = null; 274 } 275 } 276 277 initializePersistentValue(null); 278 } 279 280 private void initializePersistentValue(Object value) { 281 if (persistent || special) { 282 if (value == null && type.isPrimitive() && isConstructorArg) { 283 if (type == Boolean.TYPE) { 284 value = Boolean.FALSE; 285 } else if (type == Byte.TYPE) { 286 value = new Byte ((byte) 0); 287 } else if (type == Short.TYPE) { 288 value = new Short ((short) 0); 289 } else if (type == Integer.TYPE) { 290 value = new Integer (0); 291 } else if (type == Long.TYPE) { 292 value = new Long (0); 293 } else if (type == Character.TYPE) { 294 value = new Character ((char) 0); 295 } else if (type == Float.TYPE) { 296 value = new Float (0); 297 } else { 298 value = new Double (0); 299 } 300 } 301 persistentValue = value; 302 } 303 } 304 305 public String getName() { 306 return name; 307 } 308 309 public GAttributeInfo getAttributeInfo() { 310 return attributeInfo; 311 } 312 313 public boolean isReadable() { 314 return readable; 315 } 316 317 public boolean isWritable() { 318 return writable; 319 } 320 321 public Class getType() { 322 return type; 323 } 324 325 public boolean isFramework() { 326 return framework; 327 } 328 329 public boolean isDynamic() { 330 return dynamic; 331 } 332 333 public boolean isPersistent() { 334 return persistent; 335 } 336 337 public boolean isManageable() { 338 return manageable; 339 } 340 341 public boolean isSpecial() { 342 return special; 343 } 344 345 public void inject(Object target) throws Exception { 346 if ((persistent || special) && !isConstructorArg && writable && persistentValue != null) { 347 setValue(target, persistentValue); 348 } 349 } 350 351 public Object getPersistentValue() { 352 if (!persistent && !special) { 353 throw new IllegalStateException ("Attribute is not persistent " + getDescription()); 354 } 355 return persistentValue; 356 } 357 358 public void setPersistentValue(Object persistentValue) { 359 if (!persistent && !special) { 360 throw new IllegalStateException ("Attribute is not persistent " + getDescription()); 361 } 362 363 if (persistentValue == null && type.isPrimitive()) { 364 throw new IllegalArgumentException ("Cannot assign null to a primitive attribute. " + getDescription()); 365 } 366 367 this.persistentValue = persistentValue; 369 } 370 371 public Object getValue(Object target) throws Exception { 372 if (!readable) { 373 if (persistent) { 374 return persistentValue; 375 } else { 376 throw new IllegalStateException ("This attribute is not readable. " + getDescription()); 377 } 378 } 379 380 if (special) { 381 return persistentValue; 382 } 383 384 if (target == null && !framework) { 386 throw new IllegalStateException ("GBean does not have a target instance to invoke. " + getDescription()); 387 } 388 389 Object value = getInvoker.invoke(target, null); 391 return value; 392 } 393 394 public void setValue(Object target, Object value) throws Exception { 395 if (!writable) { 396 if (persistent) { 397 throw new IllegalStateException ("This persistent attribute is not modifable while the gbean is running. " + getDescription()); 398 } else { 399 throw new IllegalStateException ("This attribute is not writable. " + getDescription()); 400 } 401 } 402 403 if (value == null && type.isPrimitive()) { 405 throw new IllegalArgumentException ("Cannot assign null to a primitive attribute. " + getDescription()); 406 } 407 408 410 if (target == null && !framework) { 412 throw new IllegalStateException ("GBean does not have a target instance to invoke. " + getDescription()); 413 } 414 415 setInvoker.invoke(target, new Object []{value}); 417 } 418 419 public String getDescription() { 420 return "Attribute Name: " + getName() + ", Type: " + getType() + ", GBeanInstance: " + gbeanInstance.getName(); 421 } 422 423 private static final class DynamicGetterMethodInvoker implements MethodInvoker { 424 private final String name; 425 426 public DynamicGetterMethodInvoker(String name) { 427 this.name = name; 428 } 429 430 public Object invoke(Object target, Object [] arguments) throws Exception { 431 return ((DynamicGBean) target).getAttribute(name); 432 } 433 } 434 435 private static final class DynamicSetterMethodInvoker implements MethodInvoker { 436 private final String name; 437 438 public DynamicSetterMethodInvoker(String name) { 439 this.name = name; 440 } 441 442 public Object invoke(Object target, Object [] arguments) throws Exception { 443 ((DynamicGBean) target).setAttribute(name, arguments[0]); 444 return null; 445 } 446 } 447 } 448 | Popular Tags |