001/* 002 * jDTAUS Core RI Client Container 003 * Copyright (C) 2005 Christian Schulte 004 * <cs@schulte.it> 005 * 006 * This library is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 2.1 of the License, or any later version. 010 * 011 * This library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with this library; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 019 * 020 */ 021package org.jdtaus.core.container.ri.client; 022 023import java.lang.reflect.Array; 024import java.lang.reflect.Constructor; 025import java.lang.reflect.InvocationTargetException; 026import java.lang.reflect.Method; 027import java.text.MessageFormat; 028import java.util.ArrayList; 029import java.util.List; 030import java.util.Locale; 031import java.util.Map; 032import java.util.logging.Level; 033import java.util.logging.Logger; 034import org.jdtaus.core.container.Container; 035import org.jdtaus.core.container.ContainerError; 036import org.jdtaus.core.container.ContainerInitializer; 037import org.jdtaus.core.container.ContextFactory; 038import org.jdtaus.core.container.ContextInitializer; 039import org.jdtaus.core.container.Dependency; 040import org.jdtaus.core.container.DependencyCycleException; 041import org.jdtaus.core.container.Implementation; 042import org.jdtaus.core.container.MissingImplementationException; 043import org.jdtaus.core.container.Model; 044import org.jdtaus.core.container.ModelFactory; 045import org.jdtaus.core.container.MultiplicityConstraintException; 046import org.jdtaus.core.container.Specification; 047import org.jdtaus.core.container.ri.client.versioning.VersionParser; 048 049/** 050 * {@code Container} reference implementation. 051 * 052 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 053 * @version $JDTAUS: DefaultContainer.java 8743 2012-10-07 03:06:20Z schulte $ 054 * 055 * @see org.jdtaus.core.container.ContainerFactory 056 */ 057public class DefaultContainer implements Container 058{ 059 //--Constants--------------------------------------------------------------- 060 061 /** Empty Class-Array. */ 062 private static final Class[] EMPTY = 063 { 064 }; 065 066 /** Implementation Class-Array. */ 067 private static final Class[] IMPL_CTOR = 068 { 069 Implementation.class 070 }; 071 072 /** Dependency Class-Array. */ 073 private static final Class[] DEP_CTOR = 074 { 075 Dependency.class 076 }; 077 078 /** Array of scope implementations. */ 079 private static final Scope[] SCOPES = 080 { 081 null, new ContextScope(), new SingletonScope() 082 }; 083 084 //---------------------------------------------------------------Constants-- 085 //--Container--------------------------------------------------------------- 086 087 /** Mutex used to detect cyclic instantiations. */ 088 private final Object cycle = new Object(); 089 090 /** Maps objects to model object. */ 091 private final Map objects = new WeakIdentityHashMap( 1024 ); 092 093 public Object getObject( final Class specification ) 094 { 095 if ( specification == null ) 096 { 097 throw new NullPointerException( "specification" ); 098 } 099 100 return this.getObjectInternal( this.getClassLoader( specification ), 101 specification.getName(), null, false ); 102 103 } 104 105 public Object getObject( final Class specification, 106 final String implementationName ) 107 { 108 if ( specification == null ) 109 { 110 throw new NullPointerException( "specification" ); 111 } 112 if ( implementationName == null ) 113 { 114 throw new NullPointerException( "implementationName" ); 115 } 116 117 return this.getObjectInternal( this.getClassLoader( specification ), 118 specification.getName(), 119 implementationName, true ); 120 121 } 122 123 public Object getDependency( final Object object, 124 final String dependencyName ) 125 { 126 if ( object == null ) 127 { 128 throw new NullPointerException( "object" ); 129 } 130 if ( dependencyName == null ) 131 { 132 throw new NullPointerException( "dependencyName" ); 133 } 134 135 try 136 { 137 final Implementation impl = this.getImplementation( object ); 138 final Instance instance = this.getInstance( object, impl ); 139 140 synchronized ( instance ) 141 { 142 return this.getDependency( 143 instance.getClassLoader(), instance, 144 impl.getDependencies().getDependency( dependencyName ) ); 145 146 } 147 } 148 catch ( final ClassNotFoundException e ) 149 { 150 throw new ContainerError( e ); 151 } 152 catch ( final NoSuchMethodException e ) 153 { 154 throw new ContainerError( e ); 155 } 156 catch ( final IllegalAccessException e ) 157 { 158 throw new ContainerError( e ); 159 } 160 catch ( final InvocationTargetException e ) 161 { 162 throw new ContainerError( e ); 163 } 164 } 165 166 public Object getProperty( final Object object, 167 final String propertyName ) 168 { 169 if ( object == null ) 170 { 171 throw new NullPointerException( "object" ); 172 } 173 if ( propertyName == null ) 174 { 175 throw new NullPointerException( "propertyName" ); 176 } 177 178 return this.getInstance( object, this.getImplementation( object ) ). 179 getProperties().getProperty( propertyName ).getValue(); 180 181 } 182 183 public String getMessage( final Object object, final String messageName, 184 final Locale locale, final Object arguments ) 185 { 186 if ( object == null ) 187 { 188 throw new NullPointerException( "object" ); 189 } 190 if ( locale == null ) 191 { 192 throw new NullPointerException( "locale" ); 193 } 194 if ( messageName == null ) 195 { 196 throw new NullPointerException( "messageName" ); 197 } 198 199 return new MessageFormat( 200 this.getInstance( object, this.getImplementation( object ) ). 201 getMessages().getMessage( messageName ).getTemplate(). 202 getValue( locale ), locale ).format( arguments ); 203 204 } 205 206 public final Object getObject( final String specificationIdentifier ) 207 { 208 return this.getObjectInternal( this.getClassLoader( this.getClass() ), 209 specificationIdentifier, null, 210 false ); 211 212 } 213 214 public final Object getObject( final String specificationIdentifier, 215 final String implementationName ) 216 { 217 return this.getObjectInternal( this.getClassLoader( this.getClass() ), 218 specificationIdentifier, 219 implementationName, true ); 220 221 } 222 223 public final String getMessage( final Object object, 224 final String messageName, 225 final Object arguments ) 226 { 227 if ( object == null ) 228 { 229 throw new NullPointerException( "object" ); 230 } 231 if ( messageName == null ) 232 { 233 throw new NullPointerException( "messageName" ); 234 } 235 236 return this.getMessage( object, messageName, Locale.getDefault(), 237 arguments ); 238 239 } 240 241 public final Object getImplementation( 242 final Class specification, final String implementationName ) 243 { 244 if ( specification == null ) 245 { 246 throw new NullPointerException( "specification" ); 247 } 248 if ( implementationName == null ) 249 { 250 throw new NullPointerException( "implementationName" ); 251 } 252 253 return this.getObject( specification, implementationName ); 254 } 255 256 public final Object getDependency( 257 final Class implementation, final String dependencyName ) 258 { 259 if ( implementation == null ) 260 { 261 throw new NullPointerException( "implementation" ); 262 } 263 if ( dependencyName == null ) 264 { 265 throw new NullPointerException( "dependencyName" ); 266 } 267 268 try 269 { 270 final Object dependencyObject = this.getDependency( 271 this.getClassLoader( implementation ), null, 272 ModelFactory.getModel().getModules(). 273 getImplementation( implementation.getName() ). 274 getDependencies().getDependency( dependencyName ) ); 275 276 this.initializeContext( dependencyObject ); 277 return dependencyObject; 278 } 279 catch ( final ClassNotFoundException e ) 280 { 281 throw new ContainerError( e ); 282 } 283 catch ( final NoSuchMethodException e ) 284 { 285 throw new ContainerError( e ); 286 } 287 catch ( final IllegalAccessException e ) 288 { 289 throw new ContainerError( e ); 290 } 291 catch ( final InvocationTargetException e ) 292 { 293 throw new ContainerError( e ); 294 } 295 } 296 297 //---------------------------------------------------------------Container-- 298 //--DefaultContainer-------------------------------------------------------- 299 300 /** Creates a new {@code DefaultContainer} instance. */ 301 public DefaultContainer() 302 { 303 super(); 304 } 305 306 /** 307 * Creates a new instance of an implementation. 308 * <p>The reference implementation loads the class corresponding to the 309 * implementation and creates a new instance of that class by calling the 310 * constructor taking an {@code Implementation} as an argument.</p> 311 * 312 * @param classLoader The classloader to use for loading classes. 313 * @param impl the implementation to return a new instance for. 314 * 315 * @return a new instance of the class corresponding to {@code impl}. 316 * 317 * @throws NullPointerException if {@code classLoader} or {@code impl} is 318 * {@code null}. 319 * @throws org.jdtaus.core.container.InstantiationException 320 * if no instance can be created. 321 * @deprecated Replaced by {@link #instantiateObject(org.jdtaus.core.container.ri.client.Instance) 322 */ 323 private Object instantiateImplementation( final ClassLoader classLoader, 324 final Implementation impl ) 325 { 326 if ( classLoader == null ) 327 { 328 throw new NullPointerException( "classLoader" ); 329 } 330 if ( impl == null ) 331 { 332 throw new NullPointerException( "impl" ); 333 } 334 335 Constructor ctor = null; 336 337 try 338 { 339 final Class clazz = Class.forName( impl.getIdentifier(), true, 340 classLoader ); 341 342 ctor = clazz.getDeclaredConstructor( IMPL_CTOR ); 343 ctor.setAccessible( true ); 344 345 final Object object = ctor.newInstance( new Object[] 346 { 347 impl 348 } ); 349 350 return object; 351 } 352 catch ( final Throwable e ) 353 { 354 throw new org.jdtaus.core.container.InstantiationException( 355 impl.getIdentifier(), e ); 356 357 } 358 finally 359 { 360 if ( ctor != null ) 361 { 362 ctor.setAccessible( false ); 363 } 364 } 365 } 366 367 /** 368 * Creates a new instance of a dependency. 369 * <p>The reference implementation loads the class corresponding to the 370 * dependency and creates a new instance of that class by calling the 371 * constructor taking a {@code Dependency} as an argument.</p> 372 * 373 * @param classLoader The classloader to use for loading classes. 374 * @param dep the dependency to return a new instance for. 375 * 376 * @return a new instance of the class corresponding to {@code dep}. 377 * 378 * @throws NullPointerException if {@code classLoader} or {@code dep} is 379 * {@code null}. 380 * @throws org.jdtaus.core.container.InstantiationException 381 * if no instance can be created. 382 * @deprecated Replaced by {@link #instantiateObject(org.jdtaus.core.container.ri.client.Instance) 383 */ 384 private Object instantiateDependency( final ClassLoader classLoader, 385 final Dependency dep ) 386 { 387 if ( classLoader == null ) 388 { 389 throw new NullPointerException( "classLoader" ); 390 } 391 if ( dep == null ) 392 { 393 throw new NullPointerException( "dep" ); 394 } 395 396 Constructor ctor = null; 397 398 try 399 { 400 final Class clazz = Class.forName( dep.getImplementation(). 401 getIdentifier(), true, classLoader ); 402 403 ctor = clazz.getDeclaredConstructor( DEP_CTOR ); 404 ctor.setAccessible( true ); 405 406 final Object object = ctor.newInstance( new Object[] 407 { 408 dep 409 } ); 410 411 return object; 412 } 413 catch ( final Throwable e ) 414 { 415 throw new org.jdtaus.core.container.InstantiationException( 416 dep.getImplementation().getIdentifier(), e ); 417 418 } 419 finally 420 { 421 if ( ctor != null ) 422 { 423 ctor.setAccessible( false ); 424 } 425 } 426 } 427 428 /** 429 * Performs initialization of an object. 430 * 431 * @param object The object to initialize. 432 * 433 * @throws NullPointerException if {@code object} is {@code null}. 434 * @throws Exception if initialization fails. 435 */ 436 private void initializeObject( final Object object ) throws Exception 437 { 438 if ( object == null ) 439 { 440 throw new NullPointerException( "object" ); 441 } 442 443 if ( object instanceof ContainerInitializer ) 444 { 445 ( (ContainerInitializer) object ).initialize(); 446 } 447 } 448 449 /** 450 * Performs context initialization of an object. 451 * 452 * @param object The object to perform context initialization with. 453 * 454 * @throws NullPointerException if {@code object} is {@code null}. 455 * @throws org.jdtaus.core.container.ContextError for unrecoverable context 456 * errors. 457 */ 458 private void initializeContext( final Object object ) 459 { 460 if ( object == null ) 461 { 462 throw new NullPointerException( "object" ); 463 } 464 465 if ( object instanceof ContextInitializer && 466 !( (ContextInitializer) object ).isInitialized( 467 ContextFactory.getContext() ) ) 468 { 469 ( (ContextInitializer) object ).initialize( 470 ContextFactory.getContext() ); 471 472 } 473 } 474 475 private Object getObjectInternal( final ClassLoader classLoader, 476 final String specificationIdentifier, 477 final String implementationName, 478 final boolean implementationNameWarning ) 479 { 480 if ( classLoader == null ) 481 { 482 throw new NullPointerException( "classLoader" ); 483 } 484 if ( specificationIdentifier == null ) 485 { 486 throw new NullPointerException( "specificationIdentifier" ); 487 } 488 489 try 490 { 491 final Object object; 492 final Specification specification = ModelFactory.getModel(). 493 getModules().getSpecification( specificationIdentifier ); 494 495 if ( implementationName != null ) 496 { 497 final Class specClass = 498 Class.forName( specification.getIdentifier(), true, 499 classLoader ); 500 501 final Implementation implementation = 502 specification.getImplementation( implementationName ); 503 504 final Instance instance = new Instance( 505 classLoader, specification.getScope(), 506 implementation.getIdentifier(), 507 implementation.getModelVersion(), 508 implementation.getModuleName() ); 509 510 instance.setImplementation( implementation ); 511 object = this.requestImplementation( 512 specClass, specification, this.getObject( instance ) ); 513 514 } 515 else 516 { 517 if ( implementationNameWarning ) 518 { 519 final Throwable x = new Throwable(); 520 final StackTraceElement[] elements = x.getStackTrace(); 521 522 String cname = "unknown"; 523 String method = "unknown"; 524 StackTraceElement caller = null; 525 526 if ( elements != null && elements.length > 2 ) 527 { 528 caller = elements[2]; 529 cname = caller.getClassName(); 530 method = caller.getMethodName(); 531 } 532 533 Logger.getLogger( DefaultContainer.class.getName() ). 534 log( Level.SEVERE, DefaultContainerBundle.getInstance(). 535 getNullImplementationNameWarningMessage( 536 Locale.getDefault(), specificationIdentifier, cname, 537 method ), x ); 538 539 } 540 541 object = this.resolveImplementation( classLoader, 542 specification ); 543 544 } 545 546 return object; 547 } 548 catch ( final IllegalAccessException e ) 549 { 550 // Cannot happen - method got set accessible. 551 throw new AssertionError( e ); 552 } 553 catch ( final InvocationTargetException e ) 554 { 555 throw new ContainerError( e ); 556 } 557 catch ( final NoSuchMethodException e ) 558 { 559 throw new ContainerError( e ); 560 } 561 catch ( final ClassNotFoundException e ) 562 { 563 throw new ContainerError( e ); 564 } 565 } 566 567 private Object getObject( final Instance instance ) 568 { 569 return this.getScopedObject( 570 SCOPES[instance.getScope() - Specification.SCOPE_MULTITON], 571 instance ); 572 573 } 574 575 private Object instantiateObject( final Instance instance ) 576 { 577 try 578 { 579 Object object = null; 580 581 if ( VersionParser.compare( instance.getModelVersion(), 582 "1.3" ) < 0 ) 583 { 584 if ( instance.getImplementation() != null ) 585 { 586 object = this.instantiateImplementation( 587 instance.getClassLoader(), 588 instance.getImplementation() ); 589 590 } 591 else if ( instance.getDependency() != null ) 592 { 593 object = this.instantiateDependency( 594 instance.getClassLoader(), 595 instance.getDependency() ); 596 597 } 598 else 599 { 600 throw new AssertionError(); 601 } 602 } 603 else 604 { 605 final Class clazz = Class.forName( 606 instance.getClassName(), true, instance.getClassLoader() ); 607 608 if ( Model.class.getName().equals( instance.getModuleName() ) ) 609 { 610 // Automatically discovered default implementations must use 611 // the static getDefault method. 612 final Method accessor = 613 clazz.getMethod( "getDefault", EMPTY ); 614 615 object = accessor.invoke( null, EMPTY ); 616 } 617 else 618 { 619 object = clazz.newInstance(); 620 } 621 } 622 623 synchronized ( this.objects ) 624 { 625 this.objects.put( object, instance ); 626 } 627 628 this.initializeObject( object ); 629 return object; 630 } 631 catch ( final Throwable t ) 632 { 633 if ( t instanceof Error ) 634 { 635 throw (Error) t; 636 } 637 else if ( t instanceof RuntimeException ) 638 { 639 throw (RuntimeException) t; 640 } 641 else 642 { 643 throw new org.jdtaus.core.container.InstantiationException( 644 instance.getClassName(), t ); 645 646 } 647 } 648 } 649 650 private Implementation getImplementation( final Object object ) 651 { 652 MissingImplementationException exception = null; 653 Implementation implementation = null; 654 Class clazz = object.getClass(); 655 656 do 657 { 658 try 659 { 660 implementation = ModelFactory.getModel().getModules(). 661 getImplementation( clazz.getName() ); 662 663 break; 664 } 665 catch ( final MissingImplementationException e ) 666 { 667 if ( exception == null ) 668 { 669 exception = e; 670 } 671 } 672 } 673 while ( ( clazz = clazz.getSuperclass() ) != null ); 674 675 if ( implementation == null ) 676 { 677 throw exception; 678 } 679 680 return implementation; 681 } 682 683 private Instance getInstance( final Object object, 684 final Implementation impl ) 685 { 686 synchronized ( this.objects ) 687 { 688 Instance instance = (Instance) this.objects.get( object ); 689 690 if ( instance == null ) 691 { 692 instance = 693 new Instance( this.getClassLoader( object.getClass() ), 694 Specification.SCOPE_MULTITON, 695 impl.getIdentifier(), 696 impl.getModelVersion(), 697 impl.getModuleName() ); 698 699 instance.setImplementation( impl ); 700 this.objects.put( object, instance ); 701 } 702 703 return instance; 704 } 705 } 706 707 private Object getDependency( final ClassLoader classLoader, 708 final Instance instance, 709 final Dependency dependency ) 710 throws ClassNotFoundException, NoSuchMethodException, 711 IllegalAccessException, InvocationTargetException 712 { 713 Object dependencyObject = 714 instance != null 715 ? instance.getDependencyObject( dependency.getName() ) 716 : null; 717 718 if ( dependencyObject == null ) 719 { 720 if ( dependency.getImplementation() != null ) 721 { 722 final Class specClass = 723 Class.forName( dependency.getSpecification().getIdentifier(), 724 true, classLoader ); 725 726 final Instance dependencyInstance = new Instance( 727 classLoader, dependency.getSpecification().getScope(), 728 dependency.getImplementation().getIdentifier(), 729 dependency.getImplementation().getModelVersion(), 730 dependency.getImplementation().getModuleName() ); 731 732 dependencyInstance.setDependency( dependency ); 733 dependencyObject = this.requestImplementation( 734 specClass, dependency.getSpecification(), 735 this.getObject( dependencyInstance ) ); 736 737 } 738 else 739 { 740 dependencyObject = this.resolveDependency( classLoader, 741 dependency ); 742 743 } 744 } 745 746 if ( instance != null && dependency.isBound() ) 747 { 748 instance.setDependencyObject( dependency.getName(), 749 dependencyObject ); 750 751 } 752 753 return dependencyObject; 754 } 755 756 private Object resolveDependency( final ClassLoader classLoader, 757 final Dependency dependency ) 758 throws ClassNotFoundException, NoSuchMethodException, 759 IllegalAccessException, InvocationTargetException 760 { 761 Implementation impl; 762 Instance dependencyInstance; 763 Dependency clone; 764 final Object resolved; 765 766 final Class specClass = 767 Class.forName( dependency.getSpecification().getIdentifier(), 768 true, classLoader ); 769 770 switch ( dependency.getSpecification().getMultiplicity() ) 771 { 772 case Specification.MULTIPLICITY_ONE: 773 if ( dependency.getSpecification(). 774 getImplementations().size() != 1 ) 775 { 776 throw new MultiplicityConstraintException( 777 dependency.getSpecification(). 778 getIdentifier() ); 779 780 } 781 782 impl = dependency.getSpecification().getImplementations(). 783 getImplementation( 0 ); 784 785 dependencyInstance = new Instance( 786 classLoader, dependency.getSpecification().getScope(), 787 impl.getIdentifier(), impl.getModelVersion(), 788 impl.getModuleName() ); 789 790 clone = (Dependency) dependency.clone(); 791 clone.setImplementation( impl ); 792 dependencyInstance.setDependency( clone ); 793 resolved = this.requestImplementation( specClass, dependency. 794 getSpecification(), this.getObject( dependencyInstance ) ); 795 796 break; 797 798 case Specification.MULTIPLICITY_MANY: 799 final List list = new ArrayList( dependency.getSpecification(). 800 getImplementations().size() ); 801 802 for ( int i = dependency.getSpecification(). 803 getImplementations().size() - 1; i >= 0; i-- ) 804 { 805 impl = dependency.getSpecification().getImplementations(). 806 getImplementation( i ); 807 808 dependencyInstance = new Instance( 809 classLoader, dependency.getSpecification().getScope(), 810 impl.getIdentifier(), impl.getModelVersion(), 811 impl.getModuleName() ); 812 813 clone = (Dependency) dependency.clone(); 814 clone.setImplementation( impl ); 815 dependencyInstance.setDependency( clone ); 816 list.add( this.requestImplementation( 817 specClass, dependency.getSpecification(), 818 this.getObject( dependencyInstance ) ) ); 819 820 } 821 822 final Object[] implementations = 823 (Object[]) Array.newInstance( specClass, 824 list.size() ); 825 826 resolved = list.toArray( implementations ); 827 break; 828 829 default: 830 throw new AssertionError( Integer.toString( 831 dependency.getSpecification().getMultiplicity() ) ); 832 833 } 834 835 return resolved; 836 } 837 838 private Object resolveImplementation( final ClassLoader classLoader, 839 final Specification spec ) 840 throws ClassNotFoundException, NoSuchMethodException, 841 IllegalAccessException, InvocationTargetException 842 { 843 Instance instance; 844 Implementation impl; 845 846 final Object resolved; 847 final Class specClass = Class.forName( 848 spec.getIdentifier(), true, classLoader ); 849 850 switch ( spec.getMultiplicity() ) 851 { 852 case Specification.MULTIPLICITY_ONE: 853 if ( spec.getImplementations().size() != 1 ) 854 { 855 throw new MultiplicityConstraintException( 856 spec.getIdentifier() ); 857 858 } 859 860 impl = spec.getImplementations().getImplementation( 0 ); 861 instance = new Instance( classLoader, 862 spec.getScope(), 863 impl.getIdentifier(), 864 impl.getModelVersion(), 865 impl.getModuleName() ); 866 867 instance.setImplementation( impl ); 868 resolved = this.requestImplementation( 869 specClass, spec, this.getObject( instance ) ); 870 871 break; 872 873 case Specification.MULTIPLICITY_MANY: 874 final List list = new ArrayList( 875 spec.getImplementations().size() ); 876 877 for ( int i = spec.getImplementations().size() - 1; i >= 0; 878 i-- ) 879 { 880 impl = spec.getImplementations().getImplementation( i ); 881 instance = new Instance( classLoader, 882 spec.getScope(), 883 impl.getIdentifier(), 884 impl.getModelVersion(), 885 impl.getModuleName() ); 886 887 instance.setImplementation( impl ); 888 list.add( this.requestImplementation( 889 specClass, spec, this.getObject( instance ) ) ); 890 891 } 892 893 final Object[] implementations = 894 (Object[]) Array.newInstance( specClass, 895 list.size() ); 896 897 resolved = list.toArray( implementations ); 898 break; 899 900 default: 901 throw new AssertionError( Integer.toString( 902 spec.getMultiplicity() ) ); 903 904 } 905 906 return resolved; 907 } 908 909 private Object getScopedObject( final Scope scope, final Instance instance ) 910 { 911 Object object; 912 913 if ( scope != null ) 914 { 915 object = scope.getObject( instance.getClassName() ); 916 917 if ( object == null || object instanceof Instance ) 918 { 919 synchronized ( this.cycle ) 920 { 921 object = scope.getObject( instance.getClassName() ); 922 923 if ( object == null ) 924 { 925 scope.putObject( instance.getClassName(), instance ); 926 927 try 928 { 929 object = this.instantiateObject( instance ); 930 } 931 catch ( final Throwable t ) 932 { 933 scope.removeObject( instance.getClassName() ); 934 if ( t instanceof Error ) 935 { 936 throw (Error) t; 937 } 938 else if ( t instanceof RuntimeException ) 939 { 940 throw (RuntimeException) t; 941 } 942 else 943 { 944 throw new org.jdtaus.core.container.InstantiationException( 945 instance.getClassName(), t ); 946 947 } 948 } 949 950 scope.putObject( instance.getClassName(), object ); 951 } 952 else if ( object instanceof Instance ) 953 { 954 throw new DependencyCycleException( 955 ( (Instance) object ).getClassName(), 956 instance.getClassName() ); 957 958 } 959 } 960 } 961 } 962 else 963 { 964 object = this.instantiateObject( instance ); 965 } 966 967 return object; 968 } 969 970 private ClassLoader getClassLoader( final Class clazz ) 971 { 972 ClassLoader classLoader = clazz.getClassLoader(); 973 if ( classLoader == null ) 974 { 975 classLoader = ClassLoader.getSystemClassLoader(); 976 } 977 978 return classLoader; 979 } 980 981 private Object requestImplementation( final Class specClass, 982 final Specification spec, 983 final Object object ) 984 throws NoSuchMethodException, IllegalAccessException, 985 InvocationTargetException 986 { 987 Object resolved = object; 988 Method accessor = null; 989 990 try 991 { 992 if ( !specClass.isAssignableFrom( object.getClass() ) ) 993 { 994 accessor = object.getClass().getDeclaredMethod( 995 spec.getIdentifier().replace( '.', '_' ), EMPTY ); 996 997 accessor.setAccessible( true ); 998 resolved = accessor.invoke( object, EMPTY ); 999 } 1000 1001 return resolved; 1002 } 1003 finally 1004 { 1005 if ( accessor != null ) 1006 { 1007 accessor.setAccessible( false ); 1008 } 1009 } 1010 } 1011 1012 //--------------------------------------------------------DefaultContainer-- 1013}