EMMA Coverage Report (generated Mon Apr 22 06:35:53 CEST 2013)
[all classes][org.jomc.model]

COVERAGE SUMMARY FOR SOURCE FILE [Modules.java]

nameclass, %method, %block, %line, %
Modules.java100% (7/7)51%  (35/68)35%  (1206/3472)32%  (227.5/704)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Modules$6100% (1/1)50%  (1/2)27%  (3/11)50%  (1/2)
compare (JavaTypeName, JavaTypeName): int 0%   (0/1)0%   (0/8)0%   (0/1)
Modules$6 (): void 100% (1/1)100% (3/3)100% (1/1)
     
class Modules100% (1/1)43%  (24/56)34%  (1158/3416)31%  (216.5/692)
Modules (Map): void 0%   (0/1)0%   (0/18)0%   (0/6)
Modules (Modules): void 0%   (0/1)0%   (0/24)0%   (0/7)
Modules (Modules, Map): void 0%   (0/1)0%   (0/31)0%   (0/9)
checkFactoryMethod (Class, Class, String): boolean 0%   (0/1)0%   (0/27)0%   (0/7)
collectImplementation (Class): Implementation 0%   (0/1)0%   (0/16)0%   (0/4)
createObject (Instance, ClassLoader): Object 0%   (0/1)0%   (0/263)0%   (0/39)
getClasspathModule (String, ClassLoader): Module 0%   (0/1)0%   (0/48)0%   (0/8)
getDefaultClasspathModuleName (): String 0%   (0/1)0%   (0/8)0%   (0/3)
getDependencyJavaModifierName (String, String): String 0%   (0/1)0%   (0/30)0%   (0/10)
getDependencyJavaTypeName (String, String): JavaTypeName 0%   (0/1)0%   (0/83)0%   (0/19)
getElement (List, Element): Element 0%   (0/1)0%   (0/50)0%   (0/7)
getElement (List, JAXBElement): JAXBElement 0%   (0/1)0%   (0/30)0%   (0/7)
getImplementation (Class): Implementation 0%   (0/1)0%   (0/38)0%   (0/9)
getImplementation (Object): Implementation 0%   (0/1)0%   (0/5)0%   (0/1)
getImplementation (String, String): Implementation 0%   (0/1)0%   (0/26)0%   (0/8)
getImplementedJavaTypeNames (String): List 0%   (0/1)0%   (0/60)0%   (0/14)
getInstance (Object): Instance 0%   (0/1)0%   (0/48)0%   (0/12)
getMergedModule (String): Module 0%   (0/1)0%   (0/333)0%   (0/66)
getMessage (String, Object []): String 0%   (0/1)0%   (0/12)0%   (0/1)
getMessage (Throwable): String 0%   (0/1)0%   (0/19)0%   (0/1)
getMessageJavaModifierName (String, String): String 0%   (0/1)0%   (0/30)0%   (0/10)
getPropertyJavaModifierName (String, String): String 0%   (0/1)0%   (0/42)0%   (0/11)
getSpecification (Class): Specification 0%   (0/1)0%   (0/38)0%   (0/9)
getSpecifiedProperties (String): Properties 0%   (0/1)0%   (0/56)0%   (0/11)
resolveClasspath (Dependencies, Module, ClassLoader): void 0%   (0/1)0%   (0/32)0%   (0/6)
resolveClasspath (Implementations, Module, ClassLoader): void 0%   (0/1)0%   (0/36)0%   (0/7)
resolveClasspath (Module, ClassLoader): void 0%   (0/1)0%   (0/36)0%   (0/7)
resolveClasspath (Specification, Module, ClassLoader): boolean 0%   (0/1)0%   (0/211)0%   (0/56)
resolveClasspath (SpecificationReference, Module, ClassLoader): void 0%   (0/1)0%   (0/13)0%   (0/3)
resolveClasspath (Specifications, Module, ClassLoader): void 0%   (0/1)0%   (0/49)0%   (0/8)
resolveClasspath (String, Module, ClassLoader): boolean 0%   (0/1)0%   (0/94)0%   (0/28)
setDefaultClasspathModuleName (String): void 0%   (0/1)0%   (0/3)0%   (0/2)
collectDependencies (Dependency, Dependency): void 100% (1/1)7%   (10/134)17%  (4/24)
collectSpecifiedModelObjects (Specifications, Properties): void 100% (1/1)42%  (21/50)50%  (4/8)
collectModelObjects (Implementation, Dependencies, Messages, Properties, Spec... 100% (1/1)57%  (226/398)52%  (36/69)
copyModule (List, List): void 100% (1/1)64%  (25/39)88%  (7/8)
getModule (String): Module 100% (1/1)73%  (24/33)69%  (4.8/7)
getModuleOfSpecification (String): Module 100% (1/1)75%  (27/36)69%  (4.8/7)
getSpecification (String): Specification 100% (1/1)76%  (29/38)76%  (6.8/9)
getModuleOfImplementation (String): Module 100% (1/1)81%  (29/36)71%  (5/7)
getImplementation (String): Implementation 100% (1/1)82%  (31/38)78%  (7/9)
getDependencies (String): Dependencies 100% (1/1)85%  (40/47)87%  (7/8)
getMessages (String): Messages 100% (1/1)85%  (40/47)87%  (7/8)
getAnyObjects (String): List 100% (1/1)86%  (32/37)86%  (6/7)
getInstance (String, Dependency): Instance 100% (1/1)87%  (175/201)87%  (33/38)
getProperties (String): Properties 100% (1/1)87%  (48/55)89%  (9/10)
getInstance (String): Instance 100% (1/1)90%  (61/68)88%  (14/16)
getSpecifications (String): Specifications 100% (1/1)91%  (50/55)89%  (8/9)
getImplementations (String): Implementations 100% (1/1)93%  (69/74)92%  (11/12)
<static initializer> 100% (1/1)100% (28/28)100% (7/7)
Modules (): void 100% (1/1)100% (8/8)100% (3/3)
clone (): Modules 100% (1/1)100% (17/17)100% (5/5)
collectClassDeclarationModelObjects (Implementation, Dependencies, Messages, ... 100% (1/1)100% (79/79)100% (13/13)
getImplementations (): Implementations 100% (1/1)100% (39/39)100% (6/6)
getModule (): List 100% (1/1)100% (11/11)100% (3/3)
getSpecifications (): Specifications 100% (1/1)100% (39/39)100% (6/6)
     
class Modules$1100% (1/1)100% (2/2)100% (9/9)100% (2/2)
Modules$1 (): void 100% (1/1)100% (3/3)100% (1/1)
compare (Dependency, Dependency): int 100% (1/1)100% (6/6)100% (1/1)
     
class Modules$2100% (1/1)100% (2/2)100% (9/9)100% (2/2)
Modules$2 (): void 100% (1/1)100% (3/3)100% (1/1)
compare (Message, Message): int 100% (1/1)100% (6/6)100% (1/1)
     
class Modules$3100% (1/1)100% (2/2)100% (9/9)100% (2/2)
Modules$3 (): void 100% (1/1)100% (3/3)100% (1/1)
compare (Property, Property): int 100% (1/1)100% (6/6)100% (1/1)
     
class Modules$4100% (1/1)100% (2/2)100% (9/9)100% (2/2)
Modules$4 (): void 100% (1/1)100% (3/3)100% (1/1)
compare (Specification, Specification): int 100% (1/1)100% (6/6)100% (1/1)
     
class Modules$5100% (1/1)100% (2/2)100% (9/9)100% (2/2)
Modules$5 (): void 100% (1/1)100% (3/3)100% (1/1)
compare (SpecificationReference, SpecificationReference): int 100% (1/1)100% (6/6)100% (1/1)

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.22 at 06:46:06 AM CEST 
6//
7 
8 
9package org.jomc.model;
10 
11import java.util.ArrayList;
12import java.util.Iterator;
13import java.util.List;
14import javax.annotation.Generated;
15import javax.xml.bind.annotation.XmlAccessType;
16import javax.xml.bind.annotation.XmlAccessorType;
17import javax.xml.bind.annotation.XmlElement;
18import 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-22T06:46:06+02:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-2")
47public 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-22T06:46:06+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-22T06:46:06+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-22T06:46:06+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-22T06:46:06+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}

[all classes][org.jomc.model]
EMMA 2.1.5320 (stable) (C) Vladimir Roubtsov