1 package org.oddjob; 2 3 4 import java.io.File ; 5 import java.io.IOException ; 6 import java.io.InputStream ; 7 import java.io.ObjectInputStream ; 8 import java.io.ObjectOutputStream ; 9 10 import org.oddjob.arooa.ArooaClassLoader; 11 import org.oddjob.arooa.ArooaConstants; 12 import org.oddjob.arooa.ArooaContext; 13 import org.oddjob.arooa.ArooaFactory; 14 import org.oddjob.arooa.ArooaHandler; 15 import org.oddjob.arooa.ArooaRuntime; 16 import org.oddjob.arooa.Lifecycle; 17 import org.oddjob.arooa.Location; 18 import org.oddjob.arooa.ObjectFactory; 19 import org.oddjob.arooa.PropertyProxyResolver; 20 import org.oddjob.arooa.SimpleObjectFactory; 21 import org.oddjob.arooa.handlers.AttributeHelper; 22 import org.oddjob.arooa.handlers.DefaultComponentHandler; 23 import org.oddjob.arooa.handlers.SerializedComponentHandler; 24 import org.oddjob.arooa.reflect.IntrospectionHelper; 25 import org.oddjob.arooa.registry.ComponentRegistry; 26 import org.oddjob.arooa.registry.Path; 27 import org.oddjob.framework.BeanUtilsProvider; 28 import org.oddjob.framework.OddjobComponentResolver; 29 import org.oddjob.framework.StructuralJob; 30 import org.oddjob.logging.ConsoleArchive; 31 import org.oddjob.logging.ConsoleArchiveImpl; 32 import org.oddjob.logging.LogLevel; 33 import org.oddjob.logging.LoggingPrintStream; 34 import org.oddjob.persist.ComponentPersister; 35 import org.oddjob.util.OddjobConfigException; 36 import org.xml.sax.Attributes ; 37 import org.xml.sax.SAXParseException ; 38 39 115 116 public class Oddjob extends StructuralJob 117 implements Structural, Stoppable { 118 private static final long serialVersionUID = 20020506; 119 120 public static final String JOB_PROPERTIES = "/org/oddjob/oddjob.properties"; 121 public static final String CONVERTER_PROPERTIES = "/org/oddjob/converter.properties"; 122 public static final String PROXY_PROPERTIES = "/org/oddjob/values/proxies.properties"; 123 public static final String TYPE_PROPERTIES = "/org/oddjob/values/types.properties"; 124 125 public static final ConsoleArchive CONSOLE; 126 127 static { 128 ConsoleArchiveImpl console = new ConsoleArchiveImpl(); 129 System.setOut(new LoggingPrintStream(System.out, LogLevel.INFO, 130 console.consoleLog())); 131 System.setErr(new LoggingPrintStream(System.err, LogLevel.ERROR, 132 console.consoleLog())); 133 CONSOLE = console; 134 } 135 136 141 private transient File file; 142 143 149 private transient ComponentPersister persister; 150 151 152 159 private transient String substitution; 160 161 164 private transient ComponentRegistry componentRegistry; 165 private transient ComponentRegistry parentRegistry; 166 167 173 private transient Object [] args; 174 175 176 private transient InputStream input; 177 178 179 private transient ClassLoader classLoader; 180 181 188 private transient File [] classpath; 189 190 198 private transient boolean loadOnly; 199 200 201 private transient SimpleObjectFactory componentFactory; 202 203 204 private transient SimpleObjectFactory valueFactory; 205 206 207 private transient PropertyProxyResolver propertyProxyResolver; 208 209 212 private ArooaContext loadContext; 213 214 219 public void setFile(File file) { 220 this.file = file; 221 } 222 223 231 public File getFile() { 232 if (file == null) { 233 return null; 234 } 235 return file.getAbsoluteFile(); 236 } 237 238 246 public File getDir() { 247 if (file == null) { 248 return null; 249 } 250 return file.getAbsoluteFile().getParentFile(); 251 } 252 253 public void setConfig(File file) { 254 logger().warn("config is depricated use the file attribute instead."); 255 setFile(file); 256 } 257 258 263 public void setInput(InputStream inputStream) { 264 this.input = inputStream; 265 } 266 267 272 public void setClassLoader(ClassLoader classLoader) { 273 this.classLoader = classLoader; 274 } 275 276 282 public ClassLoader getClassLoader() { 283 return this.classLoader; 284 } 285 286 291 public void setClasspath(File [] files) { 292 this.classpath = files; 293 } 294 295 300 public void getClasspath(File [] files) { 301 this.classpath = files; 302 } 303 304 307 public String getSubstitution() { 308 return substitution; 309 } 310 313 public void setSubstitution(String substitution) { 314 this.substitution = substitution.toUpperCase(); 315 } 316 317 323 public void setComponentType(String name, String className) { 324 getComponentFactory().set(name, className); 325 } 326 327 333 public void setValueType(String name, String className) { 334 getValueFactory().set(name, className); 335 } 336 337 343 public void setPropertyProxy(String name, String className) { 344 getPropertyProxyResolver().setProxy(name, className); 345 } 346 347 351 public boolean setContext(ArooaContext context) { 352 ObjectFactory componentFactory = (ObjectFactory) context.get(ArooaConstants.COMPONENT_FACTORY); 355 if (componentFactory != null) { 356 this.componentFactory = new SimpleObjectFactory(componentFactory); 357 } 358 ObjectFactory valueFactory = (ObjectFactory) context.get(ArooaConstants.VALUE_FACTORY); 359 if (valueFactory != null) { 360 this.valueFactory = new SimpleObjectFactory(valueFactory); 361 } 362 PropertyProxyResolver propertyProxyResolver = 363 (PropertyProxyResolver) context.get(ArooaConstants.PROPERTY_PROXY_RESOLVER); 364 if (propertyProxyResolver != null) { 365 this.propertyProxyResolver = new PropertyProxyResolver(propertyProxyResolver); 366 } 367 parentRegistry = (ComponentRegistry) context.get( 369 ArooaConstants.COMPONENT_REGISTRY); 370 return super.setContext(context); 371 } 372 373 private SimpleObjectFactory getComponentFactory() { 374 if (componentFactory == null) { 375 componentFactory = new SimpleObjectFactory(); 376 componentFactory.addResource(JOB_PROPERTIES); 377 } 378 return componentFactory; 379 } 380 381 private SimpleObjectFactory getValueFactory() { 382 if (valueFactory == null) { 383 valueFactory = new SimpleObjectFactory(); 384 valueFactory.addResource(TYPE_PROPERTIES); 385 } 386 return valueFactory; 387 } 388 389 private PropertyProxyResolver getPropertyProxyResolver() { 390 if (propertyProxyResolver == null) { 391 propertyProxyResolver = new PropertyProxyResolver(); 392 propertyProxyResolver.addResource(PROXY_PROPERTIES); 393 } 394 return propertyProxyResolver; 395 } 396 397 400 protected void load() { 401 lock.accquire("Oddjob loading."); 402 try { 403 logger().debug("Loading oddjob."); 404 405 ArooaHandler componentHandler = new DefaultComponentHandler(); 406 if (persister != null) { 407 componentHandler = new SerializedComponentHandler( 408 componentHandler, persister); 409 } 410 411 ArooaFactory af = new ArooaFactory(); 412 componentRegistry = af.getComponentRegistry(); 413 if (parentRegistry != null) { 415 parentRegistry.addChild(componentRegistry, this); 416 } 417 if (persister != null) { 418 if (persister.getRoot() == null) { 419 persister.setRoot(this); 420 } 421 persister.initialise(componentRegistry); 422 } 423 424 425 af.setComponentFactory(getComponentFactory()); 426 af.setValueFactory(getValueFactory()); 427 af.setPropertProxyResolver(getPropertyProxyResolver()); 428 af.setComponentProxyResolver(new OddjobComponentResolver()); 429 af.setComponentHandler(componentHandler); 430 af.setBeanUtilsBean(BeanUtilsProvider.beanFor(CONVERTER_PROPERTIES)); 431 af.setSubstitutionPolicy(this.getSubstitution()); 432 af.setDocumentStartHandler(new OddjobHandler(new Root())); 433 af.setDocumentTag("oddjob"); 434 435 if (file != null) { 436 af.build(file); 437 } 438 else if (input != null) { 439 af.build(input); 440 } else { 441 throw new OddjobException("No input specified."); 442 } 443 } 444 finally { 445 lock.release(); 446 } 447 } 448 449 453 protected void execute() { 454 if (childHelper.getChild() != null) { 455 throw new OddjobException("Oddjob already loaded - reset first!"); 456 } 457 ClassLoader existing = Thread.currentThread().getContextClassLoader(); 458 if (classpath != null) { 459 classLoader = new ArooaClassLoader(existing, classpath, false); 460 } 461 if (classLoader != null) { 462 Thread.currentThread().setContextClassLoader(classLoader); 463 } else { 464 classLoader = existing; 465 } 466 try { 467 load(); 469 470 Object child = childHelper.getChild(); 471 472 if (!loadOnly && child != null && child instanceof Runnable ) { 474 ((Runnable ) child).run(); 475 } 476 childHelper.initialise(); 479 480 } 481 finally { 482 Thread.currentThread().setContextClassLoader(existing); 483 } 484 } 485 486 490 private void reset() { 491 if (persister != null) { 494 try { 495 persister.close(); 496 } catch (Exception e) { 497 logger().warn("Failed closeing persister.", e); 498 } 499 } 500 if (parentRegistry != null) { 505 parentRegistry.removeChild(this); 506 } 507 childHelper.destroyAll(); 509 510 } 511 512 public void onDestroy() { 513 reset(); 514 } 515 516 520 public void softReset() { 521 lock.accquire("Soft reset in progress."); 522 try { 523 logger().debug("Thread [" + Thread.currentThread().getName() 524 + "] soft reset for [" + getName() 525 + "] current state " + stateHandler.getJobState()); 526 if (canSoftReset()) { 527 reset(); 528 } 529 } 530 finally { 531 lock.release(); 532 } 533 } 534 535 539 public void hardReset() { 540 lock.accquire("Hard reset in progress."); 541 try { 542 logger().debug("Thread [" + Thread.currentThread().getName() 543 + "] hard reset for [" + getName() 544 + "] current state " + stateHandler.getJobState()); 545 if (canHardReset()) { 546 reset(); 547 } 548 } 549 finally { 550 lock.release(); 551 } 552 } 553 554 557 public ComponentPersister getPersister() { 558 return persister; 559 } 560 561 564 public void setPersister(ComponentPersister persister) { 565 this.persister = persister; 566 } 567 568 574 public Object lookup(String path) { 575 if (componentRegistry == null) { 576 return null; 577 } 578 return componentRegistry.objectForPath( 579 new Path(path)); 580 } 581 582 585 private void writeObject(ObjectOutputStream s) 586 throws IOException { 587 s.defaultWriteObject(); 588 } 589 590 593 private void readObject(ObjectInputStream s) 594 throws IOException , ClassNotFoundException { 595 s.defaultReadObject(); 596 } 597 598 601 public boolean isLoadOnly() { 602 return loadOnly; 603 } 604 605 610 public void setLoadOnly(boolean loadOnly) { 611 this.loadOnly = loadOnly; 612 } 613 614 617 public Object [] getArgs() { 618 return args; 619 } 620 621 627 public Object getArgs(int index) { 628 if (args == null) { 629 return null; 630 } 631 if (index < args.length) { 632 return args[index]; 633 } 634 return null; 635 } 636 637 640 public void setArgs(Object [] args) { 641 this.args = args; 642 } 643 644 650 public void setArgs(int index, Object arg) { 651 if (this.args == null) { 652 this.args = new Object [index + 1]; 653 } 654 else if (index >= args.length) { 655 Object [] next = new Object [index + 1]; 656 System.arraycopy(this.args, 0, next, 0, args.length); 657 this.args = next; 658 } 659 this.args[index] = arg; 660 } 661 662 669 public ArooaContext loadContext() { 670 return loadContext; 671 } 672 673 678 public String getVersion() { 679 return "@version@"; 680 } 681 682 686 public class Root { 687 public void addComponent(Object child) { 688 logger().debug("Adding child [" + child + "]"); 689 if (Oddjob.this.childHelper.getChild() != null) { 690 throw new OddjobConfigException( 691 "Oddjob can't have more than one child component."); 692 } 693 childHelper.addChild(child); 694 } 695 } 696 697 701 public class OddjobHandler extends ArooaHandler { 702 703 704 private final Root rootComponent; 705 706 709 public OddjobHandler(Root rootObject) { 710 this.rootComponent = rootObject; 711 } 712 713 716 public void onStartElement(String uri, String name, String qname, 717 Attributes attrs, 718 ArooaContext context) 719 throws SAXParseException { 720 loadContext = context.getParent(); 721 AttributeHelper ah = new AttributeHelper(uri, attrs); 722 final ComponentRegistry cr = (ComponentRegistry) 723 context.get(ArooaConstants.COMPONENT_REGISTRY); 724 ah.process(new AttributeHelper.Processor() { 725 728 public void process(String name, String value) { 729 if (name.equals("id") ) { 730 cr.register(value, Oddjob.this); 731 } 732 } 733 }); 734 735 ArooaRuntime wrapper = new ArooaRuntime(rootComponent, name, context); 736 context.set(ArooaConstants.CURRENTLY_CONFIGURING, wrapper); 737 context.getParent().set(ArooaConstants.CURRENTLY_CONFIGURING, wrapper); 739 740 Location location = getLocation(); 741 if (location == null) { 742 Lifecycle.setContext(Oddjob.this, context); 744 } 745 } 746 747 750 public ArooaHandler onStartChild(String uri, String name, String qname, 751 Attributes attrs, 752 ArooaContext context) 753 throws SAXParseException { 754 IntrospectionHelper ih = IntrospectionHelper.getHelper(rootComponent.getClass()); 755 return ih.provideHandler(rootComponent, name, context); 756 } 757 758 } 759 } 760 761 | Popular Tags |