View Javadoc

1   //
2   // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 
3   // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
4   // Any modifications to this file will be lost upon recompilation of the source schema. 
5   // Generated on: 2013.04.21 at 08:43:16 PM CEST 
6   //
7   
8   
9   package org.jomc.model;
10  
11  import java.util.ArrayList;
12  import java.util.Iterator;
13  import java.util.List;
14  import javax.annotation.Generated;
15  import javax.xml.bind.annotation.XmlAccessType;
16  import javax.xml.bind.annotation.XmlAccessorType;
17  import javax.xml.bind.annotation.XmlElement;
18  import javax.xml.bind.annotation.XmlType;
19  
20  
21  /**
22   * List of modules.
23   * 
24   * <p>Java class for Modules complex type.
25   * 
26   * <p>The following schema fragment specifies the expected content contained within this class.
27   * 
28   * <pre>
29   * &lt;complexType name="Modules">
30   *   &lt;complexContent>
31   *     &lt;extension base="{http://jomc.org/model}ModelObject">
32   *       &lt;sequence>
33   *         &lt;element ref="{http://jomc.org/model}module" maxOccurs="unbounded" minOccurs="0"/>
34   *       &lt;/sequence>
35   *     &lt;/extension>
36   *   &lt;/complexContent>
37   * &lt;/complexType>
38   * </pre>
39   * 
40   * 
41   */
42  @XmlAccessorType(XmlAccessType.FIELD)
43  @XmlType(name = "Modules", namespace = "http://jomc.org/model", propOrder = {
44      "module"
45  })
46  @Generated(value = "com.sun.tools.xjc.Driver", date = "2013-04-21T08:43:16+02:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-2")
47  public class Modules
48      extends ModelObject
49      implements Cloneable
50  {
51  
52      @XmlElement(namespace = "http://jomc.org/model")
53      @Generated(value = "com.sun.tools.xjc.Driver", date = "2013-04-21T08:43:16+02:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-2")
54      protected List<Module> module;
55  
56      /**
57       * Creates a new {@code Modules} instance.
58       * 
59       */
60      public Modules() {
61          // CC-XJC Version 2.0.1 Build 2012-03-02T12:09:12+0000
62          super();
63      }
64  
65      /**
66       * Creates a new {@code Modules} instance by deeply copying a given {@code Modules} instance.
67       * 
68       * 
69       * @param o
70       *     The instance to copy.
71       * @throws NullPointerException
72       *     if {@code o} is {@code null}.
73       */
74      public Modules(final Modules o) {
75          // CC-XJC Version 2.0.1 Build 2012-03-02T12:09:12+0000
76          super(o);
77          if (o == null) {
78              throw new NullPointerException("Cannot create a copy of 'Modules' from 'null'.");
79          }
80          // 'Module' collection.
81          if (o.module!= null) {
82              copyModule(o.getModule(), this.getModule());
83          }
84      }
85  
86      /**
87       * Gets the value of the module property.
88       * 
89       * <p>
90       * This accessor method returns a reference to the live list,
91       * not a snapshot. Therefore any modification you make to the
92       * returned list will be present inside the JAXB object.
93       * This is why there is not a <CODE>set</CODE> method for the module property.
94       * 
95       * <p>
96       * For example, to add a new item, do as follows:
97       * <pre>
98       *    getModule().add(newItem);
99       * </pre>
100      * 
101      * 
102      * <p>
103      * Objects of the following type(s) are allowed in the list
104      * {@link Module }
105      * 
106      * 
107      */
108     @Generated(value = "com.sun.tools.xjc.Driver", date = "2013-04-21T08:43:16+02:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-2")
109     public List<Module> getModule() {
110         if (module == null) {
111             module = new ArrayList<Module>();
112         }
113         return this.module;
114     }
115 
116     /**
117      * Copies all values of property {@code Module} deeply.
118      * 
119      * @param source
120      *     The source to copy from.
121      * @param target
122      *     The target to copy {@code source} to.
123      * @throws NullPointerException
124      *     if {@code target} is {@code null}.
125      */
126     @SuppressWarnings("unchecked")
127     @Generated(value = "com.sun.tools.xjc.Driver", date = "2013-04-21T08:43:16+02:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-2")
128     private static void copyModule(final List<Module> source, final List<Module> target) {
129         // CC-XJC Version 2.0.1 Build 2012-03-02T12:09:12+0000
130         if ((source!= null)&&(!source.isEmpty())) {
131             for (final Iterator<?> it = source.iterator(); it.hasNext(); ) {
132                 final Object next = it.next();
133                 if (next instanceof Module) {
134                     // CClassInfo: org.jomc.model.Module
135                     target.add(((Module) next).clone());
136                     continue;
137                 }
138                 // Please report this at https://apps.sourceforge.net/mantisbt/ccxjc/
139                 throw new AssertionError((("Unexpected instance '"+ next)+"' for property 'Module' of class 'org.jomc.model.Modules'."));
140             }
141         }
142     }
143 
144     /**
145      * Creates and returns a deep copy of this object.
146      * 
147      * 
148      * @return
149      *     A deep copy of this object.
150      */
151     @Override
152     @Generated(value = "com.sun.tools.xjc.Driver", date = "2013-04-21T08:43:16+02:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-2")
153     public Modules clone() {
154         {
155             // CC-XJC Version 2.0.1 Build 2012-03-02T12:09:12+0000
156             final Modules clone = ((Modules) super.clone());
157             // 'Module' collection.
158             if (this.module!= null) {
159                 clone.module = null;
160                 copyModule(this.getModule(), clone.getModule());
161             }
162             return clone;
163         }
164     }
165     
166     /**
167      * Constant for the default name of the classpath module.
168      * @see #getDefaultClasspathModuleName()
169      */
170     @javax.xml.bind.annotation.XmlTransient
171     private static final String DEFAULT_CLASSPATH_MODULE_NAME = "Java Classpath";
172 
173     /** Default classpath module name. */
174     @javax.xml.bind.annotation.XmlTransient
175     private static volatile String defaultClasspathModuleName;
176 
177     /** Empty {@code Class} array. */
178     @javax.xml.bind.annotation.XmlTransient
179     private static final Class<?>[] NO_CLASSES =
180     {
181     };
182 
183     /**
184      * Comparator comparing dependency names lexicographically.
185      * @since 1.2
186      */
187     @javax.xml.bind.annotation.XmlTransient
188     private static final java.util.Comparator<Dependency> DEPENDENCY_NAME_COMPARATOR =
189         new java.util.Comparator<Dependency>()
190     {
191 
192         public int compare( final Dependency o1, final Dependency o2 )
193         {
194             return o1.getName().compareTo( o2.getName() );
195         }
196 
197     };
198 
199     /**
200      * Comparator comparing message names lexicographically.
201      * @since 1.2
202      */
203     @javax.xml.bind.annotation.XmlTransient
204     private static final java.util.Comparator<Message> MESSAGE_NAME_COMPARATOR =
205         new java.util.Comparator<Message>()
206     {
207 
208         public int compare( final Message o1, final Message o2 )
209         {
210             return o1.getName().compareTo( o2.getName() );
211         }
212 
213     };
214 
215     /**
216      * Comparator comparing property names lexicographically.
217      * @since 1.2
218      */
219     @javax.xml.bind.annotation.XmlTransient
220     private static final java.util.Comparator<Property> PROPERTY_NAME_COMPARATOR =
221         new java.util.Comparator<Property>()
222     {
223 
224         public int compare( final Property o1, final Property o2 )
225         {
226             return o1.getName().compareTo( o2.getName() );
227         }
228 
229     };
230 
231     /**
232      * Comparator comparing specification identifiers lexicographically.
233      * @since 1.2
234      */
235     @javax.xml.bind.annotation.XmlTransient
236     private static final java.util.Comparator<Specification> SPECIFICATION_IDENTIFIER_COMPARATOR =
237         new java.util.Comparator<Specification>()
238     {
239 
240         public int compare( final Specification o1, final Specification o2 )
241         {
242             return o1.getIdentifier().compareTo( o2.getIdentifier() );
243         }
244 
245     };
246 
247     /**
248      * Comparator comparing specification reference identifiers lexicographically.
249      * @since 1.2
250      */
251     @javax.xml.bind.annotation.XmlTransient
252     private static final java.util.Comparator<SpecificationReference> SPECIFICATION_REFERENCE_IDENTIFIER_COMPARATOR =
253         new java.util.Comparator<SpecificationReference>()
254     {
255 
256         public int compare( final SpecificationReference o1, final SpecificationReference o2 )
257         {
258             return o1.getIdentifier().compareTo( o2.getIdentifier() );
259         }
260 
261     };
262 
263     /**
264      * Comparator comparing {@code JavaTypeName} names lexicographically.
265      * @since 1.4
266      */
267     @javax.xml.bind.annotation.XmlTransient
268     private static final java.util.Comparator<JavaTypeName> JAVA_TYPE_NAME_COMPARATOR =
269         new java.util.Comparator<JavaTypeName>()
270     {
271 
272         public int compare( final JavaTypeName o1, final JavaTypeName o2 )
273         {
274             return o1.getName( true ).compareTo( o2.getName( true ) );
275         }
276 
277     };
278 
279     /** Maps objects to {@code Instance}s. */
280     @javax.xml.bind.annotation.XmlTransient private java.util.Map<Object, Instance> objects =
281         new org.jomc.util.WeakIdentityHashMap<Object, Instance>();
282 
283     /**
284      * Creates a new {@code Modules} instance taking a map backing the instance.
285      *
286      * @param objects The map backing the instance.
287      */
288     public Modules( final java.util.Map<Object, Instance> objects )
289     {
290         super();
291 
292         if ( objects == null )
293         {
294             throw new NullPointerException( "objects" );
295         }
296 
297         this.objects = objects;
298     }
299 
300     /**
301      * Creates a new {@code Modules} instance by deeply copying a given {@code Modules} instance taking a map backing
302      * the instance.
303      *
304      * @param o The instance to copy.
305      * @param objects The map backing the instance.
306      *
307      * @throws NullPointerException if {@code o} or {@code objects} is {@code null}.
308      */
309     public Modules( final Modules o, final java.util.Map<Object, Instance> objects )
310     {
311         super( o );
312         if ( o == null )
313         {
314             throw new NullPointerException( "Cannot create a copy of 'Modules' from 'null'." );
315         }
316         if ( objects == null )
317         {
318             throw new NullPointerException( "objects" );
319         }
320 
321         copyModule( o.getModule(), getModule() );
322         this.objects = objects;
323     }
324 
325     /**
326      * Gets the default classpath module name.
327      * <p>The default classpath module name is controlled by system property
328      * {@code org.jomc.model.Modules.defaultClasspathModuleName} holding the default classpath module name. If that
329      * property is not set, the {@code Java Classpath} default is returned.</p>
330      *
331      * @return The default classpath module name.
332      *
333      * @see #getClasspathModule(java.lang.String, java.lang.ClassLoader)
334      */
335     public static String getDefaultClasspathModuleName()
336     {
337         if ( defaultClasspathModuleName == null )
338         {
339             defaultClasspathModuleName = System.getProperty( "org.jomc.model.Modules.defaultClasspathModuleName",
340                                                              DEFAULT_CLASSPATH_MODULE_NAME );
341 
342         }
343 
344         return defaultClasspathModuleName;
345     }
346 
347     /**
348      * Sets the default classpath module name.
349      *
350      * @param value The new default classpath module name or {@code null},
351      */
352     public static void setDefaultClasspathModuleName( final String value )
353     {
354         defaultClasspathModuleName = value;
355     }
356 
357     /**
358      * Gets a module holding model objects resolved by inspecting a given class loader.
359      * <p>This method searches this list of modules for unresolved references and tries to resolve each unresolved
360      * reference by inspecting the given class loader.</p>
361      *
362      * @param moduleName The name of the module to return.
363      * @param classLoader The class loader to use for resolving entities or {@code null}, to resolve entities using the
364      * bootstrap class loader.
365      *
366      * @return A module holding model objects resolved by inspecting the given class loader or {@code null}, if nothing
367      * is resolved.
368      *
369      * @throws NullPointerException if {@code moduleName} is {@code null}.
370      *
371      * @see #getDefaultClasspathModuleName()
372      * @see #getModule()
373      */
374     public Module getClasspathModule( final String moduleName, final ClassLoader classLoader )
375     {
376         if ( moduleName == null )
377         {
378             throw new NullPointerException( "moduleName" );
379         }
380 
381         final Module classpathModule = new Module();
382         classpathModule.setVersion( System.getProperty( "java.specification.version" ) );
383         classpathModule.setName( moduleName );
384 
385         this.resolveClasspath( classpathModule, classLoader );
386 
387         final boolean resolved = ( classpathModule.getSpecifications() != null
388                                    && !classpathModule.getSpecifications().getSpecification().isEmpty() )
389                                  || ( classpathModule.getImplementations() != null
390                                       && !classpathModule.getImplementations().getImplementation().isEmpty() );
391 
392         return resolved ? classpathModule : null;
393     }
394 
395     /**
396      * Gets a module for a given name from the list of modules.
397      *
398      * @param name The name of the module to return.
399      *
400      * @return The first matching module or {@code null}, if no such module is found.
401      *
402      * @throws NullPointerException if {@code name} is {@code null}.
403      *
404      * @see #getModule()
405      * @see Module#getName()
406      */
407     public Module getModule( final String name )
408     {
409         if ( name == null )
410         {
411             throw new NullPointerException( "name" );
412         }
413 
414         for ( int i = 0, s0 = this.getModule().size(); i < s0; i++ )
415         {
416             final Module m = this.getModule().get( i );
417 
418             if ( m.getName().equals( name ) )
419             {
420                 return m;
421             }
422         }
423 
424         return null;
425     }
426 
427     /**
428      * Gets all specifications of the list of modules.
429      *
430      * @return All specifications or {@code null}, if no specifications are found.
431      *
432      * @see #getModule()
433      */
434     public Specifications getSpecifications()
435     {
436         final Specifications specifications = new Specifications();
437 
438         for ( int i = 0, s0 = this.getModule().size(); i < s0; i++ )
439         {
440             final Module m = this.getModule().get( i );
441 
442             if ( m.getSpecifications() != null )
443             {
444                 specifications.getSpecification().addAll( m.getSpecifications().getSpecification() );
445             }
446         }
447 
448         return specifications.getSpecification().isEmpty() ? null : specifications;
449     }
450 
451     /**
452      * Gets all implementations of the list of modules.
453      *
454      * @return All implementations or {@code null}, if no implementations are found.
455      *
456      * @see #getModule()
457      */
458     public Implementations getImplementations()
459     {
460         final Implementations implementations = new Implementations();
461 
462         for ( int i = 0, s0 = this.getModule().size(); i < s0; i++ )
463         {
464             final Module m = this.getModule().get( i );
465 
466             if ( m.getImplementations() != null )
467             {
468                 implementations.getImplementation().addAll( m.getImplementations().getImplementation() );
469             }
470         }
471 
472         return implementations.getImplementation().isEmpty() ? null : implementations;
473     }
474 
475     /**
476      * Gets the module declaring a given specification from the list of modules.
477      *
478      * @param specification The identifier of the specification whose declaring module to return.
479      *
480      * @return The first matching module or {@code null}, if no such module is found.
481      *
482      * @throws NullPointerException if {@code specification} is {@code null}.
483      *
484      * @see #getModule()
485      * @see Module#getSpecifications()
486      * @see Specifications#getSpecification( java.lang.String )
487      */
488     public Module getModuleOfSpecification( final String specification )
489     {
490         if ( specification == null )
491         {
492             throw new NullPointerException( "specification" );
493         }
494 
495         for ( int i = 0, s0 = this.getModule().size(); i < s0; i++ )
496         {
497             final Module m = this.getModule().get( i );
498 
499             if ( m.getSpecifications() != null && m.getSpecifications().getSpecification( specification ) != null )
500             {
501                 return m;
502             }
503         }
504 
505         return null;
506     }
507 
508     /**
509      * Gets the module declaring a given implementation from the list of modules.
510      *
511      * @param implementation The identifier of the implementation whose declaring module to return.
512      *
513      * @return The first matching module or {@code null}, if no such module is found.
514      *
515      * @throws NullPointerException if {@code implementation} is {@code null}.
516      *
517      * @see #getModule()
518      * @see Module#getImplementations()
519      * @see Implementations#getImplementation( java.lang.String )
520      */
521     public Module getModuleOfImplementation( final String implementation )
522     {
523         if ( implementation == null )
524         {
525             throw new NullPointerException( "implementation" );
526         }
527 
528         for ( int i = 0, s0 = this.getModule().size(); i < s0; i++ )
529         {
530             final Module m = this.getModule().get( i );
531 
532             if ( m.getImplementations() != null && m.getImplementations().getImplementation( implementation ) != null )
533             {
534                 return m;
535             }
536         }
537 
538         return null;
539     }
540 
541     /**
542      * Gets a specification for a given identifier from the list of modules.
543      *
544      * @param specification The identifier of the specification to return.
545      *
546      * @return The first matching specification or {@code null}, if no such specification is found.
547      *
548      * @throws NullPointerException if {@code specification} is {@code null}.
549      *
550      * @see #getModule()
551      * @see Module#getSpecifications()
552      * @see Specifications#getSpecification( java.lang.String )
553      */
554     public Specification getSpecification( final String specification )
555     {
556         if ( specification == null )
557         {
558             throw new NullPointerException( "specification" );
559         }
560 
561         for ( int i = 0, s0 = this.getModule().size(); i < s0; i++ )
562         {
563             final Module m = this.getModule().get( i );
564 
565             if ( m.getSpecifications() != null )
566             {
567                 final Specification s = m.getSpecifications().getSpecification( specification );
568 
569                 if ( s != null )
570                 {
571                     return s;
572                 }
573             }
574         }
575 
576         return null;
577     }
578 
579     /**
580      * Gets a specification declaring a given class from the list of modules.
581      *
582      * @param specification The class of the specification to return.
583      *
584      * @return The first matching specification declaring the given class or {@code null}, if no such specification is
585      * found.
586      *
587      * @throws NullPointerException if {@code specification} is {@code null}.
588      * @throws ModelObjectException if compiling a name of a referenced type to a {@code JavaTypeName} fails.
589      *
590      * @see #getModule()
591      * @see Module#getSpecifications()
592      * @see Specifications#getSpecification( java.lang.Class )
593      */
594     public Specification getSpecification( final Class<?> specification ) throws ModelObjectException
595     {
596         if ( specification == null )
597         {
598             throw new NullPointerException( "specification" );
599         }
600 
601         for ( int i = 0, s0 = this.getModule().size(); i < s0; i++ )
602         {
603             final Module m = this.getModule().get( i );
604 
605             if ( m.getSpecifications() != null )
606             {
607                 final Specification s = m.getSpecifications().getSpecification( specification );
608 
609                 if ( s != null )
610                 {
611                     return s;
612                 }
613             }
614         }
615 
616         return null;
617     }
618 
619     /**
620      * Gets all specifications an implementation implements from the list of modules.
621      *
622      * @param implementation The identifier of the implementation to get all implemented specifications of.
623      *
624      * @return All specifications implemented by the first matching implementation or {@code null}, if no such
625      * implementation is found or if the first matching implementation does not implement any specification.
626      *
627      * @throws NullPointerException if {@code implementation} is {@code null}.
628      *
629      * @see #getModule()
630      * @see #getImplementation( java.lang.String )
631      * @see Implementation#getImplementations()
632      * @see Implementations#getReference()
633      * @see Implementation#getSpecifications()
634      */
635     public Specifications getSpecifications( final String implementation )
636     {
637         if ( implementation == null )
638         {
639             throw new NullPointerException( "implementation" );
640         }
641 
642         final Specifications specs = new Specifications();
643         final Implementation impl = this.getImplementation( implementation );
644         this.collectModelObjects( impl, null, null, null, specs, null, new java.util.HashSet<String>(), true );
645         this.collectClassDeclarationModelObjects( impl, null, null, null, specs, null );
646         java.util.Collections.sort( specs.getSpecification(), SPECIFICATION_IDENTIFIER_COMPARATOR );
647         java.util.Collections.sort( specs.getReference(), SPECIFICATION_REFERENCE_IDENTIFIER_COMPARATOR );
648         return specs.getSpecification().isEmpty() && specs.getReference().isEmpty() ? null : specs;
649     }
650 
651     /**
652      * Gets a list holding all {@code JavaTypeName}s an implementation implements from the list of modules.
653      *
654      * @param implementation The identifier of the implementation to get all implemented specifications of.
655      *
656      * @return An unmodifiable list holding all {@code JavaTypeName}s implemented by the first matching implementation
657      * or {@code null}, if no such implementation is found or if that implementation does not implement any
658      * {@code JavaTypeName}.
659      *
660      * @throws ModelObjectException if compiling the name of a referenced type to a {@code JavaTypeName} fails.
661      *
662      * @see #getSpecifications(java.lang.String)
663      * @see Specification#getJavaTypeName()
664      *
665      * @since 1.4
666      */
667     public List<JavaTypeName> getImplementedJavaTypeNames( final String implementation ) throws ModelObjectException
668     {
669         if ( implementation == null )
670         {
671             throw new NullPointerException( "implementation" );
672         }
673 
674         final Specifications implemented = this.getSpecifications( implementation );
675         java.util.List<JavaTypeName> javaTypeNames = null;
676 
677         if ( implemented != null )
678         {
679             javaTypeNames = new java.util.ArrayList<JavaTypeName>( implemented.getSpecification().size() );
680 
681             for ( int i = 0, s0 = implemented.getSpecification().size(); i < s0; i++ )
682             {
683                 final Specification s = implemented.getSpecification().get( i );
684                 final JavaTypeName javaTypeName = s.getJavaTypeName();
685 
686                 if ( javaTypeName != null && !javaTypeNames.contains( javaTypeName ) )
687                 {
688                     javaTypeNames.add( javaTypeName );
689                 }
690             }
691 
692             java.util.Collections.sort( javaTypeNames, JAVA_TYPE_NAME_COMPARATOR );
693             javaTypeNames = java.util.Collections.unmodifiableList( javaTypeNames );
694         }
695 
696         return javaTypeNames;
697     }
698 
699     /**
700      * Gets an implementation for a given identifier from the list of modules.
701      *
702      * @param implementation The identifier of the implementation to return.
703      *
704      * @return The first matching implementation or {@code null}, if no such implementation is found.
705      *
706      * @throws NullPointerException if {@code implementation} is {@code null}.
707      *
708      * @see #getModule()
709      * @see Module#getImplementations()
710      * @see Implementations#getImplementation( java.lang.String )
711      */
712     public Implementation getImplementation( final String implementation )
713     {
714         if ( implementation == null )
715         {
716             throw new NullPointerException( "implementation" );
717         }
718 
719         for ( int i = 0, s0 = this.getModule().size(); i < s0; i++ )
720         {
721             final Module m = this.getModule().get( i );
722 
723             if ( m.getImplementations() != null )
724             {
725                 final Implementation current = m.getImplementations().getImplementation( implementation );
726 
727                 if ( current != null )
728                 {
729                     return current;
730                 }
731             }
732         }
733 
734         return null;
735     }
736 
737     /**
738      * Gets an implementation declaring a given class from the list of modules.
739      *
740      * @param implementation The class of the implementation to return.
741      *
742      * @return The first matching implementation declaring the given class or {@code null}, if no such implementation is
743      * found.
744      *
745      * @throws NullPointerException if {@code implementation} is {@code null}.
746      * @throws ModelObjectException if compiling a name of a referenced type to a {@code JavaTypeName} fails.
747      *
748      * @see #getModule()
749      * @see Module#getImplementations()
750      * @see Implementations#getImplementation( java.lang.Class )
751      */
752     public Implementation getImplementation( final Class<?> implementation ) throws ModelObjectException
753     {
754         if ( implementation == null )
755         {
756             throw new NullPointerException( "implementation" );
757         }
758 
759         for ( int i = 0, s0 = this.getModule().size(); i < s0; i++ )
760         {
761             final Module m = this.getModule().get( i );
762 
763             if ( m.getImplementations() != null )
764             {
765                 final Implementation current = m.getImplementations().getImplementation( implementation );
766 
767                 if ( current != null )
768                 {
769                     return current;
770                 }
771             }
772         }
773 
774         return null;
775     }
776 
777     /**
778      * Gets an implementation for a given object from the list of modules.
779      *
780      * @param object The object of the implementation to return.
781      *
782      * @return The first matching implementation or {@code null}, if no such implementation is found.
783      *
784      * @throws NullPointerException if {@code object} is {@code null}.
785      * @throws ModelObjectException if compiling a name of a referenced type to a {@code JavaTypeName} fails.
786      *
787      * @see #getModule()
788      * @see #getImplementation( java.lang.Class )
789      */
790     public Implementation getImplementation( final Object object ) throws ModelObjectException
791     {
792         return this.collectImplementation( object.getClass() );
793     }
794 
795     /**
796      * Gets an implementation for a given name implementing a given specification from the list of modules.
797      *
798      * @param specification The identifier of the specification to return an implementation of.
799      * @param name The name of the implementation to return.
800      *
801      * @return The first matching implementation or {@code null}, if no such implementation is found.
802      *
803      * @throws NullPointerException if {@code specification} or {@code name} is {@code null}.
804      *
805      * @see #getModule()
806      * @see #getImplementations( java.lang.String )
807      * @see Implementations#getImplementationByName( java.lang.String )
808      */
809     public Implementation getImplementation( final String specification, final String name )
810     {
811         if ( specification == null )
812         {
813             throw new NullPointerException( "specification" );
814         }
815         if ( name == null )
816         {
817             throw new NullPointerException( "name" );
818         }
819 
820         final Implementations implementations = this.getImplementations( specification );
821         if ( implementations != null )
822         {
823             return implementations.getImplementationByName( name );
824         }
825 
826         return null;
827     }
828 
829     /**
830      * Gets all dependencies of an implementation from the list of modules.
831      *
832      * @param implementation The identifier of the implementation to get all dependencies of.
833      *
834      * @return All dependencies of the first matching implementation or {@code null}, if no such implementation is
835      * found or if the first matching implementation does not have any dependencies.
836      *
837      * @throws NullPointerException if {@code implementation} is {@code null}.
838      *
839      * @see #getModule()
840      * @see #getImplementation( java.lang.String )
841      * @see Implementation#getImplementations()
842      * @see Implementations#getReference()
843      * @see Implementation#getDependencies()
844      */
845     public Dependencies getDependencies( final String implementation )
846     {
847         if ( implementation == null )
848         {
849             throw new NullPointerException( "implementation" );
850         }
851 
852         final Dependencies dependencies = new Dependencies();
853         final Implementation impl = this.getImplementation( implementation );
854         this.collectModelObjects( impl, dependencies, null, null, null, null, new java.util.HashSet<String>(), true );
855         this.collectClassDeclarationModelObjects( impl, dependencies, null, null, null, null );
856         java.util.Collections.sort( dependencies.getDependency(), DEPENDENCY_NAME_COMPARATOR );
857         return dependencies.getDependency().isEmpty() ? null : dependencies;
858     }
859 
860     /**
861      * Gets the Java type name of a dependency.
862      *
863      * @param implementation The identifier of the implementation of the dependency.
864      * @param dependency The name of the dependency to get the Java type name of.
865      *
866      * @return The Java type name of the dependency named {@code dependency } of the first matching implementation
867      * identified by {@code implementation} or {@code null}, if the implementation, the dependency or the referenced
868      * specification is not found or does not reference a Java type.
869      *
870      * @throws NullPointerException if {@code implementation} or {@code dependency} is {@code null}.
871      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails.
872      *
873      * @since 1.4
874      *
875      * @see #getDependencies(java.lang.String)
876      * @see Dependencies#getDependency(java.lang.String)
877      * @see #getSpecification(java.lang.String)
878      * @see Specification#getJavaTypeName()
879      */
880     public JavaTypeName getDependencyJavaTypeName( final String implementation, final String dependency )
881         throws ModelObjectException
882     {
883         if ( implementation == null )
884         {
885             throw new NullPointerException( "implementation" );
886         }
887         if ( dependency == null )
888         {
889             throw new NullPointerException( "dependency" );
890         }
891 
892         String typeName = null;
893 
894         try
895         {
896             JavaTypeName javaTypeName = null;
897             final Dependencies dependencies = this.getDependencies( implementation );
898 
899             if ( dependencies != null )
900             {
901                 final Dependency d = dependencies.getDependency( dependency );
902 
903                 if ( d != null )
904                 {
905                     final Specification specification = this.getSpecification( d.getIdentifier() );
906 
907                     if ( specification != null && specification.getClazz() != null )
908                     {
909                         typeName = specification.getClazz();
910 
911                         if ( specification.getMultiplicity() == Multiplicity.MANY
912                              && d.getImplementationName() == null )
913                         {
914                             typeName += "[]";
915                         }
916 
917                         javaTypeName = JavaTypeName.parse( typeName );
918                     }
919                 }
920             }
921 
922             return javaTypeName;
923         }
924         catch ( final java.text.ParseException e )
925         {
926             throw new ModelObjectException( getMessage( "dependencyJavaTypeNameParseException", typeName,
927                                                         getMessage( e ) ), e );
928 
929         }
930     }
931 
932     /**
933      * Gets the Java modifier name of a dependency.
934      *
935      * @param implementation The identifier of the implementation of the dependency.
936      * @param dependency The name of the dependency to get the Java modifier name of.
937      *
938      * @return The Java modifier name of the dependency named {@code dependency} of the first matching implementation
939      * identified by {@code implementation} or {@code null}, if the implementation or the dependency is not found.
940      *
941      * @throws NullPointerException if {@code implementation} or {@code dependency} is {@code null}.
942      *
943      * @since 1.4
944      *
945      * @see #getDependencies(java.lang.String)
946      * @see Dependencies#getDependency(java.lang.String)
947      */
948     public String getDependencyJavaModifierName( final String implementation, final String dependency )
949     {
950         if ( implementation == null )
951         {
952             throw new NullPointerException( "implementation" );
953         }
954         if ( dependency == null )
955         {
956             throw new NullPointerException( "dependency" );
957         }
958 
959         final Dependencies dependencies = this.getDependencies( implementation );
960 
961         if ( dependencies != null )
962         {
963             final Dependency d = dependencies.getDependency( dependency );
964 
965             if ( d != null )
966             {
967                 return "private";
968             }
969         }
970 
971         return null;
972     }
973 
974     /**
975      * Gets all properties of an implementation from the list of modules.
976      *
977      * @param implementation The identifier of the implementation to get all properties of.
978      *
979      * @return All properties of the first matching implementation or {@code null}, if no such implementation is found
980      * or if the first matching implementation does not have any properties.
981      *
982      * @throws NullPointerException if {@code implementation} is {@code null}.
983      *
984      * @see #getModule()
985      * @see #getImplementation( java.lang.String )
986      * @see Implementation#getImplementations()
987      * @see Implementations#getReference()
988      * @see Implementation#getProperties()
989      */
990     public Properties getProperties( final String implementation )
991     {
992         if ( implementation == null )
993         {
994             throw new NullPointerException( "implementation" );
995         }
996 
997         final Properties properties = new Properties();
998         final Specifications specifications = new Specifications();
999         final Implementation impl = this.getImplementation( implementation );
1000         this.collectModelObjects(
1001             impl, null, null, properties, specifications, null, new java.util.HashSet<String>(), true );
1002 
1003         this.collectClassDeclarationModelObjects( impl, null, null, properties, specifications, null );
1004         this.collectSpecifiedModelObjects( specifications, properties );
1005         java.util.Collections.sort( properties.getProperty(), PROPERTY_NAME_COMPARATOR );
1006         return properties.getProperty().isEmpty() ? null : properties;
1007     }
1008 
1009     /**
1010      * Gets all properties specified for an implementation from the list of modules.
1011      *
1012      * @param implementation The identifier of the implementation to return specified properties of.
1013      *
1014      * @return All properties specified for the first matching implementation or {@code null}, if no such implementation
1015      * is found or if the first matching implementation does not have any specified properties.
1016      *
1017      * @throws NullPointerException if {@code implementation} is {@code null}.
1018      *
1019      * @see #getModule()
1020      * @see #getSpecifications( java.lang.String )
1021      * @see Specification#getProperties()
1022      */
1023     public Properties getSpecifiedProperties( final String implementation )
1024     {
1025         if ( implementation == null )
1026         {
1027             throw new NullPointerException( "implementation" );
1028         }
1029 
1030         final Properties properties = new Properties();
1031         final Specifications specs = this.getSpecifications( implementation );
1032 
1033         if ( specs != null )
1034         {
1035             for ( int i = 0, s0 = specs.getSpecification().size(); i < s0; i++ )
1036             {
1037                 final Specification s = specs.getSpecification().get( i );
1038 
1039                 if ( s.getProperties() != null )
1040                 {
1041                     properties.getProperty().addAll( s.getProperties().getProperty() );
1042                 }
1043             }
1044         }
1045 
1046         java.util.Collections.sort( properties.getProperty(), PROPERTY_NAME_COMPARATOR );
1047         return properties.getProperty().isEmpty() ? null : properties;
1048     }
1049 
1050     /**
1051      * Gets the Java modifier name of a property.
1052      *
1053      * @param implementation The identifier of the implementation of the property.
1054      * @param property The name of the property to get the Java modifier name of.
1055      *
1056      * @return The Java modifier name of the property named {@code property} of the first matching implementation
1057      * identified by {@code implementation} or {@code null}, if the implementation or the property is not found.
1058      *
1059      * @throws NullPointerException if {@code implementation} or {@code dependency} is {@code null}.
1060      *
1061      * @since 1.4
1062      *
1063      * @see #getProperties(java.lang.String)
1064      * @see Properties#getProperty(java.lang.String)
1065      */
1066     public String getPropertyJavaModifierName( final String implementation, final String property )
1067     {
1068         if ( implementation == null )
1069         {
1070             throw new NullPointerException( "implementation" );
1071         }
1072         if ( property == null )
1073         {
1074             throw new NullPointerException( "property" );
1075         }
1076 
1077         final Properties properties = this.getProperties( implementation );
1078 
1079         if ( properties != null )
1080         {
1081             final Property p = properties.getProperty( property );
1082 
1083             if ( p != null )
1084             {
1085                 final Properties specified = this.getSpecifiedProperties( implementation );
1086 
1087                 return specified != null && specified.getProperty( property ) != null ? "public" : "private";
1088             }
1089         }
1090 
1091         return null;
1092     }
1093 
1094     /**
1095      * Gets all messages of an implementation from the list of modules.
1096      *
1097      * @param implementation The identifier of the implementation to get all messages of.
1098      *
1099      * @return All messages of the first matching implementation or {@code null}, if no such implementation is found
1100      * or if the first matching implementation does not have any messages.
1101      *
1102      * @throws NullPointerException if {@code implementation} is {@code null}.
1103      *
1104      * @see #getModule()
1105      * @see #getImplementation( java.lang.String )
1106      * @see Implementation#getImplementations()
1107      * @see Implementations#getReference()
1108      * @see Implementation#getMessages()
1109      */
1110     public Messages getMessages( final String implementation )
1111     {
1112         if ( implementation == null )
1113         {
1114             throw new NullPointerException( "implementation" );
1115         }
1116 
1117         final Messages msgs = new Messages();
1118         final Implementation impl = this.getImplementation( implementation );
1119         this.collectModelObjects( impl, null, msgs, null, null, null, new java.util.HashSet<String>(), true );
1120         this.collectClassDeclarationModelObjects( impl, null, msgs, null, null, null );
1121         java.util.Collections.sort( msgs.getMessage(), MESSAGE_NAME_COMPARATOR );
1122         return msgs.getMessage().isEmpty() ? null : msgs;
1123     }
1124 
1125     /**
1126      * Gets the Java modifier name of a message.
1127      *
1128      * @param implementation The identifier of the implementation of the message.
1129      * @param message The name of the message to get the Java modifier name of.
1130      *
1131      * @return The Java modifier name of the message named {@code message} of the first matching implementation
1132      * identified by {@code implementation} or {@code null}, if the implementation or the message is not found.
1133      *
1134      * @throws NullPointerException if {@code implementation} or {@code message} is {@code null}.
1135      *
1136      * @since 1.4
1137      *
1138      * @see #getMessages(java.lang.String)
1139      * @see Messages#getMessage(java.lang.String)
1140      */
1141     public String getMessageJavaModifierName( final String implementation, final String message )
1142     {
1143         if ( implementation == null )
1144         {
1145             throw new NullPointerException( "implementation" );
1146         }
1147         if ( message == null )
1148         {
1149             throw new NullPointerException( "message" );
1150         }
1151 
1152         final Messages messages = this.getMessages( implementation );
1153 
1154         if ( messages != null )
1155         {
1156             final Message m = messages.getMessage( message );
1157 
1158             if ( m != null )
1159             {
1160                 return "private";
1161             }
1162         }
1163 
1164         return null;
1165     }
1166 
1167     /**
1168      * Gets any objects of an implementation from the list of modules.
1169      *
1170      * @param implementation The identifier of the implementation to get any objects of.
1171      *
1172      * @return Any objects of the first matching implementation or {@code null}, if no such implementation is found.
1173      *
1174      * @throws NullPointerException if {@code implementation} is {@code null}.
1175      *
1176      * @see #getModule()
1177      * @see #getImplementation( java.lang.String )
1178      * @see Implementation#getImplementations()
1179      * @see Implementations#getReference()
1180      * @see Implementation#getAny()
1181      *
1182      * @since 1.2
1183      */
1184     public List<Object> getAnyObjects( final String implementation )
1185     {
1186         if ( implementation == null )
1187         {
1188             throw new NullPointerException( "implementation" );
1189         }
1190 
1191         final Implementation impl = this.getImplementation( implementation );
1192         final java.util.List<Object> any = new java.util.LinkedList<Object>();
1193         this.collectModelObjects( impl, null, null, null, null, any, new java.util.HashSet<String>(), true );
1194         this.collectClassDeclarationModelObjects( impl, null, null, null, null, any );
1195         return any;
1196     }
1197 
1198     /**
1199      * Gets all implementations implementing a given specification from the list of modules.
1200      *
1201      * @param specification The identifier of the specification to return all implementations of.
1202      *
1203      * @return All implementations implementing the first matching specification or {@code null}, if no such
1204      * specification is found or if the first matching specification does not have any implementations.
1205      *
1206      * @throws NullPointerException if {@code specification} is {@code null}.
1207      *
1208      * @see #getModule()
1209      * @see #getSpecifications( java.lang.String )
1210      */
1211     public Implementations getImplementations( final String specification )
1212     {
1213         if ( specification == null )
1214         {
1215             throw new NullPointerException( "specification" );
1216         }
1217 
1218         final Implementations implementations = new Implementations();
1219 
1220         for ( int i = 0, s0 = this.getModule().size(); i < s0; i++ )
1221         {
1222             final Module m = this.getModule().get( i );
1223 
1224             if ( m.getImplementations() != null )
1225             {
1226                 for ( int j = 0, s1 = m.getImplementations().getImplementation().size(); j < s1; j++ )
1227                 {
1228                     final Implementation impl = m.getImplementations().getImplementation().get( j );
1229                     final Specifications specs = this.getSpecifications( impl.getIdentifier() );
1230 
1231                     if ( specs != null && specs.getSpecification( specification ) != null )
1232                     {
1233                         implementations.getImplementation().add( impl );
1234                     }
1235                 }
1236             }
1237         }
1238 
1239         return implementations.getImplementation().size() > 0 ? implementations : null;
1240     }
1241 
1242     /**
1243      * Merges this list of modules to a single module.
1244      *
1245      * @param name The name of the module to return.
1246      *
1247      * @return A module holding all model objects from the list.
1248      *
1249      * @throws NullPointerException if {@code name} is {@code null}.
1250      */
1251     public Module getMergedModule( final String name )
1252     {
1253         if ( name == null )
1254         {
1255             throw new NullPointerException( "name" );
1256         }
1257 
1258         final Modules copy = this.clone();
1259         final Module mergedModule = new Module();
1260         mergedModule.setName( name );
1261 
1262         for ( int i = 0, s0 = copy.getModule().size(); i < s0; i++ )
1263         {
1264             final Module m = copy.getModule().get( i );
1265             final java.util.Set<String> referencedMessages = new java.util.HashSet<String>();
1266             final java.util.Set<String> referencedProperties = new java.util.HashSet<String>();
1267 
1268             if ( m.getImplementations() != null )
1269             {
1270                 for ( int j = 0, s1 = m.getImplementations().getImplementation().size(); j < s1; j++ )
1271                 {
1272                     final Implementation impl = m.getImplementations().getImplementation().get( j );
1273                     if ( mergedModule.getImplementations() == null )
1274                     {
1275                         mergedModule.setImplementations( new Implementations() );
1276                     }
1277 
1278                     if ( impl.getMessages() != null && !impl.getMessages().getReference().isEmpty() )
1279                     {
1280                         for ( java.util.Iterator<MessageReference> it = impl.getMessages().getReference().iterator();
1281                               it.hasNext(); )
1282                         {
1283                             final String messageName = it.next().getName();
1284                             impl.getMessages().getMessage().add( m.getMessages().getMessage( messageName ) );
1285                             referencedMessages.add( messageName );
1286                             it.remove();
1287                         }
1288                     }
1289 
1290                     if ( impl.getProperties() != null && !impl.getProperties().getReference().isEmpty() )
1291                     {
1292                         for ( java.util.Iterator<PropertyReference> it = impl.getProperties().getReference().iterator();
1293                               it.hasNext(); )
1294                         {
1295                             final String propertyName = it.next().getName();
1296                             impl.getProperties().getProperty().add( m.getProperties().getProperty( propertyName ) );
1297                             referencedProperties.add( propertyName );
1298                             it.remove();
1299                         }
1300                     }
1301 
1302                     mergedModule.getImplementations().getImplementation().add( impl );
1303                 }
1304             }
1305 
1306             if ( m.getSpecifications() != null )
1307             {
1308                 if ( mergedModule.getSpecifications() == null )
1309                 {
1310                     mergedModule.setSpecifications( new Specifications() );
1311                 }
1312 
1313                 for ( int j = 0, s1 = m.getSpecifications().getSpecification().size(); j < s1; j++ )
1314                 {
1315                     final Specification s = m.getSpecifications().getSpecification().get( j );
1316 
1317                     if ( s.getProperties() != null && !s.getProperties().getReference().isEmpty() )
1318                     {
1319                         for ( java.util.Iterator<PropertyReference> it = s.getProperties().getReference().iterator();
1320                               it.hasNext(); )
1321                         {
1322                             final String propertyName = it.next().getName();
1323                             s.getProperties().getProperty().add( m.getProperties().getProperty( propertyName ) );
1324                             referencedProperties.add( propertyName );
1325                             it.remove();
1326                         }
1327                     }
1328 
1329                     mergedModule.getSpecifications().getSpecification().add( s );
1330                 }
1331             }
1332 
1333             for ( String messageName : referencedMessages )
1334             {
1335                 for ( java.util.Iterator<Message> it = m.getMessages().getMessage().iterator(); it.hasNext(); )
1336                 {
1337                     if ( messageName.equals( it.next().getName() ) )
1338                     {
1339                         it.remove();
1340                         break;
1341                     }
1342                 }
1343             }
1344 
1345             for ( String propertyName : referencedProperties )
1346             {
1347                 for ( java.util.Iterator<Property> it = m.getProperties().getProperty().iterator(); it.hasNext(); )
1348                 {
1349                     if ( propertyName.equals( it.next().getName() ) )
1350                     {
1351                         it.remove();
1352                         break;
1353                     }
1354                 }
1355             }
1356 
1357             if ( m.getProperties() != null && !m.getProperties().getProperty().isEmpty() )
1358             {
1359                 if ( mergedModule.getProperties() == null )
1360                 {
1361                     mergedModule.setProperties( new Properties() );
1362                 }
1363 
1364                 mergedModule.getProperties().getProperty().addAll( m.getProperties().getProperty() );
1365             }
1366 
1367             if ( m.getMessages() != null && !m.getMessages().getMessage().isEmpty() )
1368             {
1369                 if ( mergedModule.getMessages() == null )
1370                 {
1371                     mergedModule.setMessages( new Messages() );
1372                 }
1373 
1374                 mergedModule.getMessages().getMessage().addAll( m.getMessages().getMessage() );
1375             }
1376         }
1377 
1378         return mergedModule;
1379     }
1380 
1381     /**
1382      * Gets the instance of an object from the list of modules.
1383      *
1384      * @param object The object to get the instance of.
1385      *
1386      * @return The instance of {@code object} or {@code null}, if no such instance is found.
1387      *
1388      * @throws NullPointerException if {@code object} is {@code null}.
1389      * @throws ModelObjectException if compiling a name of a referenced type to a {@code JavaTypeName} fails.
1390      *
1391      * @see #getModule()
1392      * @see #getImplementation( java.lang.Object )
1393      * @see #getInstance( java.lang.String )
1394      * @see #createObject(org.jomc.model.Instance instance, java.lang.ClassLoader classLoader)
1395      */
1396     public Instance getInstance( final Object object ) throws ModelObjectException
1397     {
1398         if ( object == null )
1399         {
1400             throw new NullPointerException( "object" );
1401         }
1402 
1403         synchronized ( this.objects )
1404         {
1405             Instance instance = this.objects.get( object );
1406 
1407             if ( instance == null )
1408             {
1409                 final Implementation i = this.getImplementation( object );
1410 
1411                 if ( i != null )
1412                 {
1413                     instance = this.getInstance( i.getIdentifier() );
1414                     if ( instance != null )
1415                     {
1416                         this.objects.put( object, instance );
1417                     }
1418                 }
1419             }
1420 
1421             return instance;
1422         }
1423     }
1424 
1425     /**
1426      * Gets an instance for an implementation from the list of modules.
1427      *
1428      * @param implementation The identifier of the implementation to get an instance for.
1429      *
1430      * @return A new instance for the first matching implementation or {@code null}, if no such implementation is found.
1431      *
1432      * @throws NullPointerException if {@code implementation} is {@code null}.
1433      *
1434      * @see #getModule()
1435      * @see #getImplementation( java.lang.String )
1436      * @see #getDependencies(java.lang.String)
1437      * @see #getProperties(java.lang.String)
1438      * @see #getMessages(java.lang.String)
1439      * @see #getSpecifications(java.lang.String)
1440      * @see #getAnyObjects(java.lang.String)
1441      */
1442     public Instance getInstance( final String implementation )
1443     {
1444         if ( implementation == null )
1445         {
1446             throw new NullPointerException( "implementation" );
1447         }
1448 
1449         final Implementation i = this.getImplementation( implementation );
1450 
1451         if ( i != null && i.getClazz() != null )
1452         {
1453             final Instance instance = new Instance();
1454             instance.setIdentifier( i.getIdentifier() );
1455             instance.setName( i.getName() );
1456             instance.setClazz( i.getClazz() );
1457             instance.setStateless( i.isStateless() );
1458             instance.setDependencies( this.getDependencies( implementation ) );
1459             instance.setProperties( this.getProperties( implementation ) );
1460             instance.setMessages( this.getMessages( implementation ) );
1461             instance.setSpecifications( this.getSpecifications( implementation ) );
1462             instance.getAny().addAll( this.getAnyObjects( implementation ) );
1463             return instance;
1464         }
1465 
1466         return null;
1467     }
1468 
1469     /**
1470      * Gets an instance for an implementation from the list of modules overridden with a given dependency.
1471      *
1472      * @param implementation The identifier of the implementation to get an instance for.
1473      * @param dependency The dependency to use for overriding model objects of the instance.
1474      *
1475      * @return An instance for the first matching implementation with any model objects overridden using
1476      * {@code dependency} or {@code null}, if no such implementation is found.
1477      *
1478      * @throws NullPointerException if {@code implementation} or {@code dependency} is {@code null}.
1479      *
1480      * @see #getModule()
1481      * @see #getInstance( java.lang.String )
1482      */
1483     public Instance getInstance( final String implementation, final Dependency dependency )
1484     {
1485         if ( implementation == null )
1486         {
1487             throw new NullPointerException( "implementation" );
1488         }
1489         if ( dependency == null )
1490         {
1491             throw new NullPointerException( "dependency" );
1492         }
1493 
1494         Instance instance = this.getInstance( implementation );
1495 
1496         if ( instance != null )
1497         {
1498             final Specification dependencySpecification = this.getSpecification( dependency.getIdentifier() );
1499 
1500             if ( dependencySpecification != null && dependencySpecification.getScope() == null )
1501             {
1502                 if ( dependency.getDependencies() != null && !dependency.getDependencies().getDependency().isEmpty() )
1503                 {
1504                     final Dependencies dependencies = new Dependencies();
1505                     dependencies.getDependency().addAll( dependency.getDependencies().getDependency() );
1506 
1507                     if ( instance.getDependencies() != null )
1508                     {
1509                         for ( int i = 0, s0 = instance.getDependencies().getDependency().size(); i < s0; i++ )
1510                         {
1511                             final Dependency d = instance.getDependencies().getDependency().get( i );
1512                             final Dependency td = dependencies.getDependency( d.getName() );
1513 
1514                             if ( td == null )
1515                             {
1516                                 dependencies.getDependency().add( d );
1517                             }
1518                             else
1519                             {
1520                                 this.collectDependencies( d, td );
1521                             }
1522                         }
1523                     }
1524 
1525                     instance.setDependencies( dependencies );
1526                 }
1527 
1528                 if ( dependency.getMessages() != null && !dependency.getMessages().getMessage().isEmpty() )
1529                 {
1530                     final Messages messages = new Messages();
1531                     messages.getMessage().addAll( dependency.getMessages().getMessage() );
1532 
1533                     if ( instance.getMessages() != null )
1534                     {
1535                         for ( int i = 0, s0 = instance.getMessages().getMessage().size(); i < s0; i++ )
1536                         {
1537                             final Message m = instance.getMessages().getMessage().get( i );
1538 
1539                             if ( messages.getMessage( m.getName() ) == null )
1540                             {
1541                                 messages.getMessage().add( m );
1542                             }
1543                         }
1544                     }
1545 
1546                     instance.setMessages( messages );
1547                 }
1548 
1549                 if ( dependency.getProperties() != null && !dependency.getProperties().getProperty().isEmpty() )
1550                 {
1551                     final Properties properties = new Properties();
1552                     properties.getProperty().addAll( dependency.getProperties().getProperty() );
1553 
1554                     if ( instance.getProperties() != null )
1555                     {
1556                         for ( int i = 0, s0 = instance.getProperties().getProperty().size(); i < s0; i++ )
1557                         {
1558                             final Property p = instance.getProperties().getProperty().get( i );
1559 
1560                             if ( properties.getProperty( p.getName() ) == null )
1561                             {
1562                                 properties.getProperty().add( p );
1563                             }
1564                         }
1565                     }
1566 
1567                     instance.setProperties( properties );
1568                 }
1569             }
1570         }
1571 
1572         return instance;
1573     }
1574 
1575     /**
1576      * Creates an object of a given instance from the list of modules.
1577      *
1578      * @param instance The instance to create an object of.
1579      * @param classLoader The class loader to use for creating the object or {@code null}, to use the bootstrap class
1580      * loader.
1581      *
1582      * @return A new object of {@code instance}.
1583      *
1584      * @throws NullPointerException if {@code instance}  is {@code null}.
1585      * @throws ModelObjectException if compiling the name of a referenced type to a {@code JavaTypeName} fails.
1586      * @throws InstantiationException if creating an object fails.
1587      *
1588      * @see #getModule()
1589      * @see Instance#getJavaClass(java.lang.ClassLoader)
1590      * @see Instance#getJavaConstructor(java.lang.ClassLoader)
1591      * @see Instance#getJavaFactoryMethodName()
1592      * @see Instance#getJavaFactoryMethod(java.lang.ClassLoader)
1593      * @see Instance#isJavaClassAssignable(java.lang.ClassLoader)
1594      */
1595     public Object createObject( final Instance instance, final ClassLoader classLoader )
1596         throws ModelObjectException, InstantiationException
1597     {
1598         if ( instance == null )
1599         {
1600             throw new NullPointerException( "instance" );
1601         }
1602 
1603         Object object = null;
1604 
1605         try
1606         {
1607             final java.lang.reflect.Constructor<?> ctor = instance.getJavaConstructor( classLoader );
1608 
1609             if ( ctor != null && instance.isJavaClassAssignable( classLoader ) )
1610             {
1611                 object = instance.getJavaTypeName().getClass( classLoader, true ).newInstance();
1612 
1613                 synchronized ( this.objects )
1614                 {
1615                     this.objects.put( object, instance );
1616                 }
1617             }
1618             else
1619             {
1620                 java.lang.reflect.Method factoryMethod = instance.getJavaFactoryMethod( classLoader );
1621 
1622                 if ( factoryMethod != null )
1623                 {
1624                     if ( java.lang.reflect.Modifier.isStatic( factoryMethod.getModifiers() ) )
1625                     {
1626                         object = factoryMethod.invoke( null, (Object[]) null );
1627 
1628                         if ( object != null )
1629                         {
1630                             synchronized ( this.objects )
1631                             {
1632                                 this.objects.put( object, instance );
1633                             }
1634                         }
1635                     }
1636                     else if ( ctor != null )
1637                     {
1638                         final Object o = ctor.newInstance();
1639 
1640                         synchronized ( this.objects )
1641                         {
1642                             this.objects.put( o, instance );
1643                         }
1644 
1645                         try
1646                         {
1647                             object = factoryMethod.invoke( o, (Object[]) null );
1648                         }
1649                         finally
1650                         {
1651                             synchronized ( this.objects )
1652                             {
1653                                 this.objects.remove( o );
1654 
1655                                 if ( object != null )
1656                                 {
1657                                     this.objects.put( object, instance );
1658                                 }
1659                             }
1660                         }
1661                     }
1662                 }
1663             }
1664 
1665             if ( object == null )
1666             {
1667                 throw new InstantiationException( getMessage(
1668                     instance.getJavaFactoryMethodName() != null
1669                     ? "failedCreatingObjectWithMethod" : "failedCreatingObject",
1670                     instance.getIdentifier(), instance.getJavaTypeName(), instance.getJavaFactoryMethodName() ) );
1671 
1672             }
1673 
1674             return object;
1675         }
1676         catch ( final java.lang.reflect.InvocationTargetException e )
1677         {
1678             final Throwable target = e.getTargetException() != null ? e.getTargetException() : e;
1679             throw (InstantiationException) new InstantiationException(
1680                 getMessage( "exceptionCreatingObject", instance.getIdentifier() ) ).initCause( target );
1681 
1682         }
1683         catch ( final IllegalAccessException e )
1684         {
1685             throw (InstantiationException) new InstantiationException(
1686                 getMessage( "exceptionCreatingObject", instance.getIdentifier() ) ).initCause( e );
1687 
1688         }
1689         catch ( final ClassNotFoundException e )
1690         {
1691             throw (InstantiationException) new InstantiationException(
1692                 getMessage( "exceptionCreatingObject", instance.getIdentifier() ) ).initCause( e );
1693 
1694         }
1695     }
1696 
1697     /** @since 1.2 */
1698     private void collectModelObjects( final Implementation implementation, final Dependencies dependencies,
1699                                       final Messages messages, final Properties properties,
1700                                       final Specifications specifications, final List<Object> any,
1701                                       final java.util.Set<String> seen, final boolean includeDeclared )
1702     {
1703         if ( implementation != null && !seen.contains( implementation.getIdentifier() ) )
1704         {
1705             seen.add( implementation.getIdentifier() );
1706 
1707             if ( includeDeclared )
1708             {
1709                 if ( dependencies != null && implementation.getDependencies() != null )
1710                 {
1711                     for ( int i = 0, s0 = implementation.getDependencies().getDependency().size(); i < s0; i++ )
1712                     {
1713                         final Dependency d = implementation.getDependencies().getDependency().get( i );
1714                         final Dependency dependency = dependencies.getDependency( d.getName() );
1715 
1716                         if ( dependency == null )
1717                         {
1718                             dependencies.getDependency().add( d );
1719                         }
1720                         else
1721                         {
1722                             this.collectDependencies( d, dependency );
1723                         }
1724                     }
1725                 }
1726 
1727                 if ( messages != null && implementation.getMessages() != null )
1728                 {
1729                     for ( int i = 0, s0 = implementation.getMessages().getMessage().size(); i < s0; i++ )
1730                     {
1731                         final Message msg = implementation.getMessages().getMessage().get( i );
1732 
1733                         if ( messages.getMessage( msg.getName() ) == null )
1734                         {
1735                             messages.getMessage().add( msg );
1736                         }
1737                     }
1738 
1739                     if ( !implementation.getMessages().getReference().isEmpty() )
1740                     {
1741                         final Module m = this.getModuleOfImplementation( implementation.getIdentifier() );
1742 
1743                         if ( m != null )
1744                         {
1745                             for ( int i = 0, s0 = implementation.getMessages().getReference().size(); i < s0; i++ )
1746                             {
1747                                 final MessageReference ref = implementation.getMessages().getReference().get( i );
1748 
1749                                 if ( messages.getMessage( ref.getName() ) == null )
1750                                 {
1751                                     Message referenced = m.getMessages().getMessage( ref.getName() );
1752                                     if ( referenced != null )
1753                                     {
1754                                         referenced = referenced.clone();
1755                                         referenced.setDeprecated( ref.isDeprecated() );
1756                                         referenced.setFinal( ref.isFinal() );
1757                                         referenced.setOverride( ref.isOverride() );
1758                                         messages.getMessage().add( referenced );
1759                                     }
1760                                 }
1761                             }
1762                         }
1763                     }
1764                 }
1765 
1766                 if ( properties != null && implementation.getProperties() != null )
1767                 {
1768                     for ( int i = 0, s0 = implementation.getProperties().getProperty().size(); i < s0; i++ )
1769                     {
1770                         final Property p = implementation.getProperties().getProperty().get( i );
1771 
1772                         if ( properties.getProperty( p.getName() ) == null )
1773                         {
1774                             properties.getProperty().add( p );
1775                         }
1776                     }
1777 
1778                     if ( !implementation.getProperties().getReference().isEmpty() )
1779                     {
1780                         final Module m = this.getModuleOfImplementation( implementation.getIdentifier() );
1781 
1782                         if ( m != null )
1783                         {
1784                             for ( int i = 0, s0 = implementation.getProperties().getReference().size(); i < s0; i++ )
1785                             {
1786                                 final PropertyReference ref = implementation.getProperties().getReference().get( i );
1787 
1788                                 if ( properties.getProperty( ref.getName() ) == null )
1789                                 {
1790                                     Property referenced = m.getProperties().getProperty( ref.getName() );
1791                                     if ( referenced != null )
1792                                     {
1793                                         referenced = referenced.clone();
1794                                         referenced.setDeprecated( ref.isDeprecated() );
1795                                         referenced.setFinal( ref.isFinal() );
1796                                         referenced.setOverride( ref.isOverride() );
1797                                         properties.getProperty().add( referenced );
1798                                     }
1799                                 }
1800                             }
1801                         }
1802                     }
1803                 }
1804 
1805                 if ( specifications != null && implementation.getSpecifications() != null )
1806                 {
1807                     for ( int i = 0, s0 = implementation.getSpecifications().getReference().size(); i < s0; i++ )
1808                     {
1809                         final SpecificationReference r = implementation.getSpecifications().getReference().get( i );
1810 
1811                         if ( specifications.getReference( r.getIdentifier() ) == null )
1812                         {
1813                             specifications.getReference().add( r );
1814 
1815                             final Specification s = this.getSpecification( r.getIdentifier() );
1816                             if ( s != null && specifications.getSpecification( s.getIdentifier() ) == null )
1817                             {
1818                                 specifications.getSpecification().add( s );
1819                             }
1820                         }
1821                     }
1822                 }
1823 
1824                 if ( any != null && !implementation.getAny().isEmpty() )
1825                 {
1826                     for ( int i = 0, s0 = implementation.getAny().size(); i < s0; i++ )
1827                     {
1828                         final Object o = implementation.getAny().get( i );
1829 
1830                         if ( o instanceof org.w3c.dom.Element )
1831                         {
1832                             if ( this.getElement( any, (org.w3c.dom.Element) o ) == null )
1833                             {
1834                                 any.add( o );
1835                             }
1836 
1837                             continue;
1838                         }
1839 
1840                         if ( o instanceof javax.xml.bind.JAXBElement<?> )
1841                         {
1842                             if ( this.getElement( any, (javax.xml.bind.JAXBElement<?>) o ) == null )
1843                             {
1844                                 any.add( o );
1845                             }
1846 
1847                             continue;
1848                         }
1849 
1850                         any.add( o );
1851                     }
1852                 }
1853             }
1854 
1855             if ( implementation.getImplementations() != null )
1856             {
1857                 for ( int i = 0, s0 = implementation.getImplementations().getReference().size(); i < s0; i++ )
1858                 {
1859                     final ImplementationReference r = implementation.getImplementations().getReference().get( i );
1860                     this.collectModelObjects( this.getImplementation( r.getIdentifier() ), dependencies, messages,
1861                                               properties, specifications, any, seen, true );
1862 
1863                 }
1864             }
1865         }
1866     }
1867 
1868     /** @since 1.2 */
1869     private void collectClassDeclarationModelObjects( final Implementation implementation,
1870                                                       final Dependencies dependencies, final Messages messages,
1871                                                       final Properties properties, final Specifications specifications,
1872                                                       final List<Object> any )
1873     {
1874         Implementation declaration = null;
1875 
1876         if ( implementation != null && implementation.getClazz() != null && !implementation.isClassDeclaration() )
1877         {
1878             for ( int i = 0, s0 = this.getModule().size(); i < s0; i++ )
1879             {
1880                 final Module m = this.getModule().get( i );
1881 
1882                 if ( m.getImplementations() != null )
1883                 {
1884                     for ( int j = 0, s1 = m.getImplementations().getImplementation().size(); j < s1; j++ )
1885                     {
1886                         final Implementation current = m.getImplementations().getImplementation().get( j );
1887 
1888                         if ( current.getClazz() != null && current.getClazz().equals( implementation.getClazz() )
1889                              && current.isClassDeclaration() )
1890                         {
1891                             declaration = current;
1892                             break;
1893                         }
1894                     }
1895                 }
1896             }
1897         }
1898 
1899         if ( declaration != null )
1900         {
1901             this.collectModelObjects( declaration, dependencies, messages, properties, specifications, any,
1902                                       new java.util.HashSet<String>(), true );
1903 
1904         }
1905     }
1906 
1907     /** @since 1.2 */
1908     private void collectSpecifiedModelObjects( final Specifications specifications, final Properties properties )
1909     {
1910         for ( int i = 0, s0 = specifications.getSpecification().size(); i < s0; i++ )
1911         {
1912             final Specification s = specifications.getSpecification().get( i );
1913 
1914             if ( s.getProperties() != null )
1915             {
1916                 for ( int j = 0, s1 = s.getProperties().getProperty().size(); j < s1; j++ )
1917                 {
1918                     final Property p = s.getProperties().getProperty().get( j );
1919 
1920                     if ( properties.getProperty( p.getName() ) == null )
1921                     {
1922                         properties.getProperty().add( p );
1923                     }
1924                 }
1925             }
1926         }
1927     }
1928 
1929     private void collectDependencies( final Dependency source, final Dependency target )
1930     {
1931         if ( source.getMessages() != null )
1932         {
1933             if ( target.getMessages() == null )
1934             {
1935                 target.setMessages( new Messages() );
1936             }
1937 
1938             for ( int i = 0, s0 = source.getMessages().getMessage().size(); i < s0; i++ )
1939             {
1940                 final Message m = source.getMessages().getMessage().get( i );
1941 
1942                 if ( target.getMessages().getMessage( m.getName() ) == null )
1943                 {
1944                     target.getMessages().getMessage().add( m );
1945                 }
1946             }
1947         }
1948 
1949         if ( source.getProperties() != null )
1950         {
1951             if ( target.getProperties() == null )
1952             {
1953                 target.setProperties( new Properties() );
1954             }
1955 
1956             for ( int i = 0, s0 = source.getProperties().getProperty().size(); i < s0; i++ )
1957             {
1958                 final Property p = source.getProperties().getProperty().get( i );
1959 
1960                 if ( target.getProperties().getProperty( p.getName() ) == null )
1961                 {
1962                     target.getProperties().getProperty().add( p );
1963                 }
1964             }
1965         }
1966 
1967         if ( source.getDependencies() != null )
1968         {
1969             if ( target.getDependencies() == null )
1970             {
1971                 target.setDependencies( new Dependencies() );
1972             }
1973 
1974             for ( int i = 0, s0 = source.getDependencies().getDependency().size(); i < s0; i++ )
1975             {
1976                 final Dependency sd = source.getDependencies().getDependency().get( i );
1977                 final Dependency td = target.getDependencies().getDependency( sd.getName() );
1978 
1979                 if ( td == null )
1980                 {
1981                     target.getDependencies().getDependency().add( sd );
1982                 }
1983                 else
1984                 {
1985                     this.collectDependencies( sd, td );
1986                 }
1987             }
1988         }
1989     }
1990 
1991     private Implementation collectImplementation( final Class<?> clazz ) throws ModelObjectException
1992     {
1993         Implementation i = this.getImplementation( clazz );
1994 
1995         if ( i == null && clazz.getSuperclass() != null )
1996         {
1997             i = this.collectImplementation( clazz.getSuperclass() );
1998         }
1999 
2000         return i;
2001     }
2002 
2003     private org.w3c.dom.Element getElement( final List<Object> list, final org.w3c.dom.Element e )
2004     {
2005         for ( int i = 0, s0 = list.size(); i < s0; i++ )
2006         {
2007             final Object o = list.get( i );
2008 
2009             if ( o instanceof org.w3c.dom.Element )
2010             {
2011                 final org.w3c.dom.Element current = (org.w3c.dom.Element) o;
2012                 if ( ( e.getNamespaceURI() == null
2013                        ? current.getNamespaceURI() == null
2014                        : e.getNamespaceURI().equals( current.getNamespaceURI() ) )
2015                      && ( e.getLocalName() == null
2016                           ? current.getLocalName() == null
2017                           : e.getLocalName().equals( current.getLocalName() ) ) )
2018                 {
2019                     return current;
2020                 }
2021             }
2022         }
2023 
2024         return null;
2025     }
2026 
2027     private javax.xml.bind.JAXBElement<?> getElement( final List<Object> list, final javax.xml.bind.JAXBElement<?> e )
2028     {
2029         for ( int i = 0, s0 = list.size(); i < s0; i++ )
2030         {
2031             final Object o = list.get( i );
2032 
2033             if ( o instanceof javax.xml.bind.JAXBElement<?> )
2034             {
2035                 final javax.xml.bind.JAXBElement<?> current = (javax.xml.bind.JAXBElement<?>) o;
2036                 if ( e.getName().equals( current.getName() ) )
2037                 {
2038                     return current;
2039                 }
2040             }
2041         }
2042 
2043         return null;
2044     }
2045 
2046     private void resolveClasspath( final Module cpModule, final ClassLoader classLoader )
2047     {
2048         for ( int i = 0, s0 = this.getModule().size(); i < s0; i++ )
2049         {
2050             final Module m = this.getModule().get( i );
2051 
2052             if ( m.getSpecifications() != null )
2053             {
2054                 this.resolveClasspath( m.getSpecifications(), cpModule, classLoader );
2055             }
2056 
2057             if ( m.getImplementations() != null )
2058             {
2059                 this.resolveClasspath( m.getImplementations(), cpModule, classLoader );
2060             }
2061         }
2062     }
2063 
2064     private void resolveClasspath( final SpecificationReference ref, final Module cpModule,
2065                                    final ClassLoader classLoader )
2066     {
2067         if ( this.getSpecification( ref.getIdentifier() ) == null )
2068         {
2069             this.resolveClasspath( ref.getIdentifier(), cpModule, classLoader );
2070         }
2071     }
2072 
2073     private void resolveClasspath( final Specifications specifications, final Module cpModule,
2074                                    final ClassLoader classLoader )
2075     {
2076         for ( int i = 0, s0 = specifications.getSpecification().size(); i < s0; i++ )
2077         {
2078             final Specification s = specifications.getSpecification().get( i );
2079 
2080             if ( s.getClazz() != null )
2081             {
2082                 this.resolveClasspath( s, cpModule, classLoader );
2083             }
2084         }
2085         for ( int i = 0, s0 = specifications.getReference().size(); i < s0; i++ )
2086         {
2087             final SpecificationReference ref = specifications.getReference().get( i );
2088             this.resolveClasspath( ref, cpModule, classLoader );
2089         }
2090     }
2091 
2092     private void resolveClasspath( final Implementations implementations, final Module cpModule,
2093                                    final ClassLoader classLoader )
2094     {
2095         for ( int i = 0, s0 = implementations.getImplementation().size(); i < s0; i++ )
2096         {
2097             final Implementation implementation = implementations.getImplementation().get( i );
2098 
2099             if ( implementation.getSpecifications() != null )
2100             {
2101                 this.resolveClasspath( implementation.getSpecifications(), cpModule, classLoader );
2102             }
2103 
2104             if ( implementation.getDependencies() != null )
2105             {
2106                 this.resolveClasspath( implementation.getDependencies(), cpModule, classLoader );
2107             }
2108         }
2109     }
2110 
2111     private void resolveClasspath( final Dependencies dependencies, final Module cpModule,
2112                                    final ClassLoader classLoader )
2113     {
2114         for ( int i = 0, s0 = dependencies.getDependency().size(); i < s0; i++ )
2115         {
2116             final Dependency dependency = dependencies.getDependency().get( i );
2117             this.resolveClasspath( dependency, cpModule, classLoader );
2118 
2119             if ( dependency.getDependencies() != null )
2120             {
2121                 this.resolveClasspath( dependency.getDependencies(), cpModule, classLoader );
2122             }
2123         }
2124     }
2125 
2126     private boolean resolveClasspath( final String identifier, final Module cpModule, final ClassLoader classLoader )
2127     {
2128         boolean classpathSpecification = false;
2129         Specification specification = cpModule.getSpecifications() == null
2130                                       ? null : cpModule.getSpecifications().getSpecification( identifier );
2131 
2132         if ( specification == null )
2133         {
2134             try
2135             {
2136                 final JavaTypeName javaTypeName = JavaTypeName.parse( identifier );
2137                 final Class<?> classpathSpec = javaTypeName.getClass( classLoader, false );
2138 
2139                 if ( java.lang.reflect.Modifier.isPublic( classpathSpec.getModifiers() ) )
2140                 {
2141                     classpathSpecification = true;
2142                     String vendor = null;
2143                     String version = null;
2144 
2145                     if ( classpathSpec.getPackage() != null )
2146                     {
2147                         vendor = classpathSpec.getPackage().getSpecificationVendor();
2148                         version = classpathSpec.getPackage().getSpecificationVersion();
2149                     }
2150 
2151                     specification = new Specification();
2152                     specification.setIdentifier( identifier );
2153                     specification.setClazz( javaTypeName.getName( true ) );
2154                     specification.setMultiplicity( Multiplicity.MANY );
2155                     specification.setVendor( vendor );
2156                     specification.setVersion( version );
2157 
2158                     if ( cpModule.getSpecifications() == null )
2159                     {
2160                         cpModule.setSpecifications( new Specifications() );
2161                     }
2162 
2163                     cpModule.getSpecifications().getSpecification().add( specification );
2164 
2165                     this.resolveClasspath( specification, cpModule, classLoader );
2166                 }
2167             }
2168             catch ( final ClassNotFoundException e )
2169             {
2170                 classpathSpecification = false;
2171             }
2172             catch ( final java.text.ParseException e )
2173             {
2174                 classpathSpecification = false;
2175             }
2176         }
2177 
2178         return classpathSpecification;
2179     }
2180 
2181     private boolean resolveClasspath( final Specification specification, final Module cpModule,
2182                                       final ClassLoader classLoader )
2183     {
2184         boolean classpathImplementation = false;
2185         Implementation implementation =
2186             cpModule.getImplementations() == null ? null
2187             : cpModule.getImplementations().getImplementation( specification.getIdentifier() );
2188 
2189         if ( implementation == null )
2190         {
2191             implementation = this.getImplementation( specification.getIdentifier() );
2192         }
2193 
2194         if ( implementation == null )
2195         {
2196             String name = null;
2197 
2198             try
2199             {
2200                 final JavaTypeName javaTypeName = JavaTypeName.parse( specification.getClazz() );
2201                 final Class<?> classpathImpl = javaTypeName.getClass( classLoader, false );
2202 
2203                 if ( java.lang.reflect.Modifier.isPublic( classpathImpl.getModifiers() ) )
2204                 {
2205                     if ( !java.lang.reflect.Modifier.isAbstract( classpathImpl.getModifiers() ) )
2206                     {
2207                         try
2208                         {
2209                             classpathImpl.getConstructor( NO_CLASSES );
2210                             name = "init";
2211                             classpathImplementation = true;
2212                         }
2213                         catch ( final NoSuchMethodException e )
2214                         {
2215                             classpathImplementation = false;
2216                         }
2217                     }
2218 
2219                     if ( !classpathImplementation )
2220                     {
2221                         final char[] c = classpathImpl.getName().substring(
2222                             classpathImpl.getPackage().getName().length() + 1 ).toCharArray();
2223 
2224                         name = String.valueOf( c );
2225                         c[0] = Character.toUpperCase( c[0] );
2226 
2227                         if ( this.checkFactoryMethod( classpathImpl, classpathImpl, "getDefault" ) )
2228                         {
2229                             name = "default";
2230                             classpathImplementation = true;
2231                         }
2232                         else if ( this.checkFactoryMethod( classpathImpl, classpathImpl, "getInstance" ) )
2233                         {
2234                             name = "instance";
2235                             classpathImplementation = true;
2236                         }
2237                         else if ( this.checkFactoryMethod( classpathImpl, classpathImpl, "get" + String.valueOf( c ) ) )
2238                         {
2239                             classpathImplementation = true;
2240                         }
2241 
2242                     }
2243 
2244                     if ( classpathImplementation
2245                          && this.getImplementation( specification.getIdentifier(), name ) == null )
2246                     {
2247                         String vendor = null;
2248                         String version = null;
2249                         if ( classpathImpl.getPackage() != null )
2250                         {
2251                             vendor = classpathImpl.getPackage().getImplementationVendor();
2252                             version = classpathImpl.getPackage().getImplementationVersion();
2253                         }
2254 
2255                         implementation = new Implementation();
2256                         implementation.setVendor( vendor );
2257                         implementation.setFinal( true );
2258                         implementation.setName( name );
2259                         implementation.setIdentifier( specification.getIdentifier() );
2260                         implementation.setClazz( javaTypeName.getName( true ) );
2261                         implementation.setVersion( version );
2262 
2263                         final Specifications implemented = new Specifications();
2264                         final SpecificationReference ref = new SpecificationReference();
2265                         ref.setIdentifier( specification.getIdentifier() );
2266                         ref.setVersion( specification.getVersion() );
2267                         implemented.getReference().add( ref );
2268                         implementation.setSpecifications( implemented );
2269 
2270                         if ( cpModule.getImplementations() == null )
2271                         {
2272                             cpModule.setImplementations( new Implementations() );
2273                         }
2274 
2275                         cpModule.getImplementations().getImplementation().add( implementation );
2276                     }
2277                 }
2278             }
2279             catch ( final ClassNotFoundException e )
2280             {
2281                 classpathImplementation = false;
2282             }
2283             catch ( final java.text.ParseException e )
2284             {
2285                 classpathImplementation = false;
2286             }
2287         }
2288 
2289         return classpathImplementation;
2290     }
2291 
2292     private boolean checkFactoryMethod( final Class<?> clazz, final Class<?> type, final String methodName )
2293     {
2294         boolean factoryMethod = false;
2295 
2296         try
2297         {
2298             final java.lang.reflect.Method m = clazz.getMethod( methodName, (Class[]) null );
2299             factoryMethod = java.lang.reflect.Modifier.isStatic( m.getModifiers() )
2300                             && type.isAssignableFrom( m.getReturnType() );
2301 
2302         }
2303         catch ( final NoSuchMethodException e )
2304         {
2305             factoryMethod = false;
2306         }
2307 
2308         return factoryMethod;
2309     }
2310 
2311     private static String getMessage( final Throwable t )
2312     {
2313         return t != null
2314                ? t.getMessage() != null && t.getMessage().trim().length() > 0
2315                  ? t.getMessage()
2316                  : getMessage( t.getCause() )
2317                : null;
2318 
2319     }
2320 
2321     private static String getMessage( final String key, final Object... args )
2322     {
2323         return java.text.MessageFormat.format( java.util.ResourceBundle.getBundle(
2324             Modules.class.getName().replace( '.', '/' ), java.util.Locale.getDefault() ).
2325             getString( key ), args );
2326 
2327     }
2328       
2329 }