EMMA Coverage Report (generated Tue Jan 14 02:29:45 CET 2014)
[all classes][org.jdtaus.core.container.ri.client]

COVERAGE SUMMARY FOR SOURCE FILE [DefaultContainer.java]

nameclass, %method, %block, %line, %
DefaultContainer.java100% (1/1)59%  (16/27)43%  (576/1333)44%  (123.3/281)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class DefaultContainer100% (1/1)59%  (16/27)43%  (576/1333)44%  (123.3/281)
getDependency (Class, String): Object 0%   (0/1)0%   (0/58)0%   (0/15)
getImplementation (Class, String): Object 0%   (0/1)0%   (0/19)0%   (0/5)
getMessage (Object, String, Locale, Object): String 0%   (0/1)0%   (0/40)0%   (0/7)
getMessage (Object, String, Object): String 0%   (0/1)0%   (0/21)0%   (0/5)
getObject (Class): Object 0%   (0/1)0%   (0/17)0%   (0/3)
getObject (Class, String): Object 0%   (0/1)0%   (0/24)0%   (0/5)
getObject (String): Object 0%   (0/1)0%   (0/10)0%   (0/1)
initializeContext (Object): void 0%   (0/1)0%   (0/20)0%   (0/5)
instantiateDependency (ClassLoader, Dependency): Object 0%   (0/1)0%   (0/65)0%   (0/14)
instantiateImplementation (ClassLoader, Implementation): Object 0%   (0/1)0%   (0/63)0%   (0/14)
resolveDependency (ClassLoader, Dependency): Object 0%   (0/1)0%   (0/146)0%   (0/25)
requestImplementation (Class, Specification, Object): Object 100% (1/1)34%  (15/44)53%  (4.8/9)
getInstance (Object, Implementation): Instance 100% (1/1)37%  (17/46)50%  (4/8)
getDependency (Object, String): Object 100% (1/1)50%  (34/68)41%  (7/17)
instantiateObject (Instance): Object 100% (1/1)53%  (59/111)57%  (13.7/24)
resolveImplementation (ClassLoader, Specification): Object 100% (1/1)60%  (71/119)62%  (13/21)
getImplementation (Object): Implementation 100% (1/1)60%  (18/30)58%  (7/12)
getProperty (Object, String): Object 100% (1/1)60%  (15/25)60%  (3/5)
initializeObject (Object): void 100% (1/1)64%  (9/14)80%  (4/5)
getObjectInternal (ClassLoader, String, String, boolean): Object 100% (1/1)74%  (102/137)70%  (22.9/33)
getClassLoader (Class): ClassLoader 100% (1/1)78%  (7/9)75%  (3/4)
getScopedObject (Scope, Instance): Object 100% (1/1)89%  (84/94)91%  (20/22)
getDependency (ClassLoader, Instance, Dependency): Object 100% (1/1)91%  (62/68)91%  (10.9/12)
<static initializer> 100% (1/1)96%  (49/51)98%  (3.9/4)
DefaultContainer (): void 100% (1/1)100% (14/14)100% (4/4)
getObject (Instance): Object 100% (1/1)100% (10/10)100% (1/1)
getObject (String, String): Object 100% (1/1)100% (10/10)100% (1/1)

1/*
2 *  jDTAUS Core RI Client Container
3 *  Copyright (C) 2005 Christian Schulte
4 *  <cs@schulte.it>
5 *
6 *  This library is free software; you can redistribute it and/or
7 *  modify it under the terms of the GNU Lesser General Public
8 *  License as published by the Free Software Foundation; either
9 *  version 2.1 of the License, or any later version.
10 *
11 *  This library is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 *  Lesser General Public License for more details.
15 *
16 *  You should have received a copy of the GNU Lesser General Public
17 *  License along with this library; if not, write to the Free Software
18 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 *
20 */
21package org.jdtaus.core.container.ri.client;
22 
23import java.lang.reflect.Array;
24import java.lang.reflect.Constructor;
25import java.lang.reflect.InvocationTargetException;
26import java.lang.reflect.Method;
27import java.text.MessageFormat;
28import java.util.ArrayList;
29import java.util.List;
30import java.util.Locale;
31import java.util.Map;
32import java.util.logging.Level;
33import java.util.logging.Logger;
34import org.jdtaus.core.container.Container;
35import org.jdtaus.core.container.ContainerError;
36import org.jdtaus.core.container.ContainerInitializer;
37import org.jdtaus.core.container.ContextFactory;
38import org.jdtaus.core.container.ContextInitializer;
39import org.jdtaus.core.container.Dependency;
40import org.jdtaus.core.container.DependencyCycleException;
41import org.jdtaus.core.container.Implementation;
42import org.jdtaus.core.container.MissingImplementationException;
43import org.jdtaus.core.container.Model;
44import org.jdtaus.core.container.ModelFactory;
45import org.jdtaus.core.container.MultiplicityConstraintException;
46import org.jdtaus.core.container.Specification;
47import org.jdtaus.core.container.ri.client.versioning.VersionParser;
48 
49/**
50 * {@code Container} reference implementation.
51 *
52 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
53 * @version $JDTAUS: DefaultContainer.java 8743 2012-10-07 03:06:20Z schulte $
54 *
55 * @see org.jdtaus.core.container.ContainerFactory
56 */
57public class DefaultContainer implements Container
58{
59    //--Constants---------------------------------------------------------------
60 
61    /** Empty Class-Array. */
62    private static final Class[] EMPTY =
63    {
64    };
65 
66    /** Implementation Class-Array. */
67    private static final Class[] IMPL_CTOR =
68    {
69        Implementation.class
70    };
71 
72    /** Dependency Class-Array. */
73    private static final Class[] DEP_CTOR =
74    {
75        Dependency.class
76    };
77 
78    /** Array of scope implementations. */
79    private static final Scope[] SCOPES =
80    {
81        null, new ContextScope(), new SingletonScope()
82    };
83 
84    //---------------------------------------------------------------Constants--
85    //--Container---------------------------------------------------------------
86 
87    /** Mutex used to detect cyclic instantiations. */
88    private final Object cycle = new Object();
89 
90    /** Maps objects to model object. */
91    private final Map objects = new WeakIdentityHashMap( 1024 );
92 
93    public Object getObject( final Class specification )
94    {
95        if ( specification == null )
96        {
97            throw new NullPointerException( "specification" );
98        }
99 
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}

[all classes][org.jdtaus.core.container.ri.client]
EMMA 2.1.5320 (stable) (C) Vladimir Roubtsov