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