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.10.02 at 06:07:50 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-10-02T06:07:50+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-10-02T06:07:50+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-10-02T06:07:50+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-10-02T06:07:50+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-10-02T06:07:50+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( this.getImplementation( implementation ), specs, new Implementations(), true );
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        void collectSpecifications( final Implementation implementation, final Specifications specifications,
457                                    final Implementations seen, final boolean includeDeclared )
458        {
459            if ( implementation != null )
460            {
461                if ( seen.getImplementation( implementation.getIdentifier() ) == null )
462                {
463                    seen.getImplementation().add( implementation );
464    
465                    if ( includeDeclared && implementation.getSpecifications() != null )
466                    {
467                        for ( SpecificationReference r : implementation.getSpecifications().getReference() )
468                        {
469                            if ( specifications.getReference( r.getIdentifier() ) == null )
470                            {
471                                specifications.getReference().add( r );
472    
473                                final Specification s = this.getSpecification( r.getIdentifier() );
474                                if ( s != null && specifications.getSpecification( s.getIdentifier() ) == null )
475                                {
476                                    specifications.getSpecification().add( s );
477                                }
478                            }
479                        }
480                    }
481    
482                    if ( implementation.getImplementations() != null )
483                    {
484                        for ( ImplementationReference r : implementation.getImplementations().getReference() )
485                        {
486                            this.collectSpecifications(
487                                this.getImplementation( r.getIdentifier() ), specifications, seen, true );
488    
489                        }
490                    }
491                }
492            }
493        }
494    
495        /**
496         * Gets an implementation for a given identifier from this list of modules.
497         *
498         * @param implementation The identifier of the implementation to return.
499         *
500         * @return The implementation identified by {@code implementation} from the list or {@code null},
501         * if no implementation matching {@code implementation} is found.
502         *
503         * @throws NullPointerException if {@code implementation} is {@code null}.
504         *
505         * @see #getModule()
506         */
507        public Implementation getImplementation( final String implementation )
508        {
509            if ( implementation == null )
510            {
511                throw new NullPointerException( "implementation" );
512            }
513    
514            for ( Module m : this.getModule() )
515            {
516                if ( m.getImplementations() != null )
517                {
518                    final Implementation i = m.getImplementations().getImplementation( implementation );
519                    if ( i != null )
520                    {
521                        return i;
522                    }
523                }
524            }
525    
526            return null;
527        }
528    
529        /**
530         * Gets an implementation for a given class from this list of modules.
531         *
532         * @param implementation The class of the implementation to return.
533         *
534         * @return The implementation identified by {@code implementation} from the list or {@code null},
535         * if no implementation matching {@code implementation} is found.
536         *
537         * @throws NullPointerException if {@code implementation} is {@code null}.
538         *
539         * @see #getModule()
540         */
541        public Implementation getImplementation( final Class implementation )
542        {
543            if ( implementation == null )
544            {
545                throw new NullPointerException( "implementation" );
546            }
547    
548            for ( Module m : this.getModule() )
549            {
550                if ( m.getImplementations() != null )
551                {
552                    final Implementation i = m.getImplementations().getImplementation( implementation );
553                    if ( i != null )
554                    {
555                        return i;
556                    }
557                }
558            }
559    
560            return null;
561        }
562    
563        /**
564         * Gets an implementation for a given name implementing a given specification from this list of
565         * modules.
566         *
567         * @param specification The identifier of the specification to return an implementation of.
568         * @param name The name of the implementation to return.
569         *
570         * @return The implementation with name {@code name} implementing the specification identified by
571         * {@code specification} from the list or {@code null}, if no such implementation is found.
572         *
573         * @throws NullPointerException if {@code specification} or {@code name} is {@code null}.
574         *
575         * @see #getModule()
576         */
577        public Implementation getImplementation( final String specification, final String name )
578        {
579            if ( specification == null )
580            {
581                throw new NullPointerException( "specification" );
582            }
583            if ( name == null )
584            {
585                throw new NullPointerException( "name" );
586            }
587    
588            final Implementations implementations = this.getImplementations( specification );
589            if ( implementations != null )
590            {
591                return implementations.getImplementationByName( name );
592            }
593    
594            return null;
595        }
596    
597        /**
598         * Gets all dependencies of an implementation from this list of modules.
599         *
600         * @param implementation The identifier of the implementation to get all dependencies of.
601         *
602         * @return List of all dependencies of {@code implementation} from the list or {@code null},
603         * if no dependencies are found.
604         *
605         * @throws NullPointerException if {@code implementation} is {@code null}.
606         *
607         * @see #getModule()
608         */
609        public Dependencies getDependencies( final String implementation )
610        {
611            if ( implementation == null )
612            {
613                throw new NullPointerException( "implementation" );
614            }
615    
616            final Dependencies dependencies = new Dependencies();
617            this.collectDependencies( this.getImplementation( implementation ), dependencies, new Implementations(), true );
618    
619            Implementation declaration = null;
620            final Implementation impl = this.getImplementation( implementation );
621    
622            if ( impl != null && impl.getClazz() != null && !impl.getIdentifier().equals( impl.getClazz() ) )
623            {
624                for ( Module m : this.getModule() )
625                {
626                    if ( m.getImplementations() != null )
627                    {
628                        for ( Implementation i : m.getImplementations().getImplementation() )
629                        {
630                            if ( i.getClazz() != null && i.getClazz().equals( i.getIdentifier() ) &&
631                                 i.getClazz().equals( impl.getClazz() ) )
632                            {
633                                declaration = i;
634                                break;
635                            }
636                        }
637                    }
638                }
639            }
640    
641            if ( declaration != null )
642            {
643                final Dependencies declaredDependencies = this.getDependencies( declaration.getIdentifier() );
644                if ( declaredDependencies != null )
645                {
646                    for ( Dependency d : declaredDependencies.getDependency() )
647                    {
648                        if ( dependencies.getDependency( d.getName() ) == null )
649                        {
650                            dependencies.getDependency().add( d );
651                        }
652                    }
653                }
654            }
655    
656            java.util.Collections.sort( dependencies.getDependency(), new java.util.Comparator<Dependency>()
657            {
658    
659                public int compare( final Dependency o1, final Dependency o2 )
660                {
661                    return o1.getName().compareTo( o2.getName() );
662                }
663    
664            } );
665    
666            return dependencies.getDependency().isEmpty() ? null : dependencies;
667        }
668    
669        void collectDependencies( final Implementation implementation, final Dependencies dependencies,
670                                  final Implementations seen, final boolean includeDeclared )
671        {
672            if ( implementation != null )
673            {
674                if ( seen.getImplementation( implementation.getIdentifier() ) == null )
675                {
676                    seen.getImplementation().add( implementation );
677    
678                    if ( includeDeclared && implementation.getDependencies() != null )
679                    {
680                        for ( Dependency d : implementation.getDependencies().getDependency() )
681                        {
682                            final Dependency dependency = dependencies.getDependency( d.getName() );
683    
684                            if ( dependency != null )
685                            {
686                                if ( d.getProperties() != null )
687                                {
688                                    if ( dependency.getProperties() == null )
689                                    {
690                                        dependency.setProperties( new Properties() );
691                                    }
692    
693                                    for ( Property p : d.getProperties().getProperty() )
694                                    {
695                                        if ( dependency.getProperties().getProperty( p.getName() ) == null )
696                                        {
697                                            dependency.getProperties().getProperty().add( p );
698                                        }
699                                    }
700                                }
701                            }
702                            else
703                            {
704                                dependencies.getDependency().add( d );
705                            }
706                        }
707                    }
708    
709                    if ( implementation.getImplementations() != null )
710                    {
711                        for ( ImplementationReference r : implementation.getImplementations().getReference() )
712                        {
713                            this.collectDependencies(
714                                this.getImplementation( r.getIdentifier() ), dependencies, seen, true );
715    
716                        }
717                    }
718                }
719            }
720        }
721    
722        /**
723         * Gets all properties of an implementation from this list of modules.
724         *
725         * @param implementation The identifier of the implementation to get all properties of.
726         *
727         * @return List of all properties of {@code implementation} from the list or {@code null},
728         * if no properties are found.
729         *
730         * @throws NullPointerException if {@code implementation} is {@code null}.
731         *
732         * @see #getModule()
733         */
734        public Properties getProperties( final String implementation )
735        {
736            if ( implementation == null )
737            {
738                throw new NullPointerException( "implementation" );
739            }
740    
741            final Properties properties = new Properties();
742            this.collectProperties( this.getImplementation( implementation ), properties, new Implementations(), true );
743    
744            Implementation declaration = null;
745            final Implementation impl = this.getImplementation( implementation );
746    
747            if ( impl != null && impl.getClazz() != null && !impl.getIdentifier().equals( impl.getClazz() ) )
748            {
749                for ( Module m : this.getModule() )
750                {
751                    if ( m.getImplementations() != null )
752                    {
753                        for ( Implementation i : m.getImplementations().getImplementation() )
754                        {
755                            if ( i.getClazz() != null && i.getClazz().equals( i.getIdentifier() ) &&
756                                 i.getClazz().equals( impl.getClazz() ) )
757                            {
758                                declaration = i;
759                                break;
760                            }
761                        }
762                    }
763                }
764            }
765    
766            if ( declaration != null )
767            {
768                final Properties declaredProperties = this.getProperties( declaration.getIdentifier() );
769                if ( declaredProperties != null )
770                {
771                    for ( Property p : declaredProperties.getProperty() )
772                    {
773                        if ( properties.getProperty( p.getName() ) == null )
774                        {
775                            properties.getProperty().add( p );
776                        }
777                    }
778                }
779            }
780    
781            final Properties specified = this.getSpecifiedProperties( implementation );
782    
783            if ( specified != null )
784            {
785                for ( Property p : specified.getProperty() )
786                {
787                    if ( properties.getProperty( p.getName() ) == null )
788                    {
789                        properties.getProperty().add( p );
790                    }
791                }
792            }
793    
794            java.util.Collections.sort( properties.getProperty(), new java.util.Comparator<Property>()
795            {
796    
797                public int compare( final Property o1, final Property o2 )
798                {
799                    return o1.getName().compareTo( o2.getName() );
800                }
801    
802            } );
803    
804            return properties.getProperty().isEmpty() ? null : properties;
805        }
806    
807        void collectProperties( final Implementation implementation, final Properties properties,
808                                final Implementations seen, final boolean includeDeclared )
809        {
810            if ( implementation != null )
811            {
812                if ( seen.getImplementation( implementation.getIdentifier() ) == null )
813                {
814                    seen.getImplementation().add( implementation );
815    
816                    if ( includeDeclared && implementation.getProperties() != null )
817                    {
818                        for ( Property p : implementation.getProperties().getProperty() )
819                        {
820                            if ( properties.getProperty( p.getName() ) == null )
821                            {
822                                properties.getProperty().add( p );
823                            }
824                        }
825                        if ( !implementation.getProperties().getReference().isEmpty() )
826                        {
827                            final Module m = this.getModuleOfImplementation( implementation.getIdentifier() );
828    
829                            if ( m != null )
830                            {
831                                for ( PropertyReference ref : implementation.getProperties().getReference() )
832                                {
833                                    if ( properties.getProperty( ref.getName() ) == null )
834                                    {
835                                        Property referenced = m.getProperties().getProperty( ref.getName() );
836                                        if ( referenced != null )
837                                        {
838                                            referenced = new Property( referenced );
839                                            referenced.setDeprecated( ref.isDeprecated() );
840                                            referenced.setFinal( ref.isFinal() );
841                                            referenced.setOverride( ref.isOverride() );
842                                            properties.getProperty().add( referenced );
843                                        }
844                                    }
845                                }
846                            }
847                        }
848                    }
849    
850                    if ( implementation.getImplementations() != null )
851                    {
852                        for ( ImplementationReference r : implementation.getImplementations().getReference() )
853                        {
854                            this.collectProperties( this.getImplementation( r.getIdentifier() ), properties, seen, true );
855                        }
856                    }
857                }
858            }
859        }
860    
861        /**
862         * Gets all properties specified for an implementation from this list of modules.
863         *
864         * @param implementation The identifier of the implementation to return specified properties of.
865         *
866         * @return List of all properties specified for {@code implementation} from the list or {@code null},
867         * if no properties are found.
868         *
869         * @throws NullPointerException if {@code implementation} is {@code null}.
870         *
871         * @see #getModule()
872         */
873        public Properties getSpecifiedProperties( final String implementation )
874        {
875            if ( implementation == null )
876            {
877                throw new NullPointerException( "implementation" );
878            }
879    
880            final Properties properties = new Properties();
881            final Specifications specs = this.getSpecifications( implementation );
882    
883            if ( specs != null )
884            {
885                for ( Specification s : specs.getSpecification() )
886                {
887                    if ( s.getProperties() != null )
888                    {
889                        properties.getProperty().addAll( s.getProperties().getProperty() );
890                    }
891                }
892            }
893    
894            java.util.Collections.sort( properties.getProperty(), new java.util.Comparator<Property>()
895            {
896    
897                public int compare( final Property o1, final Property o2 )
898                {
899                    return o1.getName().compareTo( o2.getName() );
900                }
901    
902            } );
903    
904            return properties.getProperty().isEmpty() ? null : properties;
905        }
906    
907        /**
908         * Gets all messages of an implementation from this list of modules.
909         *
910         * @param implementation The identifier of the implementation to get all messages of.
911         *
912         * @return List of messages of {@code implementation} from the list or {@code null},
913         * if no messages are found.
914         *
915         * @throws NullPointerException if {@code implementation} is {@code null}.
916         *
917         * @see #getModule()
918         */
919        public Messages getMessages( final String implementation )
920        {
921            if ( implementation == null )
922            {
923                throw new NullPointerException( "implementation" );
924            }
925    
926            final Messages msgs = new Messages();
927            this.collectMessages( this.getImplementation( implementation ), msgs, new Implementations(), true );
928    
929            Implementation declaration = null;
930            final Implementation impl = this.getImplementation( implementation );
931    
932            if ( impl != null && impl.getClazz() != null && !impl.getIdentifier().equals( impl.getClazz() ) )
933            {
934                for ( Module m : this.getModule() )
935                {
936                    if ( m.getImplementations() != null )
937                    {
938                        for ( Implementation i : m.getImplementations().getImplementation() )
939                        {
940                            if ( i.getClazz() != null && i.getClazz().equals( i.getIdentifier() ) &&
941                                 i.getClazz().equals( impl.getClazz() ) )
942                            {
943                                declaration = i;
944                                break;
945                            }
946                        }
947                    }
948                }
949            }
950    
951            if ( declaration != null )
952            {
953                final Messages declaredMessages = this.getMessages( declaration.getIdentifier() );
954                if ( declaredMessages != null )
955                {
956                    for ( Message m : declaredMessages.getMessage() )
957                    {
958                        if ( msgs.getMessage( m.getName() ) == null )
959                        {
960                            msgs.getMessage().add( m );
961                        }
962                    }
963                }
964            }
965    
966            java.util.Collections.sort( msgs.getMessage(), new java.util.Comparator<Message>()
967            {
968    
969                public int compare( final Message o1, final Message o2 )
970                {
971                    return o1.getName().compareTo( o2.getName() );
972                }
973    
974            } );
975    
976            return msgs.getMessage().isEmpty() ? null : msgs;
977        }
978    
979        void collectMessages( final Implementation implementation, final Messages messages,
980                              final Implementations seen, boolean includeDeclared )
981        {
982            if ( implementation != null )
983            {
984                if ( seen.getImplementation( implementation.getIdentifier() ) == null )
985                {
986                    seen.getImplementation().add( implementation );
987    
988                    if ( includeDeclared && implementation.getMessages() != null )
989                    {
990                        for ( Message msg : implementation.getMessages().getMessage() )
991                        {
992                            if ( messages.getMessage( msg.getName() ) == null )
993                            {
994                                messages.getMessage().add( msg );
995                            }
996                        }
997                        if ( !implementation.getMessages().getReference().isEmpty() )
998                        {
999                            final Module m = this.getModuleOfImplementation( implementation.getIdentifier() );
1000    
1001                            if ( m != null )
1002                            {
1003                                for ( MessageReference ref : implementation.getMessages().getReference() )
1004                                {
1005                                    if ( messages.getMessage( ref.getName() ) == null )
1006                                    {
1007                                        Message referenced = m.getMessages().getMessage( ref.getName() );
1008                                        if ( referenced != null )
1009                                        {
1010                                            referenced = new Message( referenced );
1011                                            referenced.setDeprecated( ref.isDeprecated() );
1012                                            referenced.setFinal( ref.isFinal() );
1013                                            referenced.setOverride( ref.isOverride() );
1014                                            messages.getMessage().add( referenced );
1015                                        }
1016                                    }
1017                                }
1018                            }
1019                        }
1020                    }
1021    
1022                    if ( implementation.getImplementations() != null )
1023                    {
1024                        for ( ImplementationReference r : implementation.getImplementations().getReference() )
1025                        {
1026                            this.collectMessages( this.getImplementation( r.getIdentifier() ), messages, seen, true );
1027                        }
1028                    }
1029                }
1030            }
1031        }
1032    
1033        /**
1034         * Gets all implementations implementing a given specification from this list of modules.
1035         *
1036         * @param specification The identifier of the specification to return implementations of.
1037         *
1038         * @return All implementations implementing the specification identified by {@code specification}
1039         * from the list or {@code null}, if no implementation implementing {@code specification} is found.
1040         *
1041         * @throws NullPointerException if {@code specification} is {@code null}.
1042         *
1043         * @see #getModule()
1044         */
1045        public Implementations getImplementations( final String specification )
1046        {
1047            if ( specification == null )
1048            {
1049                throw new NullPointerException( "specification" );
1050            }
1051    
1052            final Implementations implementations = new Implementations();
1053            for ( Module m : this.getModule() )
1054            {
1055                if ( m.getImplementations() != null )
1056                {
1057                    for ( Implementation i : m.getImplementations().getImplementation() )
1058                    {
1059                        final Specifications specs = this.getSpecifications( i.getIdentifier() );
1060    
1061                        if ( specs != null )
1062                        {
1063                            for ( Specification s : specs.getSpecification() )
1064                            {
1065                                if ( specification.equals( s.getIdentifier() ) )
1066                                {
1067                                    implementations.getImplementation().add( i );
1068                                }
1069                            }
1070                        }
1071                    }
1072                }
1073            }
1074    
1075            return implementations.getImplementation().size() > 0 ? implementations : null;
1076        }
1077    
1078        /**
1079         * Merges this list of modules to a single module.
1080         *
1081         * @return A module holding all model objects from the list.
1082         */
1083        public Module getMergedModule()
1084        {
1085            final Modules copy = this.clone();
1086            final Module mergedModule = new Module();
1087    
1088            for ( Module m : copy.getModule() )
1089            {
1090                final java.util.Set<String> referencedMessages = new java.util.HashSet<String>();
1091                final java.util.Set<String> referencedProperties = new java.util.HashSet<String>();
1092    
1093                if ( m.getImplementations() != null )
1094                {
1095                    for ( Implementation i : m.getImplementations().getImplementation() )
1096                    {
1097                        if ( mergedModule.getImplementations() == null )
1098                        {
1099                            mergedModule.setImplementations( new Implementations() );
1100                        }
1101    
1102                        if ( i.getMessages() != null && !i.getMessages().getReference().isEmpty() )
1103                        {
1104                            for ( java.util.Iterator<MessageReference> it = i.getMessages().getReference().iterator();
1105                                  it.hasNext(); )
1106                            {
1107                                final String messageName = it.next().getName();
1108                                i.getMessages().getMessage().add( m.getMessages().getMessage( messageName ) );
1109                                referencedMessages.add( messageName );
1110                                it.remove();
1111                            }
1112                        }
1113    
1114                        if ( i.getProperties() != null && !i.getProperties().getReference().isEmpty() )
1115                        {
1116                            for ( java.util.Iterator<PropertyReference> it = i.getProperties().getReference().iterator();
1117                                  it.hasNext(); )
1118                            {
1119                                final String propertyName = it.next().getName();
1120                                i.getProperties().getProperty().add( m.getProperties().getProperty( propertyName ) );
1121                                referencedProperties.add( propertyName );
1122                                it.remove();
1123                            }
1124                        }
1125    
1126                        mergedModule.getImplementations().getImplementation().add( i );
1127                    }
1128                }
1129    
1130                if ( m.getSpecifications() != null )
1131                {
1132                    if ( mergedModule.getSpecifications() == null )
1133                    {
1134                        mergedModule.setSpecifications( new Specifications() );
1135                    }
1136    
1137                    for ( Specification s : m.getSpecifications().getSpecification() )
1138                    {
1139                        if ( s.getProperties() != null && !s.getProperties().getReference().isEmpty() )
1140                        {
1141                            for ( java.util.Iterator<PropertyReference> it = s.getProperties().getReference().iterator();
1142                                  it.hasNext(); )
1143                            {
1144                                final String propertyName = it.next().getName();
1145                                s.getProperties().getProperty().add( m.getProperties().getProperty( propertyName ) );
1146                                referencedProperties.add( propertyName );
1147                                it.remove();
1148                            }
1149                        }
1150    
1151                        mergedModule.getSpecifications().getSpecification().add( s );
1152                    }
1153                }
1154    
1155                for ( String messageName : referencedMessages )
1156                {
1157                    for ( java.util.Iterator<Message> it = m.getMessages().getMessage().iterator(); it.hasNext(); )
1158                    {
1159                        if ( messageName.equals( it.next().getName() ) )
1160                        {
1161                            it.remove();
1162                            break;
1163                        }
1164                    }
1165                }
1166    
1167                for ( String propertyName : referencedProperties )
1168                {
1169                    for ( java.util.Iterator<Property> it = m.getProperties().getProperty().iterator(); it.hasNext(); )
1170                    {
1171                        if ( propertyName.equals( it.next().getName() ) )
1172                        {
1173                            it.remove();
1174                            break;
1175                        }
1176                    }
1177                }
1178    
1179                if ( m.getProperties() != null && !m.getProperties().getProperty().isEmpty() )
1180                {
1181                    if ( mergedModule.getProperties() == null )
1182                    {
1183                        mergedModule.setProperties( new Properties() );
1184                    }
1185    
1186                    mergedModule.getProperties().getProperty().addAll( m.getProperties().getProperty() );
1187                }
1188    
1189                if ( m.getMessages() != null && !m.getMessages().getMessage().isEmpty() )
1190                {
1191                    if ( mergedModule.getMessages() == null )
1192                    {
1193                        mergedModule.setMessages( new Messages() );
1194                    }
1195    
1196                    mergedModule.getMessages().getMessage().addAll( m.getMessages().getMessage() );
1197                }
1198            }
1199    
1200            return mergedModule;
1201        }
1202    
1203          
1204    }