1 58 package org.oddjob.arooa; 59 60 import java.util.ArrayList ; 61 import java.util.Enumeration ; 62 import java.util.EventObject ; 63 import java.util.HashMap ; 64 import java.util.Hashtable ; 65 import java.util.Iterator ; 66 import java.util.LinkedHashMap ; 67 import java.util.List ; 68 import java.util.Map ; 69 import java.util.Vector ; 70 71 import org.apache.commons.beanutils.BeanUtilsBean; 72 import org.apache.log4j.Logger; 73 import org.oddjob.arooa.reflect.BeanUtilsBeanHelper; 74 import org.oddjob.arooa.reflect.DefaultRegistryLookup; 75 import org.oddjob.arooa.reflect.IntrospectionHelper; 76 import org.oddjob.arooa.reflect.RegistryLookup; 77 import org.xml.sax.Locator ; 78 79 80 87 public class ArooaRuntime 88 implements RuntimeConfiguration { 89 private static final Logger logger = Logger.getLogger(ArooaRuntime.class); 90 91 92 private String elementTag = null; 93 94 95 private final Vector children = new Vector (); 96 97 98 private final Map linked = new LinkedHashMap (); 99 100 103 private final Object wrappedObject; 104 105 112 private final List attributeNames = new ArrayList (); 113 114 115 private final Map attributeMap = new LinkedHashMap (); 116 117 class MappedProperty { 118 final String key; 119 final RuntimeConfiguration propertyWrapper; 120 MappedProperty(String key, RuntimeConfiguration propertyWrapper) { 121 this.key = key; 122 this.propertyWrapper = propertyWrapper; 123 } 124 } 125 126 128 private final Map mappedProperties = new HashMap (); 129 130 131 private StringBuffer characters = null; 132 133 135 private boolean configured = false; 136 137 140 private RegistryLookup registry; 141 142 145 private boolean strictSubstituation; 146 147 150 private final Location location; 151 152 155 private final BeanUtilsBeanHelper bubh; 156 157 160 private final ArooaContext context; 161 162 165 private Boolean leaveProxy; 166 167 168 private final List listeners = new ArrayList (); 169 170 171 188 public ArooaRuntime(Object wrappedObject, String elementTag, 189 ArooaContext context) { 190 if (context == null) { 191 throw new NullPointerException ("Context can't be null!"); 192 } 193 this.wrappedObject = wrappedObject; 194 this.elementTag = elementTag; 195 196 this.context = context; 197 registry = new DefaultRegistryLookup(elementTag, context); 198 this.strictSubstituation = (ArooaConstants.SUBPOLICY_STRICT.equals( 199 context.get(ArooaConstants.SUBSTITUTION_POLICY))); 200 BeanUtilsBean bub = (BeanUtilsBean) context.get(ArooaConstants.BEAN_UTILS_BEAN); 201 if (bub == null) { 202 this.bubh = new BeanUtilsBeanHelper(BeanUtilsBean.getInstance()); 203 location = null; 204 } else { 205 Locator locator = context.getLocator(); 206 if (locator != null) { 207 location = new Location(locator.getSystemId(), locator 208 .getLineNumber(), locator.getColumnNumber()); 209 } else { 210 location = null; 211 } 212 this.bubh = new BeanUtilsBeanHelper(bub, elementTag, location); 213 } 214 } 215 216 225 public ArooaRuntime(Object wrappedObject, String elementTag) { 226 this.wrappedObject = wrappedObject; 227 this.elementTag = elementTag; 228 this.context = null; 230 location = null; 231 this.strictSubstituation = false; 232 this.bubh = new BeanUtilsBeanHelper(BeanUtilsBean.getInstance()); 233 234 } 235 241 public Object getWrappedObject() { 242 return wrappedObject; 243 } 244 245 251 public boolean isLeaveProxy() { 252 if (leaveProxy == null) { 253 if (context != null) { 254 leaveProxy = (Boolean ) context.get(ArooaConstants.RTC_LEAVE_PROXY); 255 } 256 } 257 if (leaveProxy == null) { 258 leaveProxy = new Boolean (false); 259 } 260 return leaveProxy.booleanValue(); 261 } 262 263 public void setStrictSubstituation(boolean value) { 264 strictSubstituation = value; 265 } 266 267 public boolean isStrictSubstituation() { 268 return strictSubstituation; 269 } 270 271 278 public void setConfigured(boolean configured) { 279 this.configured = configured; 280 } 281 282 288 public void setAttribute(String name, String value) { 289 if (name == null) { 290 throw new NullPointerException ("Property name can not be null!"); 291 } 292 attributeNames.add(name); 293 PropertyHelper ph = new PropertyHelper(value); 294 attributeMap.put(name, ph); 295 if (ph.isConstant() && !configured) { 297 bubh.setProperty(wrappedObject, name, value); 298 } 299 } 300 301 308 public void setMappedProperty(String name, String key, RuntimeConfiguration rtc) { 309 if (name == null) { 310 throw new NullPointerException ("Property name can not be null!"); 311 } 312 List mps = (List ) mappedProperties.get(name); 313 if (mps == null) { 314 mps = new ArrayList (); 315 mappedProperties.put(name, mps); 316 } 317 mps.add(new MappedProperty(key, rtc)); 318 } 319 320 321 327 public void setAttribute(String name, RuntimeConfiguration rtc) { 328 if (name == null) { 329 throw new NullPointerException ("Property name can not be null!"); 330 } 331 attributeNames.add(name); 332 attributeMap.put(name, rtc); 333 } 334 335 341 public String getAttribute(String name) { 342 if (attributeMap == null) { 343 return null; 344 } 345 Object value = attributeMap.get(name); 346 if (value == null) { 347 return null; 348 } 349 if (! (value instanceof PropertyHelper)) { 350 return null; 351 } 352 return ((PropertyHelper)value).getValue(); 353 } 354 355 359 public Hashtable getAttributeMap() { 360 if (attributeMap != null) { 361 return new Hashtable (attributeMap); 362 } else { 363 return new Hashtable (1); 364 } 365 } 366 367 368 374 public void addChild(RuntimeConfiguration child) { 375 children.add(child); 376 } 377 378 386 RuntimeConfiguration getChild(int index) { 387 return (RuntimeConfiguration) children.get(index); 388 } 389 390 394 public Enumeration getChildren() { 395 return children.elements(); 396 } 397 398 404 public void link(RuntimeConfiguration link) { 405 linked.put(link.getWrappedObject(), link); 406 } 407 408 415 public RuntimeConfiguration unlink(Object linkedComponent) { 416 return (RuntimeConfiguration) linked.remove(linkedComponent); 417 } 418 419 425 public void addText(String data) { 426 if (data.length() == 0) { 427 return; 428 } 429 if (characters != null) { 430 characters.append(data); 431 } else { 432 characters = new StringBuffer (data); 433 } 434 } 435 436 445 public void addText(char[] buf, int start, int count) { 446 if (count == 0) { 447 return; 448 } 449 if (characters == null) { 450 characters = new StringBuffer (count); 451 } 452 characters.append(buf, start, count); 453 } 454 455 461 public StringBuffer getText() { 462 if (characters != null) { 463 return characters; 464 } else { 465 return new StringBuffer (0); 466 } 467 } 468 469 475 public String getElementTag() { 476 return elementTag; 477 } 478 479 484 public void configure() 485 throws ArooaException { 486 if (registry == null) { 487 throw new NullPointerException ("ResgistryLookup must be set"); 488 } else { 489 configure(this.registry, strictSubstituation); 490 } 491 } 492 493 512 513 public void configure(RegistryLookup registry, boolean strictSubstitution) 514 throws ArooaException { 515 for (int i = 0; i < attributeNames.size(); ++i) { 517 String name = (String ) attributeNames.get(i); 518 Object attributeObject = attributeMap.get(name); 519 if (attributeObject instanceof PropertyHelper) { 520 PropertyHelper propHelper = (PropertyHelper) attributeObject; 521 if (!propHelper.isConstant()) { 523 Object newValue = propHelper.replaceProperties(registry, 525 strictSubstitution); 526 logger.debug("Substituted [" + propHelper.getValue() + "] for [" + newValue + "]"); 527 bubh.setProperty(wrappedObject, name, 528 valueFor(name, newValue)); 529 } 530 } else { 531 RuntimeConfiguration attributeRtc = (RuntimeConfiguration) attributeObject; 532 attributeRtc.configure(registry, strictSubstitution); 533 bubh.setProperty(wrappedObject, name, 534 valueFor(name, attributeRtc.getWrappedObject())); 535 } 536 } 537 538 for (Iterator it = mappedProperties.entrySet().iterator(); it.hasNext(); ) { 540 Map.Entry entry = (Map.Entry ) it.next(); 541 String name = (String ) entry.getKey(); 542 List mps = (List ) entry.getValue(); 543 for (Iterator pit = mps.iterator(); pit.hasNext(); ) { 544 MappedProperty mp = (MappedProperty) pit.next(); 545 mp.propertyWrapper.configure(registry, strictSubstitution); 546 Object value = valueFor(name, mp.propertyWrapper.getWrappedObject()); 547 if (mp.key == null) { 548 if (!(value instanceof Map )) { 550 throw new ArooaConfigException( 551 "A mapped property must either have a name or be a Map.", 552 elementTag, location); 553 } 554 Map map = (Map ) value; 555 for (Iterator mit = map.entrySet().iterator(); mit.hasNext(); ) { 556 Map.Entry me = (Map.Entry ) mit.next(); 557 String mk = (String ) me.getKey(); 558 Object mv = me.getValue(); 559 bubh.setMappedProperty(wrappedObject, name, mk, 560 valueFor(name, mv)); 561 } 562 } 563 else { 564 PropertyHelper ph = new PropertyHelper(mp.key); 565 String key = (String ) ph.replaceProperties(registry, 566 strictSubstitution); 567 bubh.setMappedProperty(wrappedObject, name, key, value); 568 } 569 } 570 } 571 572 IntrospectionHelper ih = IntrospectionHelper.getHelper(wrappedObject 573 .getClass()); 574 575 if (characters != null && !configured) { 576 ih.addText(wrappedObject, characters.substring(0)); 577 } 578 579 Enumeration e = getChildren(); 580 while (e.hasMoreElements()) { 581 RuntimeConfiguration child = (RuntimeConfiguration) e.nextElement(); 582 583 child.configure(registry, strictSubstitution); 584 if (!configured) { 586 ih.storeConfiguredElement(wrappedObject, child 587 .getWrappedObject(), child.getElementTag()); 588 } 589 } 590 591 for (Iterator it = linked.values().iterator(); it.hasNext(); ) { 592 RuntimeConfiguration link = (RuntimeConfiguration) it.next(); 593 link.configure(registry, strictSubstitution); 594 } 595 596 configured = true; 597 fireConfigurationComplete(); 598 } 599 600 610 Object valueFor(String name, Object value) { 611 if (value == null) { 612 return null; 613 } 614 Class type = bubh.getPropertyType(wrappedObject, name); 615 if (isLeaveProxy() && type.isAssignableFrom(Object .class)) { 616 return value; 617 } 618 619 return IntrospectionHelper.valueFor(value, type); 620 } 621 622 625 public RegistryLookup getRegistryLookup() { 626 return registry; 627 } 628 629 public void addConfigurationListener(ConfigurationListener l) { 630 listeners.add(l); 631 } 632 633 public void removeConfigurationListener(ConfigurationListener l) { 634 listeners.remove(l); 635 } 636 637 protected void fireConfigurationComplete() { 638 for (Iterator it = listeners.iterator(); it.hasNext();) { 639 ConfigurationListener l = (ConfigurationListener) it.next(); 640 l.configurationComplete(new EventObject (this)); 641 } 642 } 643 644 public String toString() { 645 return "Configured element [" + elementTag + "]: " + configured; 646 } 647 } 648 | Popular Tags |