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.12.07 at 03:06:36 AM 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 *
023 * <p>Java class for Modules complex type.
024 *
025 * <p>The following schema fragment specifies the expected content contained within this class.
026 *
027 * <pre>
028 * <complexType name="Modules">
029 * <complexContent>
030 * <extension base="{http://jomc.org/model}ModelObject">
031 * <sequence>
032 * <element ref="{http://jomc.org/model}module" maxOccurs="unbounded" minOccurs="0"/>
033 * </sequence>
034 * </extension>
035 * </complexContent>
036 * </complexType>
037 * </pre>
038 *
039 *
040 */
041 @XmlAccessorType(XmlAccessType.FIELD)
042 @XmlType(name = "Modules", propOrder = {
043 "module"
044 })
045 @Generated(value = "com.sun.tools.xjc.Driver", date = "2009-12-07T03:06:36+00:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-833")
046 public class Modules
047 extends ModelObject
048 implements Cloneable
049 {
050
051 @Generated(value = "com.sun.tools.xjc.Driver", date = "2009-12-07T03:06:36+00:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-833")
052 protected List<Module> module;
053
054 /**
055 * Creates a new {@code Modules} instance.
056 *
057 */
058 public Modules() {
059 // CC-XJC Version 1.2 Build 2009-11-15T21:50:02+0000
060 super();
061 }
062
063 /**
064 * Creates a new {@code Modules} instance by deeply copying a given {@code Modules} instance.
065 *
066 *
067 * @param o
068 * The instance to copy.
069 * @throws NullPointerException
070 * if {@code o} is {@code null}.
071 */
072 public Modules(final Modules o) {
073 // CC-XJC Version 1.2 Build 2009-11-15T21:50:02+0000
074 super(o);
075 if (o == null) {
076 throw new NullPointerException("Cannot create a copy of 'Modules' from 'null'.");
077 }
078 // 'Module' collection.
079 copyModule(o.getModule(), getModule());
080 }
081
082 /**
083 * Gets the value of the module property.
084 *
085 * <p>
086 * This accessor method returns a reference to the live list,
087 * not a snapshot. Therefore any modification you make to the
088 * returned list will be present inside the JAXB object.
089 * This is why there is not a <CODE>set</CODE> method for the module property.
090 *
091 * <p>
092 * For example, to add a new item, do as follows:
093 * <pre>
094 * getModule().add(newItem);
095 * </pre>
096 *
097 *
098 * <p>
099 * Objects of the following type(s) are allowed in the list
100 * {@link Module }
101 *
102 *
103 */
104 @Generated(value = "com.sun.tools.xjc.Driver", date = "2009-12-07T03:06:36+00:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-833")
105 public List<Module> getModule() {
106 if (module == null) {
107 module = new ArrayList<Module>();
108 }
109 return this.module;
110 }
111
112 /**
113 * Copies all values of property {@code Module} deeply.
114 *
115 * @param target
116 * The target to copy {@code source} to.
117 * @param source
118 * The source to copy from.
119 * @throws NullPointerException
120 * if {@code source} or {@code target} is {@code null}.
121 */
122 @SuppressWarnings("unchecked")
123 @Generated(value = "com.sun.tools.xjc.Driver", date = "2009-12-07T03:06:36+00:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-833")
124 private static void copyModule(final List<Module> source, final List<Module> target) {
125 // CC-XJC Version 1.2 Build 2009-11-15T21:50:02+0000
126 if (!source.isEmpty()) {
127 for (Iterator it = source.iterator(); it.hasNext(); ) {
128 final Object next = it.next();
129 if (next instanceof Module) {
130 // CClassInfo: org.jomc.model.Module
131 target.add(((Module) next).clone());
132 continue;
133 }
134 // Please report this at https://apps.sourceforge.net/mantisbt/ccxjc/
135 throw new AssertionError((("Unexpected instance '"+ next)+"' for property 'Module' of class 'org.jomc.model.Modules'."));
136 }
137 }
138 }
139
140 /**
141 * Creates and returns a deep copy of this object.
142 *
143 *
144 * @return
145 * A deep copy of this object.
146 */
147 @Override
148 @Generated(value = "com.sun.tools.xjc.Driver", date = "2009-12-07T03:06:36+00:00", comments = "JAXB RI vhudson-jaxb-ri-2.1-833")
149 public Modules clone() {
150 // CC-XJC Version 1.2 Build 2009-11-15T21:50:02+0000
151 return new Modules(this);
152 }
153
154
155 /**
156 * Constant for the default name of the classpath module.
157 * @see #getClasspathModuleName()
158 */
159 private static final String DEFAULT_CLASSPATH_MODULE_NAME = "Java Classpath";
160
161 /** Default classpath module name. */
162 private static volatile String defaultClasspathModuleName;
163
164 /** Empty {@code Class} array. */
165 private static final Class[] NO_CLASSES =
166 {
167 };
168
169 /** Maps objects to {@code Instance}s. */
170 @javax.xml.bind.annotation.XmlTransient private java.util.Map<Object,Instance> objects = new org.jomc.util.WeakIdentityHashMap();
171
172 /**
173 * Creates a new {@code Modules} instance taking a map backing the instance.
174 *
175 * @param objects The map backing the instance.
176 */
177 public Modules( final java.util.Map<Object, Instance> objects )
178 {
179 if ( objects == null )
180 {
181 throw new NullPointerException( "objects" );
182 }
183
184 this.objects = objects;
185 }
186
187 /**
188 * Creates a new {@code Modules} instance by deeply copying a given {@code Modules} instance taking a map backing
189 * the instance.
190 *
191 * @param o The instance to copy.
192 * @param objects The map backing the instance.
193 *
194 * @throws NullPointerException if {@code o} or {@code objects} is {@code null}.
195 */
196 public Modules( final Modules o, final java.util.Map<Object, Instance> objects )
197 {
198 super( o );
199 if ( o == null )
200 {
201 throw new NullPointerException( "Cannot create a copy of 'Modules' from 'null'." );
202 }
203 if ( objects == null )
204 {
205 throw new NullPointerException( "objects" );
206 }
207
208 copyModule( o.getModule(), getModule() );
209 this.objects = objects;
210 }
211
212 /**
213 * Gets the default classpath module name.
214 * <p>The default classpath module name is controlled by system property
215 * {@code org.jomc.model.Modules.defaultClasspathModuleName} holding the default classpath module name. If that
216 * property is not set, the {@code Java Classpath} default is returned.</p>
217 *
218 * @return The default classpath module name.
219 *
220 * @see #getClasspathModule(java.lang.String, java.lang.ClassLoader)
221 */
222 public static String getDefaultClasspathModuleName()
223 {
224 if ( defaultClasspathModuleName == null )
225 {
226 defaultClasspathModuleName = System.getProperty( "org.jomc.model.Modules.defaultClasspathModuleName",
227 DEFAULT_CLASSPATH_MODULE_NAME );
228
229 }
230
231 return defaultClasspathModuleName;
232 }
233
234 /**
235 * Sets the default classpath module name.
236 *
237 * @param value The new default classpath module name or {@code null},
238 */
239 public static void setDefaultClasspathModuleName( final String value )
240 {
241 defaultClasspathModuleName = value;
242 }
243
244 /**
245 * Gets a module holding model objects resolved by inspecting a given class loader.
246 * <p>This method searches this list of modules for unresolved references and tries to resolve each unresolved
247 * reference by inspecting the given class loader.</p>
248 *
249 * @param moduleName The name of the module to return.
250 * @param classLoader The class loader to use for resolving entities or {@code null} to resolve entities using the
251 * bootstrap class loader.
252 *
253 * @return A module holding model objects resolved by inspecting the given class loader or {@code null} if nothing
254 * is resolved.
255 *
256 * @throws NullPointerException if {@code moduleName} is {@code null}.
257 *
258 * @see #getDefaultClasspathModuleName()
259 * @see #getModule()
260 */
261 public Module getClasspathModule( final String moduleName, final ClassLoader classLoader )
262 {
263 if ( moduleName == null )
264 {
265 throw new NullPointerException( "moduleName," );
266 }
267
268 final Module classpathModule = new Module();
269 classpathModule.setVersion( System.getProperty( "java.specification.version" ) );
270 classpathModule.setName( moduleName );
271
272 this.resolveClasspath( classpathModule, classLoader );
273
274 final boolean resolved = ( classpathModule.getSpecifications() != null &&
275 !classpathModule.getSpecifications().getSpecification().isEmpty() ) ||
276 ( classpathModule.getImplementations() != null &&
277 !classpathModule.getImplementations().getImplementation().isEmpty() );
278
279 return resolved ? classpathModule : null;
280 }
281
282 /**
283 * Gets a module for a given name from this list of modules.
284 *
285 * @param name The name of the module to return.
286 *
287 * @return The module with name {@code name} from the list or {@code null},
288 * if no module matching {@code name} is found.
289 *
290 * @throws NullPointerException if {@code name} is {@code null}.
291 *
292 * @see #getModule()
293 */
294 public Module getModule( final String name )
295 {
296 if ( name == null )
297 {
298 throw new NullPointerException( "name" );
299 }
300
301 for ( Module m : this.getModule() )
302 {
303 if ( m.getName().equals( name ) )
304 {
305 return m;
306 }
307 }
308
309 return null;
310 }
311
312 /**
313 * Gets all specifications declared in this list of modules.
314 *
315 * @return All specifications declared in the list or {@code null}, if no
316 * specifications are declared.
317 *
318 * @see #getModule()
319 */
320 public Specifications getSpecifications()
321 {
322 final Specifications specifications = new Specifications();
323 for ( Module m : this.getModule() )
324 {
325 if ( m.getSpecifications() != null )
326 {
327 specifications.getSpecification().addAll( m.getSpecifications().getSpecification() );
328 }
329 }
330
331 return specifications.getSpecification().isEmpty() ? null : specifications;
332 }
333
334 /**
335 * Gets all implementations declared in this list of modules.
336 *
337 * @return All implementations declared in the list or {@code null}, if no
338 * implementations are declared.
339 *
340 * @see #getModule()
341 */
342 public Implementations getImplementations()
343 {
344 final Implementations implementations = new Implementations();
345 for ( Module m : this.getModule() )
346 {
347 if ( m.getImplementations() != null )
348 {
349 implementations.getImplementation().addAll( m.getImplementations().getImplementation() );
350 }
351 }
352
353 return implementations.getImplementation().isEmpty() ? null : implementations;
354 }
355
356 /**
357 * Gets the module declaring a given specification from this list of modules.
358 *
359 * @param specification The identifier of the specification whose declaring module to return.
360 *
361 * @return The module declaring {@code specification} from the list or {@code null}, if no module
362 * is found declaring {@code specification}.
363 *
364 * @throws NullPointerException if {@code specification} is {@code null}.
365 *
366 * @see #getModule()
367 */
368 public Module getModuleOfSpecification( final String specification )
369 {
370 if ( specification == null )
371 {
372 throw new NullPointerException( "specification" );
373 }
374
375 for ( Module m : this.getModule() )
376 {
377 if ( m.getSpecifications() != null )
378 {
379 for ( Specification s : m.getSpecifications().getSpecification() )
380 {
381 if ( specification.equals( s.getIdentifier() ) )
382 {
383 return m;
384 }
385 }
386 }
387 }
388
389 return null;
390 }
391
392 /**
393 * Gets the module declaring a given implementation from this list of modules.
394 *
395 * @param implementation The identifier of the implementation whose declaring module to return.
396 *
397 * @return The module declaring {@code implementation} from the list or {@code null}, if no module
398 * is found declaring {@code implementation}.
399 *
400 * @throws NullPointerException if {@code implementation} is {@code null}.
401 *
402 * @see #getModule()
403 */
404 public Module getModuleOfImplementation( final String implementation )
405 {
406 if ( implementation == null )
407 {
408 throw new NullPointerException( "implementation" );
409 }
410
411 for ( Module m : this.getModule() )
412 {
413 if ( m.getImplementations() != null )
414 {
415 for ( Implementation i : m.getImplementations().getImplementation() )
416 {
417 if ( implementation.equals( i.getIdentifier() ) )
418 {
419 return m;
420 }
421 }
422 }
423 }
424
425 return null;
426 }
427
428 /**
429 * Gets a specification for a given identifier from this list of modules.
430 *
431 * @param specification The identifier of the specification to return.
432 *
433 * @return The specification identified by {@code specification} from the list or {@code null},
434 * if no specification matching {@code specification} is found.
435 *
436 * @throws NullPointerException if {@code specification} is {@code null}.
437 *
438 * @see #getModule()
439 */
440 public Specification getSpecification( final String specification )
441 {
442 if ( specification == null )
443 {
444 throw new NullPointerException( "specification" );
445 }
446
447 for ( Module m : this.getModule() )
448 {
449 if ( m.getSpecifications() != null )
450 {
451 final Specification s = m.getSpecifications().getSpecification( specification );
452 if ( s != null )
453 {
454 return s;
455 }
456 }
457 }
458
459 return null;
460 }
461
462 /**
463 * Gets a specification for a given class from this list of modules.
464 *
465 * @param specification The class of the specification to return.
466 *
467 * @return The specification identified by {@code specification} from the list or {@code null},
468 * if no specification matching {@code specification} is found.
469 *
470 * @throws NullPointerException if {@code specification} is {@code null}.
471 *
472 * @see #getModule()
473 */
474 public Specification getSpecification( final Class specification )
475 {
476 if ( specification == null )
477 {
478 throw new NullPointerException( "specification" );
479 }
480
481 for ( Module m : this.getModule() )
482 {
483 if ( m.getSpecifications() != null )
484 {
485 final Specification s = m.getSpecifications().getSpecification( specification );
486 if ( s != null )
487 {
488 return s;
489 }
490 }
491 }
492
493 return null;
494 }
495
496 /**
497 * Gets all specifications an implementation implements from this list of modules.
498 *
499 * @param implementation The identifier of the implementation to get all implemented specifications of.
500 *
501 * @return List of all specifications implemented by {@code implementation} from the list or {@code null}, if no
502 * implementation matching {@code implementation} is found or if that implementation does not implement any
503 * specification.
504 *
505 * @throws NullPointerException if {@code implementation} is {@code null}.
506 *
507 * @see #getModule()
508 */
509 public Specifications getSpecifications( final String implementation )
510 {
511 if ( implementation == null )
512 {
513 throw new NullPointerException( "implementation" );
514 }
515
516 final Specifications specs = new Specifications();
517 this.collectSpecifications( this.getImplementation( implementation ), specs, new Implementations(), true );
518
519 Implementation declaration = null;
520 final Implementation impl = this.getImplementation( implementation );
521
522 if ( impl != null && impl.getClazz() != null && !impl.getIdentifier().equals( impl.getClazz() ) )
523 {
524 for ( Module m : this.getModule() )
525 {
526 if ( m.getImplementations() != null )
527 {
528 for ( Implementation i : m.getImplementations().getImplementation() )
529 {
530 if ( i.getClazz() != null && i.getClazz().equals( i.getIdentifier() ) &&
531 i.getClazz().equals( impl.getClazz() ) )
532 {
533 declaration = i;
534 break;
535 }
536 }
537 }
538 }
539 }
540
541 if ( declaration != null )
542 {
543 final Specifications declaredSpecifications = this.getSpecifications( declaration.getIdentifier() );
544 if ( declaredSpecifications != null )
545 {
546 for ( SpecificationReference r : declaredSpecifications.getReference() )
547 {
548 if ( specs.getReference( r.getIdentifier() ) == null )
549 {
550 specs.getReference().add( r );
551 final Specification s = declaredSpecifications.getSpecification( r.getIdentifier() );
552 if ( s != null )
553 {
554 specs.getSpecification().add( s );
555 }
556 }
557 }
558 }
559 }
560
561 java.util.Collections.sort( specs.getSpecification(), new java.util.Comparator<Specification>()
562 {
563
564 public int compare( final Specification o1, final Specification o2 )
565 {
566 return o1.getIdentifier().compareTo( o2.getIdentifier() );
567 }
568
569 } );
570
571 java.util.Collections.sort( specs.getReference(), new java.util.Comparator<SpecificationReference>()
572 {
573
574 public int compare( final SpecificationReference o1, final SpecificationReference o2 )
575 {
576 return o1.getIdentifier().compareTo( o2.getIdentifier() );
577 }
578
579 } );
580
581 return specs.getSpecification().isEmpty() && specs.getReference().isEmpty() ? null : specs;
582 }
583
584 /**
585 * Gets an implementation for a given identifier from this list of modules.
586 *
587 * @param implementation The identifier of the implementation to return.
588 *
589 * @return The implementation identified by {@code implementation} from the list or {@code null},
590 * if no implementation matching {@code implementation} is found.
591 *
592 * @throws NullPointerException if {@code implementation} is {@code null}.
593 *
594 * @see #getModule()
595 */
596 public Implementation getImplementation( final String implementation )
597 {
598 if ( implementation == null )
599 {
600 throw new NullPointerException( "implementation" );
601 }
602
603 for ( Module m : this.getModule() )
604 {
605 if ( m.getImplementations() != null )
606 {
607 final Implementation i = m.getImplementations().getImplementation( implementation );
608 if ( i != null )
609 {
610 return i;
611 }
612 }
613 }
614
615 return null;
616 }
617
618 /**
619 * Gets an implementation for a given class from this list of modules.
620 *
621 * @param implementation The class of the implementation to return.
622 *
623 * @return The implementation identified by {@code implementation} from the list or {@code null},
624 * if no implementation matching {@code implementation} is found.
625 *
626 * @throws NullPointerException if {@code implementation} is {@code null}.
627 *
628 * @see #getModule()
629 */
630 public Implementation getImplementation( final Class implementation )
631 {
632 if ( implementation == null )
633 {
634 throw new NullPointerException( "implementation" );
635 }
636
637 for ( Module m : this.getModule() )
638 {
639 if ( m.getImplementations() != null )
640 {
641 final Implementation i = m.getImplementations().getImplementation( implementation );
642 if ( i != null )
643 {
644 return i;
645 }
646 }
647 }
648
649 return null;
650 }
651
652 /**
653 * Gets an implementation for a given object from this list of modules.
654 *
655 * @param object The object of the implementation to return.
656 *
657 * @return The implementation identified by {@code object} from the list or {@code null},
658 * if no implementation matching {@code object} is found.
659 *
660 * @throws NullPointerException if {@code object} is {@code null}.
661 *
662 * @see #getModule()
663 */
664 public Implementation getImplementation( final Object object )
665 {
666 return this.collectImplementation( object.getClass() );
667 }
668
669 /**
670 * Gets an implementation for a given name implementing a given specification from this list of
671 * modules.
672 *
673 * @param specification The identifier of the specification to return an implementation of.
674 * @param name The name of the implementation to return.
675 *
676 * @return The implementation with name {@code name} implementing the specification identified by
677 * {@code specification} from the list or {@code null}, if no such implementation is found.
678 *
679 * @throws NullPointerException if {@code specification} or {@code name} is {@code null}.
680 *
681 * @see #getModule()
682 */
683 public Implementation getImplementation( final String specification, final String name )
684 {
685 if ( specification == null )
686 {
687 throw new NullPointerException( "specification" );
688 }
689 if ( name == null )
690 {
691 throw new NullPointerException( "name" );
692 }
693
694 final Implementations implementations = this.getImplementations( specification );
695 if ( implementations != null )
696 {
697 return implementations.getImplementationByName( name );
698 }
699
700 return null;
701 }
702
703 /**
704 * Gets all dependencies of an implementation from this list of modules.
705 *
706 * @param implementation The identifier of the implementation to get all dependencies of.
707 *
708 * @return List of all dependencies of {@code implementation} from the list or {@code null},
709 * if no dependencies are found.
710 *
711 * @throws NullPointerException if {@code implementation} is {@code null}.
712 *
713 * @see #getModule()
714 */
715 public Dependencies getDependencies( final String implementation )
716 {
717 if ( implementation == null )
718 {
719 throw new NullPointerException( "implementation" );
720 }
721
722 final Dependencies dependencies = new Dependencies();
723 this.collectDependencies( this.getImplementation( implementation ), dependencies, new Implementations(), true );
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 Dependencies declaredDependencies = this.getDependencies( declaration.getIdentifier() );
750 if ( declaredDependencies != null )
751 {
752 for ( Dependency d : declaredDependencies.getDependency() )
753 {
754 if ( dependencies.getDependency( d.getName() ) == null )
755 {
756 dependencies.getDependency().add( d );
757 }
758 }
759 }
760 }
761
762 java.util.Collections.sort( dependencies.getDependency(), new java.util.Comparator<Dependency>()
763 {
764
765 public int compare( final Dependency o1, final Dependency o2 )
766 {
767 return o1.getName().compareTo( o2.getName() );
768 }
769
770 } );
771
772 return dependencies.getDependency().isEmpty() ? null : dependencies;
773 }
774
775 /**
776 * Gets all properties of an implementation from this list of modules.
777 *
778 * @param implementation The identifier of the implementation to get all properties of.
779 *
780 * @return List of all properties of {@code implementation} from the list or {@code null},
781 * if no properties are found.
782 *
783 * @throws NullPointerException if {@code implementation} is {@code null}.
784 *
785 * @see #getModule()
786 */
787 public Properties getProperties( final String implementation )
788 {
789 if ( implementation == null )
790 {
791 throw new NullPointerException( "implementation" );
792 }
793
794 final Properties properties = new Properties();
795 this.collectProperties( this.getImplementation( implementation ), properties, new Implementations(), true );
796
797 Implementation declaration = null;
798 final Implementation impl = this.getImplementation( implementation );
799
800 if ( impl != null && impl.getClazz() != null && !impl.getIdentifier().equals( impl.getClazz() ) )
801 {
802 for ( Module m : this.getModule() )
803 {
804 if ( m.getImplementations() != null )
805 {
806 for ( Implementation i : m.getImplementations().getImplementation() )
807 {
808 if ( i.getClazz() != null && i.getClazz().equals( i.getIdentifier() ) &&
809 i.getClazz().equals( impl.getClazz() ) )
810 {
811 declaration = i;
812 break;
813 }
814 }
815 }
816 }
817 }
818
819 if ( declaration != null )
820 {
821 final Properties declaredProperties = this.getProperties( declaration.getIdentifier() );
822 if ( declaredProperties != null )
823 {
824 for ( Property p : declaredProperties.getProperty() )
825 {
826 if ( properties.getProperty( p.getName() ) == null )
827 {
828 properties.getProperty().add( p );
829 }
830 }
831 }
832 }
833
834 final Properties specified = this.getSpecifiedProperties( implementation );
835
836 if ( specified != null )
837 {
838 for ( Property p : specified.getProperty() )
839 {
840 if ( properties.getProperty( p.getName() ) == null )
841 {
842 properties.getProperty().add( p );
843 }
844 }
845 }
846
847 java.util.Collections.sort( properties.getProperty(), new java.util.Comparator<Property>()
848 {
849
850 public int compare( final Property o1, final Property o2 )
851 {
852 return o1.getName().compareTo( o2.getName() );
853 }
854
855 } );
856
857 return properties.getProperty().isEmpty() ? null : properties;
858 }
859
860 /**
861 * Gets all properties specified for an implementation from this list of modules.
862 *
863 * @param implementation The identifier of the implementation to return specified properties of.
864 *
865 * @return List of all properties specified for {@code implementation} from the list or {@code null},
866 * if no properties are found.
867 *
868 * @throws NullPointerException if {@code implementation} is {@code null}.
869 *
870 * @see #getModule()
871 */
872 public Properties getSpecifiedProperties( final String implementation )
873 {
874 if ( implementation == null )
875 {
876 throw new NullPointerException( "implementation" );
877 }
878
879 final Properties properties = new Properties();
880 final Specifications specs = this.getSpecifications( implementation );
881
882 if ( specs != null )
883 {
884 for ( Specification s : specs.getSpecification() )
885 {
886 if ( s.getProperties() != null )
887 {
888 properties.getProperty().addAll( s.getProperties().getProperty() );
889 }
890 }
891 }
892
893 java.util.Collections.sort( properties.getProperty(), new java.util.Comparator<Property>()
894 {
895
896 public int compare( final Property o1, final Property o2 )
897 {
898 return o1.getName().compareTo( o2.getName() );
899 }
900
901 } );
902
903 return properties.getProperty().isEmpty() ? null : properties;
904 }
905
906 /**
907 * Gets all messages of an implementation from this list of modules.
908 *
909 * @param implementation The identifier of the implementation to get all messages of.
910 *
911 * @return List of all messages of {@code implementation} from the list or {@code null},
912 * if no messages are found.
913 *
914 * @throws NullPointerException if {@code implementation} is {@code null}.
915 *
916 * @see #getModule()
917 */
918 public Messages getMessages( final String implementation )
919 {
920 if ( implementation == null )
921 {
922 throw new NullPointerException( "implementation" );
923 }
924
925 final Messages msgs = new Messages();
926 this.collectMessages( this.getImplementation( implementation ), msgs, new Implementations(), true );
927
928 Implementation declaration = null;
929 final Implementation impl = this.getImplementation( implementation );
930
931 if ( impl != null && impl.getClazz() != null && !impl.getIdentifier().equals( impl.getClazz() ) )
932 {
933 for ( Module m : this.getModule() )
934 {
935 if ( m.getImplementations() != null )
936 {
937 for ( Implementation i : m.getImplementations().getImplementation() )
938 {
939 if ( i.getClazz() != null && i.getClazz().equals( i.getIdentifier() ) &&
940 i.getClazz().equals( impl.getClazz() ) )
941 {
942 declaration = i;
943 break;
944 }
945 }
946 }
947 }
948 }
949
950 if ( declaration != null )
951 {
952 final Messages declaredMessages = this.getMessages( declaration.getIdentifier() );
953 if ( declaredMessages != null )
954 {
955 for ( Message m : declaredMessages.getMessage() )
956 {
957 if ( msgs.getMessage( m.getName() ) == null )
958 {
959 msgs.getMessage().add( m );
960 }
961 }
962 }
963 }
964
965 java.util.Collections.sort( msgs.getMessage(), new java.util.Comparator<Message>()
966 {
967
968 public int compare( final Message o1, final Message o2 )
969 {
970 return o1.getName().compareTo( o2.getName() );
971 }
972
973 } );
974
975 return msgs.getMessage().isEmpty() ? null : msgs;
976 }
977
978 /**
979 * Gets all implementations implementing a given specification from this list of modules.
980 *
981 * @param specification The identifier of the specification to return all implementations of.
982 *
983 * @return All implementations implementing the specification identified by {@code specification}
984 * from the list or {@code null}, if no implementation implementing {@code specification} is found.
985 *
986 * @throws NullPointerException if {@code specification} is {@code null}.
987 *
988 * @see #getModule()
989 */
990 public Implementations getImplementations( final String specification )
991 {
992 if ( specification == null )
993 {
994 throw new NullPointerException( "specification" );
995 }
996
997 final Implementations implementations = new Implementations();
998 for ( Module m : this.getModule() )
999 {
1000 if ( m.getImplementations() != null )
1001 {
1002 for ( Implementation i : m.getImplementations().getImplementation() )
1003 {
1004 final Specifications specs = this.getSpecifications( i.getIdentifier() );
1005
1006 if ( specs != null )
1007 {
1008 for ( Specification s : specs.getSpecification() )
1009 {
1010 if ( specification.equals( s.getIdentifier() ) )
1011 {
1012 implementations.getImplementation().add( i );
1013 }
1014 }
1015 }
1016 }
1017 }
1018 }
1019
1020 return implementations.getImplementation().size() > 0 ? implementations : null;
1021 }
1022
1023 /**
1024 * Merges this list of modules to a single module.
1025 *
1026 * @return A module holding all model objects from the list.
1027 */
1028 public Module getMergedModule()
1029 {
1030 final Modules copy = this.clone();
1031 final Module mergedModule = new Module();
1032
1033 for ( Module m : copy.getModule() )
1034 {
1035 final java.util.Set<String> referencedMessages = new java.util.HashSet<String>();
1036 final java.util.Set<String> referencedProperties = new java.util.HashSet<String>();
1037
1038 if ( m.getImplementations() != null )
1039 {
1040 for ( Implementation i : m.getImplementations().getImplementation() )
1041 {
1042 if ( mergedModule.getImplementations() == null )
1043 {
1044 mergedModule.setImplementations( new Implementations() );
1045 }
1046
1047 if ( i.getMessages() != null && !i.getMessages().getReference().isEmpty() )
1048 {
1049 for ( java.util.Iterator<MessageReference> it = i.getMessages().getReference().iterator();
1050 it.hasNext(); )
1051 {
1052 final String messageName = it.next().getName();
1053 i.getMessages().getMessage().add( m.getMessages().getMessage( messageName ) );
1054 referencedMessages.add( messageName );
1055 it.remove();
1056 }
1057 }
1058
1059 if ( i.getProperties() != null && !i.getProperties().getReference().isEmpty() )
1060 {
1061 for ( java.util.Iterator<PropertyReference> it = i.getProperties().getReference().iterator();
1062 it.hasNext(); )
1063 {
1064 final String propertyName = it.next().getName();
1065 i.getProperties().getProperty().add( m.getProperties().getProperty( propertyName ) );
1066 referencedProperties.add( propertyName );
1067 it.remove();
1068 }
1069 }
1070
1071 mergedModule.getImplementations().getImplementation().add( i );
1072 }
1073 }
1074
1075 if ( m.getSpecifications() != null )
1076 {
1077 if ( mergedModule.getSpecifications() == null )
1078 {
1079 mergedModule.setSpecifications( new Specifications() );
1080 }
1081
1082 for ( Specification s : m.getSpecifications().getSpecification() )
1083 {
1084 if ( s.getProperties() != null && !s.getProperties().getReference().isEmpty() )
1085 {
1086 for ( java.util.Iterator<PropertyReference> it = s.getProperties().getReference().iterator();
1087 it.hasNext(); )
1088 {
1089 final String propertyName = it.next().getName();
1090 s.getProperties().getProperty().add( m.getProperties().getProperty( propertyName ) );
1091 referencedProperties.add( propertyName );
1092 it.remove();
1093 }
1094 }
1095
1096 mergedModule.getSpecifications().getSpecification().add( s );
1097 }
1098 }
1099
1100 for ( String messageName : referencedMessages )
1101 {
1102 for ( java.util.Iterator<Message> it = m.getMessages().getMessage().iterator(); it.hasNext(); )
1103 {
1104 if ( messageName.equals( it.next().getName() ) )
1105 {
1106 it.remove();
1107 break;
1108 }
1109 }
1110 }
1111
1112 for ( String propertyName : referencedProperties )
1113 {
1114 for ( java.util.Iterator<Property> it = m.getProperties().getProperty().iterator(); it.hasNext(); )
1115 {
1116 if ( propertyName.equals( it.next().getName() ) )
1117 {
1118 it.remove();
1119 break;
1120 }
1121 }
1122 }
1123
1124 if ( m.getProperties() != null && !m.getProperties().getProperty().isEmpty() )
1125 {
1126 if ( mergedModule.getProperties() == null )
1127 {
1128 mergedModule.setProperties( new Properties() );
1129 }
1130
1131 mergedModule.getProperties().getProperty().addAll( m.getProperties().getProperty() );
1132 }
1133
1134 if ( m.getMessages() != null && !m.getMessages().getMessage().isEmpty() )
1135 {
1136 if ( mergedModule.getMessages() == null )
1137 {
1138 mergedModule.setMessages( new Messages() );
1139 }
1140
1141 mergedModule.getMessages().getMessage().addAll( m.getMessages().getMessage() );
1142 }
1143 }
1144
1145 return mergedModule;
1146 }
1147
1148 /**
1149 * Gets the instance of an object from this list of modules.
1150 *
1151 * @param object The object to get the instance of.
1152 *
1153 * @return The instance of {@code object} from the list or {@code null} if no such instance is found.
1154 *
1155 * @throws NullPointerException if {@code object} is {@code null}.
1156 *
1157 * @see #getModule()
1158 * @see #createObject(org.jomc.model.Instance instance, java.lang.ClassLoader classLoader)
1159 */
1160 public Instance getInstance( final Object object )
1161 {
1162 if ( object == null )
1163 {
1164 throw new NullPointerException( "object" );
1165 }
1166
1167 synchronized ( this.objects )
1168 {
1169 Instance instance = (Instance) this.objects.get( object );
1170
1171 if ( instance == null )
1172 {
1173 final Implementation i = this.getImplementation( object );
1174
1175 if ( i != null )
1176 {
1177 instance = this.getInstance( i.getIdentifier() );
1178 if ( instance != null )
1179 {
1180 this.objects.put( object, instance );
1181 }
1182 }
1183 }
1184
1185 return instance;
1186 }
1187 }
1188
1189 /**
1190 * Gets an instance for an implementation from this list of modules.
1191 *
1192 * @param implementation The identifier of the implementation to get an instance for.
1193 *
1194 * @return An instance for the implementation identified by {@code implementation} from the list or {@code null}, if
1195 * no such instance is found.
1196 *
1197 * @throws NullPointerException if {@code implementation} is {@code null}.
1198 *
1199 * @see #getModule()
1200 */
1201 public Instance getInstance( final String implementation )
1202 {
1203 if ( implementation == null )
1204 {
1205 throw new NullPointerException( "implementation" );
1206 }
1207
1208 final Implementation i = this.getImplementation( implementation );
1209
1210 if ( i != null && i.getClazz() != null )
1211 {
1212 final Instance instance = new Instance();
1213 instance.setIdentifier( i.getIdentifier() );
1214 instance.setName( i.getName() );
1215 instance.setClazz( i.getClazz() );
1216 instance.setStateless( i.isStateless() );
1217 instance.setDependencies( this.getDependencies( implementation ) );
1218 instance.setProperties( this.getProperties( implementation ) );
1219 instance.setMessages( this.getMessages( implementation ) );
1220 instance.setSpecifications( this.getSpecifications( implementation ) );
1221 this.collectAny( i, instance.getAny(), new Implementations(), true );
1222 return instance;
1223 }
1224
1225 return null;
1226 }
1227
1228 /**
1229 * Gets an instance for an implementation from this list of modules overridden with a given dependency.
1230 *
1231 * @param implementation The identifier of the implementation to get an instance for.
1232 * @param dependency The dependency to use for overriding model objects of the instance.
1233 *
1234 * @return An instance for the implementation identified by {@code implementation} from the list with any model
1235 * objects overridden using {@code dependency} or {@code null}, if no such instance is found.
1236 *
1237 * @throws NullPointerException if {@code implementation} or {@code dependency} is {@code null}.
1238 *
1239 * @see #getModule()
1240 */
1241 public Instance getInstance( final String implementation, final Dependency dependency )
1242 {
1243 if ( implementation == null )
1244 {
1245 throw new NullPointerException( "implementation" );
1246 }
1247 if ( dependency == null )
1248 {
1249 throw new NullPointerException( "dependency" );
1250 }
1251
1252 Instance instance = this.getInstance( implementation );
1253
1254 if ( instance != null )
1255 {
1256 final Specification dependencySpecification = this.getSpecification( dependency.getIdentifier() );
1257 if ( dependencySpecification != null && dependencySpecification.getScope() == null &&
1258 dependency.getProperties() != null && !dependency.getProperties().getProperty().isEmpty() )
1259 {
1260 instance = new Instance( instance );
1261 final Properties properties = new Properties();
1262 properties.getProperty().addAll( dependency.getProperties().getProperty() );
1263
1264 if ( instance.getProperties() != null )
1265 {
1266 for ( Property p : instance.getProperties().getProperty() )
1267 {
1268 if ( properties.getProperty( p.getName() ) == null )
1269 {
1270 properties.getProperty().add( p );
1271 }
1272 }
1273 }
1274
1275 instance.setProperties( properties );
1276 }
1277 }
1278
1279 return instance;
1280 }
1281
1282 /**
1283 * Creates an object for a given instance from this list of modules.
1284 *
1285 * @param instance The instance to create an object of.
1286 * @param classLoader The class loader to use for creating the object or {@code null} to use the bootstrap class
1287 * loader.
1288 *
1289 * @return A new object of {@code instance} from the list or {@code null} if no such object is found.
1290 *
1291 * @throws NullPointerException if {@code instance} is {@code null},
1292 * @throws InstantiationException if creating an object fails.
1293 *
1294 * @see #getModule()
1295 */
1296 public Object createObject( final Instance instance, final ClassLoader classLoader ) throws InstantiationException
1297 {
1298 if ( instance == null )
1299 {
1300 throw new NullPointerException( "instance" );
1301 }
1302
1303 Object object = null;
1304
1305 try
1306 {
1307 final Class clazz = Class.forName( instance.getClazz(), true, classLoader );
1308
1309 if ( java.lang.reflect.Modifier.isPublic( clazz.getModifiers() ) )
1310 {
1311 java.lang.reflect.Constructor ctor = null;
1312
1313 if ( !java.lang.reflect.Modifier.isAbstract( clazz.getModifiers() ) )
1314 {
1315 try
1316 {
1317 ctor = clazz.getConstructor( NO_CLASSES );
1318 }
1319 catch ( final NoSuchMethodException e )
1320 {
1321 ctor = null;
1322 }
1323 }
1324
1325 boolean assignable = true;
1326 if ( instance.getSpecifications() != null )
1327 {
1328 for ( Specification s : instance.getSpecifications().getSpecification() )
1329 {
1330 if ( s.getClazz() != null )
1331 {
1332 final Class specClass = Class.forName( s.getClazz(), true, classLoader );
1333 if ( !specClass.isAssignableFrom( clazz ) )
1334 {
1335 assignable = false;
1336 break;
1337 }
1338 }
1339 }
1340 }
1341
1342 if ( ctor != null && assignable )
1343 {
1344 synchronized ( this.objects )
1345 {
1346 object = clazz.newInstance();
1347 this.objects.put( object, instance );
1348 }
1349 }
1350 else
1351 {
1352 java.lang.reflect.Method factoryMethod = null;
1353 String methodName = null;
1354
1355 char[] c = instance.getName().toCharArray();
1356 c[0] = Character.toUpperCase( c[0] );
1357 methodName = "get" + String.valueOf( c );
1358
1359 boolean javaIdentifier = Character.isJavaIdentifierStart( c[0] );
1360 if ( javaIdentifier )
1361 {
1362 for ( int idx = c.length - 1; idx > 0; idx-- )
1363 {
1364 if ( !Character.isJavaIdentifierPart( c[idx] ) )
1365 {
1366 javaIdentifier = false;
1367 break;
1368 }
1369 }
1370 }
1371
1372 if ( javaIdentifier )
1373 {
1374 try
1375 {
1376 factoryMethod = clazz.getMethod( methodName, (Class[]) null );
1377 }
1378 catch ( NoSuchMethodException e )
1379 {
1380 factoryMethod = null;
1381 }
1382 }
1383
1384 if ( factoryMethod == null )
1385 {
1386 try
1387 {
1388 factoryMethod = clazz.getMethod( "getObject", (Class[]) null );
1389 }
1390 catch ( NoSuchMethodException e )
1391 {
1392 factoryMethod = null;
1393 }
1394 }
1395
1396 if ( factoryMethod == null )
1397 {
1398 throw new InstantiationException( this.getMessage( "failedCreatingObject", new Object[]
1399 {
1400 instance.getIdentifier(), clazz.getName(), methodName
1401 } ) );
1402
1403 }
1404
1405 if ( java.lang.reflect.Modifier.isStatic( factoryMethod.getModifiers() ) )
1406 {
1407 synchronized ( this.objects )
1408 {
1409 object = factoryMethod.invoke( null, (Object[]) null );
1410 this.objects.put( object, instance );
1411 }
1412 }
1413 else if ( ctor != null )
1414 {
1415 synchronized ( this.objects )
1416 {
1417 final Object o = ctor.newInstance();
1418 this.objects.put( o, instance );
1419 object = factoryMethod.invoke( o, (Object[]) null );
1420 this.objects.put( object, instance );
1421 this.objects.remove( o );
1422 }
1423 }
1424 else
1425 {
1426 throw new InstantiationException( this.getMessage( "failedCreatingObject", new Object[]
1427 {
1428 instance.getIdentifier(), clazz.getName(), methodName
1429 } ) );
1430
1431 }
1432 }
1433 }
1434
1435 return object;
1436 }
1437 catch ( final java.lang.reflect.InvocationTargetException e )
1438 {
1439 throw (InstantiationException) new InstantiationException().initCause(
1440 e.getTargetException() != null ? e.getTargetException() : e );
1441
1442 }
1443 catch ( final IllegalAccessException e )
1444 {
1445 throw (InstantiationException) new InstantiationException().initCause( e );
1446 }
1447 catch ( final ClassNotFoundException e )
1448 {
1449 throw (InstantiationException) new InstantiationException().initCause( e );
1450 }
1451 }
1452
1453 void collectSpecifications( final Implementation implementation, final Specifications specifications,
1454 final Implementations seen, final boolean includeDeclared )
1455 {
1456 if ( implementation != null )
1457 {
1458 if ( seen.getImplementation( implementation.getIdentifier() ) == null )
1459 {
1460 seen.getImplementation().add( implementation );
1461
1462 if ( includeDeclared && implementation.getSpecifications() != null )
1463 {
1464 for ( SpecificationReference r : implementation.getSpecifications().getReference() )
1465 {
1466 if ( specifications.getReference( r.getIdentifier() ) == null )
1467 {
1468 specifications.getReference().add( r );
1469
1470 final Specification s = this.getSpecification( r.getIdentifier() );
1471 if ( s != null && specifications.getSpecification( s.getIdentifier() ) == null )
1472 {
1473 specifications.getSpecification().add( s );
1474 }
1475 }
1476 }
1477 }
1478
1479 if ( implementation.getImplementations() != null )
1480 {
1481 for ( ImplementationReference r : implementation.getImplementations().getReference() )
1482 {
1483 this.collectSpecifications(
1484 this.getImplementation( r.getIdentifier() ), specifications, seen, true );
1485
1486 }
1487 }
1488 }
1489 }
1490 }
1491
1492 void collectDependencies( final Implementation implementation, final Dependencies dependencies,
1493 final Implementations seen, final boolean includeDeclared )
1494 {
1495 if ( implementation != null )
1496 {
1497 if ( seen.getImplementation( implementation.getIdentifier() ) == null )
1498 {
1499 seen.getImplementation().add( implementation );
1500
1501 if ( includeDeclared && implementation.getDependencies() != null )
1502 {
1503 for ( Dependency d : implementation.getDependencies().getDependency() )
1504 {
1505 final Dependency dependency = dependencies.getDependency( d.getName() );
1506
1507 if ( dependency != null )
1508 {
1509 if ( d.getProperties() != null )
1510 {
1511 if ( dependency.getProperties() == null )
1512 {
1513 dependency.setProperties( new Properties() );
1514 }
1515
1516 for ( Property p : d.getProperties().getProperty() )
1517 {
1518 if ( dependency.getProperties().getProperty( p.getName() ) == null )
1519 {
1520 dependency.getProperties().getProperty().add( p );
1521 }
1522 }
1523 }
1524 }
1525 else
1526 {
1527 dependencies.getDependency().add( d );
1528 }
1529 }
1530 }
1531
1532 if ( implementation.getImplementations() != null )
1533 {
1534 for ( ImplementationReference r : implementation.getImplementations().getReference() )
1535 {
1536 this.collectDependencies(
1537 this.getImplementation( r.getIdentifier() ), dependencies, seen, true );
1538
1539 }
1540 }
1541 }
1542 }
1543 }
1544
1545 void collectProperties( final Implementation implementation, final Properties properties,
1546 final Implementations seen, final boolean includeDeclared )
1547 {
1548 if ( implementation != null )
1549 {
1550 if ( seen.getImplementation( implementation.getIdentifier() ) == null )
1551 {
1552 seen.getImplementation().add( implementation );
1553
1554 if ( includeDeclared && implementation.getProperties() != null )
1555 {
1556 for ( Property p : implementation.getProperties().getProperty() )
1557 {
1558 if ( properties.getProperty( p.getName() ) == null )
1559 {
1560 properties.getProperty().add( p );
1561 }
1562 }
1563 if ( !implementation.getProperties().getReference().isEmpty() )
1564 {
1565 final Module m = this.getModuleOfImplementation( implementation.getIdentifier() );
1566
1567 if ( m != null )
1568 {
1569 for ( PropertyReference ref : implementation.getProperties().getReference() )
1570 {
1571 if ( properties.getProperty( ref.getName() ) == null )
1572 {
1573 Property referenced = m.getProperties().getProperty( ref.getName() );
1574 if ( referenced != null )
1575 {
1576 referenced = new Property( referenced );
1577 referenced.setDeprecated( ref.isDeprecated() );
1578 referenced.setFinal( ref.isFinal() );
1579 referenced.setOverride( ref.isOverride() );
1580 properties.getProperty().add( referenced );
1581 }
1582 }
1583 }
1584 }
1585 }
1586 }
1587
1588 if ( implementation.getImplementations() != null )
1589 {
1590 for ( ImplementationReference r : implementation.getImplementations().getReference() )
1591 {
1592 this.collectProperties( this.getImplementation( r.getIdentifier() ), properties, seen, true );
1593 }
1594 }
1595 }
1596 }
1597 }
1598
1599 void collectMessages( final Implementation implementation, final Messages messages,
1600 final Implementations seen, boolean includeDeclared )
1601 {
1602 if ( implementation != null )
1603 {
1604 if ( seen.getImplementation( implementation.getIdentifier() ) == null )
1605 {
1606 seen.getImplementation().add( implementation );
1607
1608 if ( includeDeclared && implementation.getMessages() != null )
1609 {
1610 for ( Message msg : implementation.getMessages().getMessage() )
1611 {
1612 if ( messages.getMessage( msg.getName() ) == null )
1613 {
1614 messages.getMessage().add( msg );
1615 }
1616 }
1617 if ( !implementation.getMessages().getReference().isEmpty() )
1618 {
1619 final Module m = this.getModuleOfImplementation( implementation.getIdentifier() );
1620
1621 if ( m != null )
1622 {
1623 for ( MessageReference ref : implementation.getMessages().getReference() )
1624 {
1625 if ( messages.getMessage( ref.getName() ) == null )
1626 {
1627 Message referenced = m.getMessages().getMessage( ref.getName() );
1628 if ( referenced != null )
1629 {
1630 referenced = new Message( referenced );
1631 referenced.setDeprecated( ref.isDeprecated() );
1632 referenced.setFinal( ref.isFinal() );
1633 referenced.setOverride( ref.isOverride() );
1634 messages.getMessage().add( referenced );
1635 }
1636 }
1637 }
1638 }
1639 }
1640 }
1641
1642 if ( implementation.getImplementations() != null )
1643 {
1644 for ( ImplementationReference r : implementation.getImplementations().getReference() )
1645 {
1646 this.collectMessages( this.getImplementation( r.getIdentifier() ), messages, seen, true );
1647 }
1648 }
1649 }
1650 }
1651 }
1652
1653 void collectAny( final Implementation implementation, final List<Object> any, final Implementations seen,
1654 final boolean includeDeclared )
1655 {
1656 if ( implementation != null )
1657 {
1658 if ( seen.getImplementation( implementation.getIdentifier() ) == null )
1659 {
1660 seen.getImplementation().add( implementation );
1661
1662 if ( includeDeclared && !implementation.getAny().isEmpty() )
1663 {
1664 for ( Object o : implementation.getAny() )
1665 {
1666 if ( o instanceof org.w3c.dom.Element )
1667 {
1668 if ( this.getElement( any, (org.w3c.dom.Element) o ) == null )
1669 {
1670 any.add( o );
1671 }
1672
1673 continue;
1674 }
1675
1676 if ( o instanceof javax.xml.bind.JAXBElement )
1677 {
1678 if ( this.getElement( any, (javax.xml.bind.JAXBElement) o ) == null )
1679 {
1680 any.add( o );
1681 }
1682
1683 continue;
1684 }
1685
1686 any.add( o );
1687 }
1688 }
1689
1690 if ( implementation.getImplementations() != null )
1691 {
1692 for ( ImplementationReference r : implementation.getImplementations().getReference() )
1693 {
1694 this.collectAny( this.getImplementation( r.getIdentifier() ), any, seen, true );
1695 }
1696 }
1697 }
1698 }
1699 }
1700
1701 private Implementation collectImplementation( final Class clazz )
1702 {
1703 Implementation i = this.getImplementation( clazz );
1704 if ( i == null && clazz.getSuperclass() != null )
1705 {
1706 i = this.collectImplementation( clazz.getSuperclass() );
1707 }
1708
1709 return i;
1710 }
1711
1712 private org.w3c.dom.Element getElement( final List<Object> list, final org.w3c.dom.Element e )
1713 {
1714 for ( Object o : list )
1715 {
1716 if ( o instanceof org.w3c.dom.Element )
1717 {
1718 final org.w3c.dom.Element current = (org.w3c.dom.Element) o;
1719 if ( ( e.getNamespaceURI() == null
1720 ? current.getNamespaceURI() == null
1721 : e.getNamespaceURI().equals( current.getNamespaceURI() ) ) &&
1722 ( e.getLocalName() == null
1723 ? current.getLocalName() == null
1724 : e.getLocalName().equals( current.getLocalName() ) ) )
1725 {
1726 return current;
1727 }
1728 }
1729 }
1730
1731 return null;
1732 }
1733
1734 private javax.xml.bind.JAXBElement getElement( final List<Object> list, final javax.xml.bind.JAXBElement e )
1735 {
1736 for ( Object o : list )
1737 {
1738 if ( o instanceof javax.xml.bind.JAXBElement )
1739 {
1740 final javax.xml.bind.JAXBElement current = (javax.xml.bind.JAXBElement) o;
1741 if ( e.getName().equals( current.getName() ) )
1742 {
1743 return current;
1744 }
1745 }
1746 }
1747
1748 return null;
1749 }
1750
1751 private void resolveClasspath( final Module cpModule, final ClassLoader classLoader )
1752 {
1753 for ( Module m : this.getModule() )
1754 {
1755 if ( m.getSpecifications() != null )
1756 {
1757 this.resolveClasspath( m.getSpecifications(), cpModule, classLoader );
1758 }
1759
1760 if ( m.getImplementations() != null )
1761 {
1762 this.resolveClasspath( m.getImplementations(), cpModule, classLoader );
1763 }
1764 }
1765 }
1766
1767 private void resolveClasspath( final SpecificationReference ref, final Module cpModule,
1768 final ClassLoader classLoader )
1769 {
1770 if ( this.getSpecification( ref.getIdentifier() ) == null )
1771 {
1772 this.resolveClasspath( ref.getIdentifier(), cpModule, classLoader );
1773 }
1774 }
1775
1776 private void resolveClasspath( final Specifications references, final Module cpModule,
1777 final ClassLoader classLoader )
1778 {
1779 for ( SpecificationReference ref : references.getReference() )
1780 {
1781 this.resolveClasspath( ref, cpModule, classLoader );
1782 }
1783 }
1784
1785 private void resolveClasspath( final Implementations implementations, final Module cpModule,
1786 final ClassLoader classLoader )
1787 {
1788 for ( Implementation implementation : implementations.getImplementation() )
1789 {
1790 if ( implementation.getSpecifications() != null )
1791 {
1792 this.resolveClasspath( implementation.getSpecifications(), cpModule, classLoader );
1793 }
1794
1795 if ( implementation.getDependencies() != null )
1796 {
1797 this.resolveClasspath( implementation.getDependencies(), cpModule, classLoader );
1798 }
1799 }
1800 }
1801
1802 private void resolveClasspath( final Dependencies dependencies, final Module cpModule,
1803 final ClassLoader classLoader )
1804 {
1805 for ( Dependency dependency : dependencies.getDependency() )
1806 {
1807 this.resolveClasspath( dependency, cpModule, classLoader );
1808 }
1809 }
1810
1811 private boolean resolveClasspath( final String identifier, final Module cpModule, final ClassLoader classLoader )
1812 {
1813 boolean classpathSpecification = false;
1814 Specification specification = cpModule.getSpecifications() == null
1815 ? null : cpModule.getSpecifications().getSpecification( identifier );
1816
1817 if ( specification == null )
1818 {
1819 try
1820 {
1821 final Class classpathSpec = Class.forName( identifier, true, classLoader );
1822 if ( java.lang.reflect.Modifier.isPublic( classpathSpec.getModifiers() ) )
1823 {
1824 classpathSpecification = true;
1825 String vendor = null;
1826 String version = null;
1827
1828 if ( classpathSpec.getPackage() != null )
1829 {
1830 vendor = classpathSpec.getPackage().getSpecificationVendor();
1831 version = classpathSpec.getPackage().getSpecificationVersion();
1832 }
1833
1834 specification = new Specification();
1835 specification.setIdentifier( identifier );
1836 specification.setClazz( classpathSpec.getName() );
1837 specification.setMultiplicity( Multiplicity.MANY );
1838 specification.setVendor( vendor );
1839 specification.setVersion( version );
1840
1841 if ( cpModule.getSpecifications() == null )
1842 {
1843 cpModule.setSpecifications( new Specifications() );
1844 }
1845
1846 cpModule.getSpecifications().getSpecification().add( specification );
1847
1848 this.resolveClasspath( specification, cpModule, classLoader );
1849 }
1850 }
1851 catch ( final ClassNotFoundException e )
1852 {
1853 classpathSpecification = false;
1854 }
1855 }
1856
1857 return classpathSpecification;
1858 }
1859
1860 private boolean resolveClasspath( final Specification specification, final Module cpModule,
1861 final ClassLoader classLoader )
1862 {
1863 boolean classpathImplementation = false;
1864 Implementation implementation =
1865 cpModule.getImplementations() == null ? null
1866 : cpModule.getImplementations().getImplementation( specification.getIdentifier() );
1867
1868 if ( implementation == null )
1869 {
1870 String name = null;
1871
1872 try
1873 {
1874 final Class classpathImpl = Class.forName( specification.getClazz(), true, classLoader );
1875
1876 if ( java.lang.reflect.Modifier.isPublic( classpathImpl.getModifiers() ) )
1877 {
1878 if ( !java.lang.reflect.Modifier.isAbstract( classpathImpl.getModifiers() ) )
1879 {
1880 try
1881 {
1882 classpathImpl.getConstructor( NO_CLASSES );
1883 name = "init";
1884 classpathImplementation = true;
1885 }
1886 catch ( final NoSuchMethodException e )
1887 {
1888 classpathImplementation = false;
1889 }
1890 }
1891
1892 if ( !classpathImplementation )
1893 {
1894 final char[] c = classpathImpl.getName().substring(
1895 classpathImpl.getPackage().getName().length() + 1 ).toCharArray();
1896
1897 name = String.valueOf( c );
1898 c[0] = Character.toUpperCase( c[0] );
1899
1900 if ( this.checkFactoryMethod( classpathImpl, classpathImpl, "getDefault" ) )
1901 {
1902 name = "default";
1903 classpathImplementation = true;
1904 }
1905 else if ( this.checkFactoryMethod( classpathImpl, classpathImpl, "getInstance" ) )
1906 {
1907 name = "instance";
1908 classpathImplementation = true;
1909 }
1910 else if ( this.checkFactoryMethod( classpathImpl, classpathImpl, "get" + String.valueOf( c ) ) )
1911 {
1912 classpathImplementation = true;
1913 }
1914
1915 }
1916
1917 if ( classpathImplementation )
1918 {
1919 String vendor = null;
1920 String version = null;
1921 if ( classpathImpl.getPackage() != null )
1922 {
1923 vendor = classpathImpl.getPackage().getImplementationVendor();
1924 version = classpathImpl.getPackage().getImplementationVersion();
1925 }
1926
1927 implementation = new Implementation();
1928 implementation.setVendor( vendor );
1929 implementation.setFinal( true );
1930 implementation.setName( name );
1931 implementation.setIdentifier( specification.getIdentifier() );
1932 implementation.setClazz( classpathImpl.getName() );
1933 implementation.setVersion( version );
1934
1935 final Specifications implemented = new Specifications();
1936 final SpecificationReference ref = new SpecificationReference();
1937 ref.setIdentifier( specification.getIdentifier() );
1938 ref.setVersion( specification.getVersion() );
1939 implemented.getReference().add( ref );
1940 implementation.setSpecifications( implemented );
1941
1942 if ( cpModule.getImplementations() == null )
1943 {
1944 cpModule.setImplementations( new Implementations() );
1945 }
1946
1947 cpModule.getImplementations().getImplementation().add( implementation );
1948 }
1949 }
1950 }
1951 catch ( final ClassNotFoundException e )
1952 {
1953 classpathImplementation = false;
1954 }
1955 }
1956
1957 return classpathImplementation;
1958 }
1959
1960 private boolean checkFactoryMethod( final Class clazz, final Class type, final String methodName )
1961 {
1962 boolean factoryMethod = false;
1963
1964 try
1965 {
1966 final java.lang.reflect.Method m = clazz.getMethod( methodName, (Class[]) null );
1967 factoryMethod = java.lang.reflect.Modifier.isStatic( m.getModifiers() ) &&
1968 type.isAssignableFrom( m.getReturnType() );
1969
1970 }
1971 catch ( final NoSuchMethodException e )
1972 {
1973 factoryMethod = false;
1974 }
1975
1976 return factoryMethod;
1977 }
1978
1979 private String getMessage( final String key, final Object args )
1980 {
1981 return new java.text.MessageFormat( java.util.ResourceBundle.getBundle(
1982 Modules.class.getName().replace( '.', '/' ), java.util.Locale.getDefault() ).
1983 getString( key ) ).format( args );
1984
1985 }
1986
1987
1988 }