001    //
002    // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 
003    // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
004    // Any modifications to this file will be lost upon recompilation of the source schema. 
005    // Generated on: 2009.09.21 at 10:35:38 PM UTC 
006    //
007    
008    
009    package org.jomc.model;
010    
011    import java.util.ArrayList;
012    import java.util.Iterator;
013    import java.util.List;
014    import javax.annotation.Generated;
015    import javax.xml.bind.annotation.XmlAccessType;
016    import javax.xml.bind.annotation.XmlAccessorType;
017    import javax.xml.bind.annotation.XmlType;
018    
019    
020    /**
021     * List of modules.
022     * <p><b>Queries</b><ul>
023     * <li>{@link #getMergedModule() }</li>
024     * <li>{@link #getSpecifications() }</li>
025     * <li>{@link #getSpecification(java.lang.String) }</li>
026     * <li>{@link #getSpecification(java.lang.Class) }</li>
027     * <li>{@link #getModuleOfSpecification(java.lang.String) }</li>
028     * <li>{@link #getImplementations() }</li>
029     * <li>{@link #getImplementation(java.lang.String) }</li>
030     * <li>{@link #getImplementation(java.lang.Class) }</li>
031     * <li>{@link #getModuleOfImplementation(java.lang.String) }</li>
032     * <li>{@link #getImplementation(java.lang.String, java.lang.String) }</li>
033     * <li>{@link #getImplementations(java.lang.String) }</li>
034     * <li>{@link #getDependencies(java.lang.String) }</li>
035     * <li>{@link #getMessages(java.lang.String) }</li>
036     * <li>{@link #getProperties(java.lang.String) }</li>
037     * <li>{@link #getSpecifiedProperties(java.lang.String) }</li>
038     * </ul></p>
039     * 
040     * @see Module
041     * 
042     * 
043     * 
044     */
045    @XmlAccessorType(XmlAccessType.FIELD)
046    @XmlType(name = "Modules", propOrder = {
047        "module"
048    })
049    @Generated(value = "com.sun.tools.xjc.Driver", date = "2009-09-21T10:35:38+00:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-833")
050    public class Modules
051        extends ModelObject
052        implements Cloneable
053    {
054    
055        @Generated(value = "com.sun.tools.xjc.Driver", date = "2009-09-21T10:35:38+00:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-833")
056        protected List<Module> module;
057    
058        /**
059         * Creates a new {@code Modules} instance.
060         * 
061         */
062        public Modules() {
063             // CC-XJC Version 1.0 Build 2009-09-18T15:48:40+0000
064            super();
065        }
066    
067        /**
068         * Creates a new {@code Modules} instance by deeply copying a given instance.
069         * 
070         * @param o
071         *     The instance to copy or {@code null}.
072         */
073        public Modules(final Modules o) {
074             // CC-XJC Version 1.0 Build 2009-09-18T15:48:40+0000
075            super(o);
076            if (o!= null) {
077                {
078                    // 'Module' collection.
079                    copyModule(o.getModule(), getModule());
080                }
081            }
082        }
083    
084        /**
085         * Gets the value of the module property.
086         * 
087         * <p>
088         * This accessor method returns a reference to the live list,
089         * not a snapshot. Therefore any modification you make to the
090         * returned list will be present inside the JAXB object.
091         * This is why there is not a <CODE>set</CODE> method for the module property.
092         * 
093         * <p>
094         * For example, to add a new item, do as follows:
095         * <pre>
096         *    getModule().add(newItem);
097         * </pre>
098         * 
099         * 
100         * <p>
101         * Objects of the following type(s) are allowed in the list
102         * {@link Module }
103         * 
104         * 
105         */
106        @Generated(value = "com.sun.tools.xjc.Driver", date = "2009-09-21T10:35:38+00:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-833")
107        public List<Module> getModule() {
108            if (module == null) {
109                module = new ArrayList<Module>();
110            }
111            return this.module;
112        }
113    
114        /**
115         * Copies all values of property {@code Module} deeply.
116         * 
117         * @param target
118         *     The target to copy {@code source} to.
119         * @param source
120         *     The source to copy from.
121         * @throws NullPointerException
122         *     if {@code source} or {@code target} is {@code null}.
123         */
124        @Generated(value = "com.sun.tools.xjc.Driver", date = "2009-09-21T10:35:38+00:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-833")
125        private static void copyModule(final List<Module> source, final List<Module> target) {
126            // CC-XJC Version 1.0 Build 2009-09-18T15:48:40+0000
127            if (!source.isEmpty()) {
128                for (Iterator it = source.iterator(); it.hasNext(); ) {
129                    final Object next = it.next();
130                    if (next instanceof Module) {
131                        // CClassInfo: org.jomc.model.Module
132                        target.add(((Module) next).clone());
133                        continue;
134                    }
135                    // Please report this at https://apps.sourceforge.net/mantisbt/ccxjc/
136                    throw new AssertionError((("Unexpected instance '"+ next)+"' for property 'Module' of class 'org.jomc.model.Modules'."));
137                }
138            }
139        }
140    
141        /**
142         * Creates and returns a deep copy of this object.
143         * 
144         * 
145         * @return
146         *     A deep copy of this object.
147         */
148        @Override
149        @Generated(value = "com.sun.tools.xjc.Driver", date = "2009-09-21T10:35:38+00:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-833")
150        public Modules clone() {
151             // CC-XJC Version 1.0 Build 2009-09-18T15:48:40+0000
152            return new Modules(this);
153        }
154        
155        /**
156         * Gets a module for a given name from this list of modules.
157         *
158         * @param name The name of the module to return.
159         *
160         * @return The module with name {@code name} from the list or {@code null},
161         * if no module matching {@code name} is found.
162         *
163         * @throws NullPointerException if {@code name} is {@code null}.
164         *
165         * @see #getModule()
166         */
167        public Module getModule( final String name )
168        {
169            if ( name == null )
170            {
171                throw new NullPointerException( "name" );
172            }
173    
174            for ( Module m : this.getModule() )
175            {
176                if ( m.getName().equals( name ) )
177                {
178                    return m;
179                }
180            }
181    
182            return null;
183        }
184    
185        /**
186         * Gets all specifications declared in this list of modules.
187         *
188         * @return All specifications declared in the list or {@code null}, if no
189         * specifications are declared.
190         *
191         * @see #getModule()
192         */
193        public Specifications getSpecifications()
194        {
195            final Specifications specifications = new Specifications();
196            for ( Module m : this.getModule() )
197            {
198                if ( m.getSpecifications() != null )
199                {
200                    specifications.getSpecification().addAll( m.getSpecifications().getSpecification() );
201                }
202            }
203    
204            return specifications.getSpecification().isEmpty() ? null : specifications;
205        }
206    
207        /**
208         * Gets all implementations declared in this list of modules.
209         *
210         * @return All implementations declared in the list or {@code null}, if no
211         * implementations are declared.
212         *
213         * @see #getModule()
214         */
215        public Implementations getImplementations()
216        {
217            final Implementations implementations = new Implementations();
218            for ( Module m : this.getModule() )
219            {
220                if ( m.getImplementations() != null )
221                {
222                    implementations.getImplementation().addAll( m.getImplementations().getImplementation() );
223                }
224            }
225    
226            return implementations.getImplementation().isEmpty() ? null : implementations;
227        }
228    
229        /**
230         * Gets the module declaring a given specification from this list of modules.
231         *
232         * @param specification The identifier of the specification whose declaring module to return.
233         *
234         * @return The module declaring {@code specification} from the list or {@code null}, if no module
235         * is found declaring {@code specification}.
236         *
237         * @throws NullPointerException if {@code specification} is {@code null}.
238         *
239         * @see #getModule()
240         */
241        public Module getModuleOfSpecification( final String specification )
242        {
243            if ( specification == null )
244            {
245                throw new NullPointerException( "specification" );
246            }
247    
248            for ( Module m : this.getModule() )
249            {
250                if ( m.getSpecifications() != null )
251                {
252                    for ( Specification s : m.getSpecifications().getSpecification() )
253                    {
254                        if ( specification.equals( s.getIdentifier() ) )
255                        {
256                            return m;
257                        }
258                    }
259                }
260            }
261    
262            return null;
263        }
264    
265        /**
266         * Gets the module declaring a given implementation from this list of modules.
267         *
268         * @param implementation The identifier of the implementation whose declaring module to return.
269         *
270         * @return The module declaring {@code implementation} from the list or {@code null}, if no module
271         * is found declaring {@code implementation}.
272         *
273         * @throws NullPointerException if {@code implementation} is {@code null}.
274         *
275         * @see #getModule()
276         */
277        public Module getModuleOfImplementation( final String implementation )
278        {
279            if ( implementation == null )
280            {
281                throw new NullPointerException( "implementation" );
282            }
283    
284            for ( Module m : this.getModule() )
285            {
286                if ( m.getImplementations() != null )
287                {
288                    for ( Implementation i : m.getImplementations().getImplementation() )
289                    {
290                        if ( implementation.equals( i.getIdentifier() ) )
291                        {
292                            return m;
293                        }
294                    }
295                }
296            }
297    
298            return null;
299        }
300    
301        /**
302         * Gets a specification for a given identifier from this list of modules.
303         *
304         * @param specification The identifier of the specification to return.
305         *
306         * @return The specification identified by {@code specification} from the list or {@code null},
307         * if no specification matching {@code specification} is found.
308         *
309         * @throws NullPointerException if {@code specification} is {@code null}.
310         *
311         * @see #getModule()
312         */
313        public Specification getSpecification( final String specification )
314        {
315            if ( specification == null )
316            {
317                throw new NullPointerException( "specification" );
318            }
319    
320            for ( Module m : this.getModule() )
321            {
322                if ( m.getSpecifications() != null )
323                {
324                    final Specification s = m.getSpecifications().getSpecification( specification );
325                    if ( s != null )
326                    {
327                        return s;
328                    }
329                }
330            }
331    
332            return null;
333        }
334    
335        /**
336         * Gets a specification for a given class from this list of modules.
337         *
338         * @param specification The class of the specification to return.
339         *
340         * @return The specification identified by {@code specification} from the list or {@code null},
341         * if no specification matching {@code specification} is found.
342         *
343         * @throws NullPointerException if {@code specification} is {@code null}.
344         *
345         * @see #getModule()
346         */
347        public Specification getSpecification( final Class specification )
348        {
349            if ( specification == null )
350            {
351                throw new NullPointerException( "specification" );
352            }
353    
354            for ( Module m : this.getModule() )
355            {
356                if ( m.getSpecifications() != null )
357                {
358                    final Specification s = m.getSpecifications().getSpecification( specification );
359                    if ( s != null )
360                    {
361                        return s;
362                    }
363                }
364            }
365    
366            return null;
367        }
368    
369        /**
370         * Gets all specifications an implementation implements from this list of modules.
371         *
372         * @param implementation The identifier of the implementation to get all implemented specifications of.
373         *
374         * @return List of all specifications implemented by {@code implementation} from the list or {@code null}, if no
375         * implementation matching {@code implementation} is found.
376         *
377         * @throws NullPointerException if {@code implementation} is {@code null}.
378         *
379         * @see #getModule()
380         */
381        public Specifications getSpecifications( final String implementation )
382        {
383            if ( implementation == null )
384            {
385                throw new NullPointerException( "implementation" );
386            }
387    
388            final Specifications specs = new Specifications();
389            this.collectSpecifications( implementation, specs );
390    
391            Implementation declaration = null;
392            final Implementation impl = this.getImplementation( implementation );
393    
394            if ( impl != null && impl.getClazz() != null && !impl.getIdentifier().equals( impl.getClazz() ) )
395            {
396                for ( Module m : this.getModule() )
397                {
398                    if ( m.getImplementations() != null )
399                    {
400                        for ( Implementation i : m.getImplementations().getImplementation() )
401                        {
402                            if ( i.getClazz() != null && i.getClazz().equals( i.getIdentifier() ) &&
403                                 i.getClazz().equals( impl.getClazz() ) )
404                            {
405                                declaration = i;
406                                break;
407                            }
408                        }
409                    }
410                }
411            }
412    
413            if ( declaration != null )
414            {
415                final Specifications declaredSpecifications = this.getSpecifications( declaration.getIdentifier() );
416                if ( declaredSpecifications != null )
417                {
418                    for ( SpecificationReference r : declaredSpecifications.getReference() )
419                    {
420                        if ( specs.getReference( r.getIdentifier() ) == null )
421                        {
422                            specs.getReference().add( r );
423                            final Specification s = declaredSpecifications.getSpecification( r.getIdentifier() );
424                            if ( s != null )
425                            {
426                                specs.getSpecification().add( s );
427                            }
428                        }
429                    }
430                }
431            }
432    
433            java.util.Collections.sort( specs.getSpecification(), new java.util.Comparator<Specification>()
434            {
435    
436                public int compare( final Specification o1, final Specification o2 )
437                {
438                    return o1.getIdentifier().compareTo( o2.getIdentifier() );
439                }
440    
441            } );
442    
443            java.util.Collections.sort( specs.getReference(), new java.util.Comparator<SpecificationReference>()
444            {
445    
446                public int compare( final SpecificationReference o1, final SpecificationReference o2 )
447                {
448                    return o1.getIdentifier().compareTo( o2.getIdentifier() );
449                }
450    
451            } );
452    
453            return specs.getSpecification().isEmpty() && specs.getReference().isEmpty() ? null : specs;
454        }
455    
456        private void collectSpecifications( final String implementation, final Specifications specifications )
457        {
458            final Implementation i = this.getImplementation( implementation );
459    
460            if ( i != null )
461            {
462                if ( i.getSpecifications() != null )
463                {
464                    for ( SpecificationReference r : i.getSpecifications().getReference() )
465                    {
466                        if ( specifications.getReference( r.getIdentifier() ) == null )
467                        {
468                            specifications.getReference().add( r );
469    
470                            final Specification s = this.getSpecification( r.getIdentifier() );
471                            if ( s != null && specifications.getSpecification( s.getIdentifier() ) == null )
472                            {
473                                specifications.getSpecification().add( s );
474                            }
475                        }
476                    }
477                }
478    
479                if ( i.getParent() != null )
480                {
481                    this.collectSpecifications( i.getParent(), specifications );
482                }
483            }
484        }
485    
486        /**
487         * Gets an implementation for a given identifier from this list of modules.
488         *
489         * @param implementation The identifier of the implementation to return.
490         *
491         * @return The implementation identified by {@code implementation} from the list or {@code null},
492         * if no implementation matching {@code implementation} is found.
493         *
494         * @throws NullPointerException if {@code implementation} is {@code null}.
495         *
496         * @see #getModule()
497         */
498        public Implementation getImplementation( final String implementation )
499        {
500            if ( implementation == null )
501            {
502                throw new NullPointerException( "implementation" );
503            }
504    
505            for ( Module m : this.getModule() )
506            {
507                if ( m.getImplementations() != null )
508                {
509                    final Implementation i = m.getImplementations().getImplementation( implementation );
510                    if ( i != null )
511                    {
512                        return i;
513                    }
514                }
515            }
516    
517            return null;
518        }
519    
520        /**
521         * Gets an implementation for a given class from this list of modules.
522         *
523         * @param implementation The class of the implementation to return.
524         *
525         * @return The implementation identified by {@code implementation} from the list or {@code null},
526         * if no implementation matching {@code implementation} is found.
527         *
528         * @throws NullPointerException if {@code implementation} is {@code null}.
529         *
530         * @see #getModule()
531         */
532        public Implementation getImplementation( final Class implementation )
533        {
534            if ( implementation == null )
535            {
536                throw new NullPointerException( "implementation" );
537            }
538    
539            for ( Module m : this.getModule() )
540            {
541                if ( m.getImplementations() != null )
542                {
543                    final Implementation i = m.getImplementations().getImplementation( implementation );
544                    if ( i != null )
545                    {
546                        return i;
547                    }
548                }
549            }
550    
551            return null;
552        }
553    
554        /**
555         * Gets an implementation for a given name implementing a given specification from this list of
556         * modules.
557         *
558         * @param specification The identifier of the specification to return an implementation of.
559         * @param name The name of the implementation to return.
560         *
561         * @return The implementation with name {@code name} implementing the specification identified by
562         * {@code specification} from the list or {@code null}, if no such implementation is found.
563         *
564         * @throws NullPointerException if {@code specification} or {@code name} is {@code null}.
565         *
566         * @see #getModule()
567         */
568        public Implementation getImplementation( final String specification, final String name )
569        {
570            if ( specification == null )
571            {
572                throw new NullPointerException( "specification" );
573            }
574            if ( name == null )
575            {
576                throw new NullPointerException( "name" );
577            }
578    
579            final Implementations implementations = this.getImplementations( specification );
580            if ( implementations != null )
581            {
582                return implementations.getImplementationByName( name );
583            }
584    
585            return null;
586        }
587    
588        /**
589         * Gets all dependencies of an implementation from this list of modules.
590         *
591         * @param implementation The identifier of the implementation to get all dependencies of.
592         *
593         * @return List of all dependencies of {@code implementation} from the list or {@code null},
594         * if no dependencies are found.
595         *
596         * @throws NullPointerException if {@code implementation} is {@code null}.
597         *
598         * @see #getModule()
599         */
600        public Dependencies getDependencies( final String implementation )
601        {
602            if ( implementation == null )
603            {
604                throw new NullPointerException( "implementation" );
605            }
606    
607            final Dependencies dependencies = new Dependencies();
608            this.collectDependencies( implementation, dependencies );
609    
610            Implementation declaration = null;
611            final Implementation impl = this.getImplementation( implementation );
612    
613            if ( impl != null && impl.getClazz() != null && !impl.getIdentifier().equals( impl.getClazz() ) )
614            {
615                for ( Module m : this.getModule() )
616                {
617                    if ( m.getImplementations() != null )
618                    {
619                        for ( Implementation i : m.getImplementations().getImplementation() )
620                        {
621                            if ( i.getClazz() != null && i.getClazz().equals( i.getIdentifier() ) &&
622                                 i.getClazz().equals( impl.getClazz() ) )
623                            {
624                                declaration = i;
625                                break;
626                            }
627                        }
628                    }
629                }
630            }
631    
632            if ( declaration != null )
633            {
634                final Dependencies declaredDependencies = this.getDependencies( declaration.getIdentifier() );
635                if ( declaredDependencies != null )
636                {
637                    for ( Dependency d : declaredDependencies.getDependency() )
638                    {
639                        if ( dependencies.getDependency( d.getName() ) == null )
640                        {
641                            dependencies.getDependency().add( d );
642                        }
643                    }
644                }
645            }
646    
647            java.util.Collections.sort( dependencies.getDependency(), new java.util.Comparator<Dependency>()
648            {
649    
650                public int compare( final Dependency o1, final Dependency o2 )
651                {
652                    return o1.getName().compareTo( o2.getName() );
653                }
654    
655            } );
656    
657            return dependencies.getDependency().isEmpty() ? null : dependencies;
658        }
659    
660        private void collectDependencies( final String implementation, final Dependencies dependencies )
661        {
662            final Implementation i = this.getImplementation( implementation );
663    
664            if ( i != null )
665            {
666                if ( i.getDependencies() != null )
667                {
668                    for ( Dependency d : i.getDependencies().getDependency() )
669                    {
670                        final Dependency dependency = dependencies.getDependency( d.getName() );
671                        if ( dependency != null )
672                        {
673                            if ( d.getProperties() != null )
674                            {
675                                if ( dependency.getProperties() == null )
676                                {
677                                    dependency.setProperties( new Properties() );
678                                }
679    
680                                for ( Property p : d.getProperties().getProperty() )
681                                {
682                                    if ( dependency.getProperties().getProperty( p.getName() ) == null )
683                                    {
684                                        dependency.getProperties().getProperty().add( p );
685                                    }
686                                }
687                            }
688                        }
689                        else
690                        {
691                            dependencies.getDependency().add( d );
692                        }
693                    }
694                }
695    
696                if ( i.getParent() != null )
697                {
698                    this.collectDependencies( i.getParent(), dependencies );
699                }
700            }
701        }
702    
703        /**
704         * Gets all properties of an implementation from this list of modules.
705         *
706         * @param implementation The identifier of the implementation to get all properties of.
707         *
708         * @return List of all properties of {@code implementation} from the list or {@code null},
709         * if no properties are found.
710         *
711         * @throws NullPointerException if {@code implementation} is {@code null}.
712         *
713         * @see #getModule()
714         */
715        public Properties getProperties( final String implementation )
716        {
717            if ( implementation == null )
718            {
719                throw new NullPointerException( "implementation" );
720            }
721    
722            final Properties properties = new Properties();
723            this.collectProperties( implementation, properties );
724    
725            Implementation declaration = null;
726            final Implementation impl = this.getImplementation( implementation );
727    
728            if ( impl != null && impl.getClazz() != null && !impl.getIdentifier().equals( impl.getClazz() ) )
729            {
730                for ( Module m : this.getModule() )
731                {
732                    if ( m.getImplementations() != null )
733                    {
734                        for ( Implementation i : m.getImplementations().getImplementation() )
735                        {
736                            if ( i.getClazz() != null && i.getClazz().equals( i.getIdentifier() ) &&
737                                 i.getClazz().equals( impl.getClazz() ) )
738                            {
739                                declaration = i;
740                                break;
741                            }
742                        }
743                    }
744                }
745            }
746    
747            if ( declaration != null )
748            {
749                final Properties declaredProperties = this.getProperties( declaration.getIdentifier() );
750                if ( declaredProperties != null )
751                {
752                    for ( Property p : declaredProperties.getProperty() )
753                    {
754                        if ( properties.getProperty( p.getName() ) == null )
755                        {
756                            properties.getProperty().add( p );
757                        }
758                    }
759                }
760            }
761    
762            final Properties specified = this.getSpecifiedProperties( implementation );
763    
764            if ( specified != null )
765            {
766                for ( Property p : specified.getProperty() )
767                {
768                    if ( properties.getProperty( p.getName() ) == null )
769                    {
770                        properties.getProperty().add( p );
771                    }
772                }
773            }
774    
775            java.util.Collections.sort( properties.getProperty(), new java.util.Comparator<Property>()
776            {
777    
778                public int compare( final Property o1, final Property o2 )
779                {
780                    return o1.getName().compareTo( o2.getName() );
781                }
782    
783            } );
784    
785            return properties.getProperty().isEmpty() ? null : properties;
786        }
787    
788        private void collectProperties( final String implementation, final Properties properties )
789        {
790            final Implementation i = this.getImplementation( implementation );
791    
792            if ( i != null )
793            {
794                if ( i.getProperties() != null )
795                {
796                    for ( Property p : i.getProperties().getProperty() )
797                    {
798                        if ( properties.getProperty( p.getName() ) == null )
799                        {
800                            properties.getProperty().add( p );
801                        }
802                    }
803                    if ( !i.getProperties().getReference().isEmpty() )
804                    {
805                        final Module m = this.getModuleOfImplementation( i.getIdentifier() );
806    
807                        if ( m != null )
808                        {
809                            for ( PropertyReference ref : i.getProperties().getReference() )
810                            {
811                                if ( properties.getProperty( ref.getName() ) == null )
812                                {
813                                    properties.getProperty().add( m.getProperties().getProperty( ref.getName() ) );
814                                }
815                            }
816                        }
817                    }
818                }
819    
820                if ( i.getParent() != null )
821                {
822                    this.collectProperties( i.getParent(), properties );
823                }
824            }
825        }
826    
827        /**
828         * Gets all properties specified for an implementation from this list of modules.
829         *
830         * @param implementation The identifier of the implementation to return specified properties of.
831         *
832         * @return List of all properties specified for {@code implementation} from the list or {@code null},
833         * if no properties are found.
834         *
835         * @throws NullPointerException if {@code implementation} is {@code null}.
836         *
837         * @see #getModule()
838         */
839        public Properties getSpecifiedProperties( final String implementation )
840        {
841            if ( implementation == null )
842            {
843                throw new NullPointerException( "implementation" );
844            }
845    
846            final Properties properties = new Properties();
847            final Specifications specs = this.getSpecifications( implementation );
848    
849            if ( specs != null )
850            {
851                for ( Specification s : specs.getSpecification() )
852                {
853                    if ( s.getProperties() != null )
854                    {
855                        properties.getProperty().addAll( s.getProperties().getProperty() );
856                    }
857                }
858            }
859    
860            java.util.Collections.sort( properties.getProperty(), new java.util.Comparator<Property>()
861            {
862    
863                public int compare( final Property o1, final Property o2 )
864                {
865                    return o1.getName().compareTo( o2.getName() );
866                }
867    
868            } );
869    
870            return properties.getProperty().isEmpty() ? null : properties;
871        }
872    
873        /**
874         * Gets all messages of an implementation from this list of modules.
875         *
876         * @param implementation The identifier of the implementation to get all messages of.
877         *
878         * @return List of messages of {@code implementation} from the list or {@code null},
879         * if no messages are found.
880         *
881         * @throws NullPointerException if {@code implementation} is {@code null}.
882         *
883         * @see #getModule()
884         */
885        public Messages getMessages( final String implementation )
886        {
887            if ( implementation == null )
888            {
889                throw new NullPointerException( "implementation" );
890            }
891    
892            final Messages msgs = new Messages();
893            this.collectMessages( implementation, msgs );
894    
895            Implementation declaration = null;
896            final Implementation impl = this.getImplementation( implementation );
897    
898            if ( impl != null && impl.getClazz() != null && !impl.getIdentifier().equals( impl.getClazz() ) )
899            {
900                for ( Module m : this.getModule() )
901                {
902                    if ( m.getImplementations() != null )
903                    {
904                        for ( Implementation i : m.getImplementations().getImplementation() )
905                        {
906                            if ( i.getClazz() != null && i.getClazz().equals( i.getIdentifier() ) &&
907                                 i.getClazz().equals( impl.getClazz() ) )
908                            {
909                                declaration = i;
910                                break;
911                            }
912                        }
913                    }
914                }
915            }
916    
917            if ( declaration != null )
918            {
919                final Messages declaredMessages = this.getMessages( declaration.getIdentifier() );
920                if ( declaredMessages != null )
921                {
922                    for ( Message m : declaredMessages.getMessage() )
923                    {
924                        if ( msgs.getMessage( m.getName() ) == null )
925                        {
926                            msgs.getMessage().add( m );
927                        }
928                    }
929                }
930            }
931    
932            java.util.Collections.sort( msgs.getMessage(), new java.util.Comparator<Message>()
933            {
934    
935                public int compare( final Message o1, final Message o2 )
936                {
937                    return o1.getName().compareTo( o2.getName() );
938                }
939    
940            } );
941    
942            return msgs.getMessage().isEmpty() ? null : msgs;
943        }
944    
945        private void collectMessages( final String implementation, final Messages messages )
946        {
947            final Implementation i = this.getImplementation( implementation );
948    
949            if ( i != null )
950            {
951                if ( i.getMessages() != null )
952                {
953                    for ( Message msg : i.getMessages().getMessage() )
954                    {
955                        if ( messages.getMessage( msg.getName() ) == null )
956                        {
957                            messages.getMessage().add( msg );
958                        }
959                    }
960                    if ( !i.getMessages().getReference().isEmpty() )
961                    {
962                        final Module m = this.getModuleOfImplementation( i.getIdentifier() );
963    
964                        if ( m != null )
965                        {
966                            for ( MessageReference ref : i.getMessages().getReference() )
967                            {
968                                if ( messages.getMessage( ref.getName() ) == null )
969                                {
970                                    messages.getMessage().add( m.getMessages().getMessage( ref.getName() ) );
971                                }
972                            }
973                        }
974                    }
975                }
976    
977                if ( i.getParent() != null )
978                {
979                    this.collectMessages( i.getParent(), messages );
980                }
981            }
982        }
983    
984        /**
985         * Gets all implementations implementing a given specification from this list of modules.
986         *
987         * @param specification The identifier of the specification to return implementations of.
988         *
989         * @return All implementations implementing the specification identified by {@code specification}
990         * from the list or {@code null}, if no implementation implementing {@code specification} is found.
991         *
992         * @throws NullPointerException if {@code specification} is {@code null}.
993         *
994         * @see #getModule()
995         */
996        public Implementations getImplementations( final String specification )
997        {
998            if ( specification == null )
999            {
1000                throw new NullPointerException( "specification" );
1001            }
1002    
1003            final Implementations implementations = new Implementations();
1004            for ( Module m : this.getModule() )
1005            {
1006                if ( m.getImplementations() != null )
1007                {
1008                    for ( Implementation i : m.getImplementations().getImplementation() )
1009                    {
1010                        final Specifications specs = this.getSpecifications( i.getIdentifier() );
1011    
1012                        if ( specs != null )
1013                        {
1014                            for ( Specification s : specs.getSpecification() )
1015                            {
1016                                if ( specification.equals( s.getIdentifier() ) )
1017                                {
1018                                    implementations.getImplementation().add( i );
1019                                }
1020                            }
1021                        }
1022                    }
1023                }
1024            }
1025    
1026            return implementations.getImplementation().size() > 0 ? implementations : null;
1027        }
1028    
1029        /**
1030         * Merges this list of modules to a single module.
1031         *
1032         * @return A module holding all model objects from the list.
1033         */
1034        public Module getMergedModule()
1035        {
1036            final Modules copy = this.clone();
1037            final Module mergedModule = new Module();
1038    
1039            for ( Module m : copy.getModule() )
1040            {
1041                final java.util.Set<String> referencedMessages = new java.util.HashSet<String>();
1042                final java.util.Set<String> referencedProperties = new java.util.HashSet<String>();
1043    
1044                if ( m.getImplementations() != null )
1045                {
1046                    for ( Implementation i : m.getImplementations().getImplementation() )
1047                    {
1048                        if ( mergedModule.getImplementations() == null )
1049                        {
1050                            mergedModule.setImplementations( new Implementations() );
1051                        }
1052    
1053                        if ( i.getMessages() != null && !i.getMessages().getReference().isEmpty() )
1054                        {
1055                            for ( java.util.Iterator<MessageReference> it = i.getMessages().getReference().iterator();
1056                                  it.hasNext(); )
1057                            {
1058                                final String messageName = it.next().getName();
1059                                i.getMessages().getMessage().add( m.getMessages().getMessage( messageName ) );
1060                                referencedMessages.add( messageName );
1061                                it.remove();
1062                            }
1063                        }
1064    
1065                        if ( i.getProperties() != null && !i.getProperties().getReference().isEmpty() )
1066                        {
1067                            for ( java.util.Iterator<PropertyReference> it = i.getProperties().getReference().iterator();
1068                                  it.hasNext(); )
1069                            {
1070                                final String propertyName = it.next().getName();
1071                                i.getProperties().getProperty().add( m.getProperties().getProperty( propertyName ) );
1072                                referencedProperties.add( propertyName );
1073                                it.remove();
1074                            }
1075                        }
1076    
1077                        mergedModule.getImplementations().getImplementation().add( i );
1078                    }
1079                }
1080    
1081                if ( m.getSpecifications() != null )
1082                {
1083                    if ( mergedModule.getSpecifications() == null )
1084                    {
1085                        mergedModule.setSpecifications( new Specifications() );
1086                    }
1087    
1088                    for ( Specification s : m.getSpecifications().getSpecification() )
1089                    {
1090                        if ( s.getProperties() != null && !s.getProperties().getReference().isEmpty() )
1091                        {
1092                            for ( java.util.Iterator<PropertyReference> it = s.getProperties().getReference().iterator();
1093                                  it.hasNext(); )
1094                            {
1095                                final String propertyName = it.next().getName();
1096                                s.getProperties().getProperty().add( m.getProperties().getProperty( propertyName ) );
1097                                referencedProperties.add( propertyName );
1098                                it.remove();
1099                            }
1100                        }
1101    
1102                        mergedModule.getSpecifications().getSpecification().add( s );
1103                    }
1104                }
1105    
1106                for ( String messageName : referencedMessages )
1107                {
1108                    for ( java.util.Iterator<Message> it = m.getMessages().getMessage().iterator(); it.hasNext(); )
1109                    {
1110                        if ( messageName.equals( it.next().getName() ) )
1111                        {
1112                            it.remove();
1113                            break;
1114                        }
1115                    }
1116                }
1117    
1118                for ( String propertyName : referencedProperties )
1119                {
1120                    for ( java.util.Iterator<Property> it = m.getProperties().getProperty().iterator(); it.hasNext(); )
1121                    {
1122                        if ( propertyName.equals( it.next().getName() ) )
1123                        {
1124                            it.remove();
1125                            break;
1126                        }
1127                    }
1128                }
1129    
1130                if ( m.getProperties() != null && !m.getProperties().getProperty().isEmpty() )
1131                {
1132                    if ( mergedModule.getProperties() == null )
1133                    {
1134                        mergedModule.setProperties( new Properties() );
1135                    }
1136    
1137                    mergedModule.getProperties().getProperty().addAll( m.getProperties().getProperty() );
1138                }
1139    
1140                if ( m.getMessages() != null && !m.getMessages().getMessage().isEmpty() )
1141                {
1142                    if ( mergedModule.getMessages() == null )
1143                    {
1144                        mergedModule.setMessages( new Messages() );
1145                    }
1146    
1147                    mergedModule.getMessages().getMessage().addAll( m.getMessages().getMessage() );
1148                }
1149            }
1150    
1151            return mergedModule;
1152        }
1153    
1154    }