View Javadoc

1   /*
2    *  jDTAUS Core Container Mojo
3    *  Copyright (C) 2005 Christian Schulte
4    *  <cs@schulte.it>
5    *
6    *  This library is free software; you can redistribute it and/or
7    *  modify it under the terms of the GNU Lesser General Public
8    *  License as published by the Free Software Foundation; either
9    *  version 2.1 of the License, or any later version.
10   *
11   *  This library is distributed in the hope that it will be useful,
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   *  Lesser General Public License for more details.
15   *
16   *  You should have received a copy of the GNU Lesser General Public
17   *  License along with this library; if not, write to the Free Software
18   *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19   *
20   */
21  package org.jdtaus.core.container.mojo.model;
22  
23  import java.math.BigInteger;
24  import java.util.Iterator;
25  import java.util.Locale;
26  import javax.xml.bind.JAXBContext;
27  import javax.xml.bind.JAXBException;
28  import javax.xml.bind.Marshaller;
29  import javax.xml.bind.Unmarshaller;
30  import org.codehaus.plexus.logging.AbstractLogEnabled;
31  import org.jdtaus.core.container.mojo.model.container.ArgumentElement;
32  import org.jdtaus.core.container.mojo.model.container.ArgumentType;
33  import org.jdtaus.core.container.mojo.model.container.ArgumentsElement;
34  import org.jdtaus.core.container.mojo.model.container.DependenciesElement;
35  import org.jdtaus.core.container.mojo.model.container.DependencyElement;
36  import org.jdtaus.core.container.mojo.model.container.ImplementationElement;
37  import org.jdtaus.core.container.mojo.model.container.ImplementationsElement;
38  import org.jdtaus.core.container.mojo.model.container.Message;
39  import org.jdtaus.core.container.mojo.model.container.MessageElement;
40  import org.jdtaus.core.container.mojo.model.container.MessageReference;
41  import org.jdtaus.core.container.mojo.model.container.MessagesElement;
42  import org.jdtaus.core.container.mojo.model.container.ModelObject;
43  import org.jdtaus.core.container.mojo.model.container.Module;
44  import org.jdtaus.core.container.mojo.model.container.ModuleElement;
45  import org.jdtaus.core.container.mojo.model.container.ModulesElement;
46  import org.jdtaus.core.container.mojo.model.container.Multiplicity;
47  import org.jdtaus.core.container.mojo.model.container.ObjectFactory;
48  import org.jdtaus.core.container.mojo.model.container.Properties;
49  import org.jdtaus.core.container.mojo.model.container.PropertiesElement;
50  import org.jdtaus.core.container.mojo.model.container.Property;
51  import org.jdtaus.core.container.mojo.model.container.PropertyElement;
52  import org.jdtaus.core.container.mojo.model.container.PropertyType;
53  import org.jdtaus.core.container.mojo.model.container.Scope;
54  import org.jdtaus.core.container.mojo.model.container.SpecificationElement;
55  import org.jdtaus.core.container.mojo.model.container.SpecificationReference;
56  import org.jdtaus.core.container.mojo.model.container.Specifications;
57  import org.jdtaus.core.container.mojo.model.container.SpecificationsElement;
58  import org.jdtaus.core.container.mojo.model.container.Text;
59  import org.jdtaus.core.container.mojo.model.container.Texts;
60  import org.jdtaus.core.container.mojo.model.spring.BeanElement;
61  import org.jdtaus.core.container.mojo.model.spring.BeansElement;
62  
63  /**
64   * Manages the {@code http://jdtaus.org/core/model/container} namespace.
65   *
66   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
67   * @version $JDTAUS: ModelManager.java 8743 2012-10-07 03:06:20Z schulte $
68   * @plexus.component role="org.jdtaus.core.container.mojo.model.ModelManager"
69   *                   role-hint="default"
70   */
71  public class ModelManager extends AbstractLogEnabled
72  {
73  
74      /** Package names of the container model classes. */
75      private static final String CONTAINER_MODEL_PACKAGES =
76          "org.jdtaus.core.container.mojo.model.container";
77  
78      /** Package names of the spring model classes. */
79      private static final String SPRING_MODEL_PACKAGES =
80          "org.jdtaus.core.container.mojo.model.spring";
81  
82      private static final String JAXB_MODEL_PACKAGES =
83          CONTAINER_MODEL_PACKAGES + ":" + SPRING_MODEL_PACKAGES;
84  
85      /** Container model schema locations. */
86      private static final String[] CONTAINER_SCHEMA_LOCATIONS =
87      {
88          "http://jdtaus.org/core/model/container",
89          "http://xml.jdtaus.org/1.0.x/jdtaus-core/jdtaus-core-schemas/jdtaus-container-1.1.xsd"
90      };
91  
92      /** Spring model schema locations. */
93      private static final String[] SPRING_SCHEMA_LOCATIONS =
94      {
95          "http://www.springframework.org/schema/beans",
96          "http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
97      };
98  
99      /**
100      * Gets a {@code Marshaller} for marshalling the container model.
101      *
102      * @return a {@code Marshaller} for marshalling the container model.
103      *
104      * @throws JAXBException if creating a {@code Marshaller} fails.
105      */
106     public Marshaller getContainerMarshaller() throws JAXBException
107     {
108         final StringBuffer schemaLocation = new StringBuffer();
109         for ( int i = 0; i < CONTAINER_SCHEMA_LOCATIONS.length; i += 2 )
110         {
111             schemaLocation.append( CONTAINER_SCHEMA_LOCATIONS[i] ).
112                 append( ' ' ).
113                 append( CONTAINER_SCHEMA_LOCATIONS[i + 1] ).append( ' ' );
114 
115         }
116 
117         final JAXBContext ctx =
118             JAXBContext.newInstance( JAXB_MODEL_PACKAGES );
119 
120         final Marshaller marshaller = ctx.createMarshaller();
121         marshaller.setProperty( Marshaller.JAXB_ENCODING, "UTF-8" );
122         marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT,
123                                 Boolean.TRUE );
124 
125         marshaller.setProperty( Marshaller.JAXB_SCHEMA_LOCATION,
126                                 schemaLocation.toString().trim() );
127 
128         return marshaller;
129     }
130 
131     /**
132      * Gets a {@code Marshaller} for marshalling the spring container model.
133      *
134      * @return a {@code Marshaller} for marshalling the spring container model.
135      *
136      * @throws JAXBException if creating a {@code Marshaller} fails.
137      */
138     public Marshaller getSpringMarshaller() throws JAXBException
139     {
140         final StringBuffer schemaLocation = new StringBuffer();
141         for ( int i = 0; i < SPRING_SCHEMA_LOCATIONS.length; i += 2 )
142         {
143             schemaLocation.append( SPRING_SCHEMA_LOCATIONS[i] ).append( ' ' ).
144                 append( SPRING_SCHEMA_LOCATIONS[i + 1] ).append( ' ' );
145 
146         }
147 
148         final JAXBContext ctx =
149             JAXBContext.newInstance( JAXB_MODEL_PACKAGES );
150 
151         final Marshaller marshaller = ctx.createMarshaller();
152         marshaller.setProperty( Marshaller.JAXB_ENCODING, "UTF-8" );
153         marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT,
154                                 Boolean.TRUE );
155 
156         marshaller.setProperty( Marshaller.JAXB_SCHEMA_LOCATION,
157                                 schemaLocation.toString().trim() );
158 
159         return marshaller;
160     }
161 
162     /**
163      * Gets an {@code Unmarshaller} for unmarshalling the container model.
164      *
165      * @return a {@code Unmarshaller} for unmarshalling the container model.
166      *
167      * @throws JAXBException if creating an {@code Unmarshaller} fails.
168      */
169     public Unmarshaller getContainerUnmarshaller() throws JAXBException
170     {
171         final JAXBContext ctx =
172             JAXBContext.newInstance( JAXB_MODEL_PACKAGES );
173 
174         return ctx.createUnmarshaller();
175     }
176 
177     /**
178      * Gets an {@code Unmarshaller} for unmarshalling the spring container
179      * model.
180      *
181      * @return a {@code Unmarshaller} for unmarshalling the spring container
182      * model.
183      *
184      * @throws JAXBException if creating an {@code Unmarshaller} fails.
185      */
186     public Unmarshaller getSpringUnmarshaller() throws JAXBException
187     {
188         final JAXBContext ctx =
189             JAXBContext.newInstance( JAXB_MODEL_PACKAGES );
190 
191         return ctx.createUnmarshaller();
192     }
193 
194     /**
195      * Maps a container {@code Modules} instance to the JAXB model.
196      *
197      * @param cModules the container model to map.
198      *
199      * @return {@code model} mapped to the plugin's model.
200      *
201      * @throws NullPointerException if {@code cModules} is {@code null}.
202      * @throws JAXBException if mapping fails.
203      */
204     public ModulesElement getContainerModel(
205         final org.jdtaus.core.container.Modules cModules ) throws JAXBException
206     {
207         if ( cModules == null )
208         {
209             throw new NullPointerException( "cModules" );
210         }
211 
212         final ObjectFactory f = new ObjectFactory();
213         final ModulesElement modules = f.createModulesElement();
214 
215         for ( int i = cModules.size() - 1; i >= 0; i-- )
216         {
217             final Module module = f.createModuleElement();
218             module.setName( cModules.getModule( i ).getName() );
219             module.setVersion( cModules.getModule( i ).getVersion() );
220 
221             module.setMessages(
222                 this.map( cModules.getModule( i ).getMessages() ) );
223 
224             module.setImplementations(
225                 this.map( cModules.getModule( i ).getImplementations(),
226                           module ) );
227 
228             module.setSpecifications(
229                 this.map( cModules.getModule( i ).getSpecifications() ) );
230 
231             module.setProperties(
232                 this.map( cModules.getModule( i ).getProperties() ) );
233 
234             this.map( module, cModules.getModule( i ) );
235             modules.getModule().add( module );
236         }
237 
238         this.map( modules, cModules );
239 
240         return modules.getModule().size() > 0 ? modules : null;
241     }
242 
243     /**
244      * Maps a container {@code Implementation} instance to the plugin's
245      * model with any references resolved.
246      *
247      * @param model The model to use for resolving references.
248      * @param implementation The container model to map.
249      *
250      * @return {@code implementation} mapped to the plugin's model with any
251      * references resolved.
252      *
253      * @throws NullPointerException if {@code implementation} or {@code model}
254      * is {@code null}.
255      * @throws JAXBException if mapping fails.
256      */
257     public ModuleElement getResolvedImplementation(
258         final org.jdtaus.core.container.Model model,
259         final org.jdtaus.core.container.Implementation implementation )
260         throws JAXBException
261     {
262         if ( implementation == null )
263         {
264             throw new NullPointerException( "implementation" );
265         }
266 
267         final ObjectFactory f = new ObjectFactory();
268         final ImplementationElement e = f.createImplementationElement();
269         final ModuleElement m = f.createModuleElement();
270 
271         m.setImplementations( f.createImplementationsElement() );
272         m.setSpecifications( f.createSpecificationsElement() );
273         m.setName( implementation.getIdentifier() );
274         m.setVersion( implementation.getVersion() );
275         this.map( m, implementation );
276 
277         for ( int d = implementation.getDependencies().size() - 1; d >= 0; d-- )
278         {
279             if ( e.getDependencies() == null )
280             {
281                 e.setDependencies( f.createDependenciesElement() );
282             }
283 
284             final org.jdtaus.core.container.Dependency dep =
285                 implementation.getDependencies().getDependency( d );
286 
287             e.getDependencies().getDependency().
288                 add( this.getDependency( dep ) );
289 
290             if ( this.getSpecification(
291                 m.getSpecifications(), dep.getSpecification().
292                 getIdentifier() ) == null )
293             {
294                 m.getSpecifications().getSpecification().add(
295                     this.getSpecification( model.getModules().getSpecification(
296                     dep.getSpecification().getIdentifier() ) ) );
297 
298             }
299         }
300 
301         e.setFinal( implementation.isFinal() );
302         e.setIdentifier( implementation.getIdentifier() );
303         e.setMessages( this.map( implementation.getMessages() ) );
304         e.setName( implementation.getName() );
305         e.setProperties( this.map( implementation.getProperties() ) );
306         e.setSpecifications( f.createSpecificationsElement() );
307 
308         for ( int i = implementation.getImplementedSpecifications().size() - 1;
309               i >= 0; i-- )
310         {
311             final org.jdtaus.core.container.Specification s =
312                 implementation.getImplementedSpecifications().
313                 getSpecification( i );
314 
315             final SpecificationReference ref = f.createSpecificationReference();
316             ref.setIdentifier( s.getIdentifier() );
317             ref.setVersion( s.getVersion() );
318             this.map( ref, s );
319 
320             e.getSpecifications().getReference().add( ref );
321 
322             if ( this.getSpecification( m.getSpecifications(),
323                                         s.getIdentifier() ) == null )
324             {
325                 m.getSpecifications().getSpecification().
326                     add( this.getSpecification( model.getModules().
327                     getSpecification( s.getIdentifier() ) ) );
328 
329             }
330         }
331 
332         e.setVendor( implementation.getVendor() );
333         e.setVersion( implementation.getVersion() );
334 
335         if ( implementation.getParent() != null )
336         {
337             e.setParent( implementation.getParent().getIdentifier() );
338         }
339 
340         this.map( e, implementation );
341         m.getImplementations().getImplementation().add( e );
342 
343         return m;
344     }
345 
346     /**
347      * Maps a container {@code Specification} instance to the plugin's
348      * model.
349      *
350      * @param specification The container model to map.
351      *
352      * @return {@code specificaction} mapped to the plugin's model.
353      *
354      * @throws NullPointerException if {@code specificaction} is {@code null}.
355      * @throws JAXBException if mapping fails.
356      */
357     public SpecificationElement getSpecification(
358         final org.jdtaus.core.container.Specification specification )
359         throws JAXBException
360     {
361         if ( specification == null )
362         {
363             throw new NullPointerException( "specification" );
364         }
365 
366         final ObjectFactory f = new ObjectFactory();
367         final SpecificationElement e = f.createSpecificationElement();
368 
369         e.setIdentifier( specification.getIdentifier() );
370         e.setMultiplicity( this.getMultiplicity( specification ) );
371         e.setProperties( this.map( specification.getProperties() ) );
372         e.setScope( this.getScope( specification ) );
373         e.setStateless( specification.isStateless() );
374         e.setVendor( specification.getVendor() );
375         e.setVersion( specification.getVersion() );
376 
377         this.map( e, specification );
378 
379         return e;
380     }
381 
382     /**
383      * Maps a container {@code Dependency} instance to the plugin's
384      * model.
385      *
386      * @param dependency The container model to map.
387      *
388      * @return {@code dependency} mapped to the plugin's model.
389      *
390      * @throws NullPointerException if {@code dependency} is {@code null}.
391      * @throws JAXBException if mapping fails.
392      */
393     public DependencyElement getDependency(
394         final org.jdtaus.core.container.Dependency dependency )
395         throws JAXBException
396     {
397         if ( dependency == null )
398         {
399             throw new NullPointerException( "dependency" );
400         }
401 
402         final ObjectFactory f = new ObjectFactory();
403         final DependencyElement dep = f.createDependencyElement();
404 
405         dep.setBound( dependency.isBound() );
406         dep.setName( dependency.getName() );
407         dep.setIdentifier( dependency.getSpecification().getIdentifier() );
408 
409         if ( dependency.getSpecification().getVersion() != null )
410         {
411             dep.setVersion( dependency.getSpecification().getVersion() );
412         }
413 
414         if ( dependency.getImplementation() != null )
415         {
416             dep.setImplementationName( dependency.getImplementation().
417                 getName() );
418 
419         }
420 
421         final int propertyCount = dependency.getDeclaredProperties().size();
422 
423         if ( propertyCount > 0 )
424         {
425             final Properties properties = f.createProperties();
426             dep.setProperties( properties );
427 
428             for ( int p = propertyCount - 1; p >= 0; p-- )
429             {
430                 final org.jdtaus.core.container.Property cProperty =
431                     dependency.getDeclaredProperties().getProperty( p );
432 
433                 final Property property = f.createProperty();
434 
435                 property.setName( cProperty.getName() );
436                 property.setType( PropertyType.fromValue(
437                     cProperty.getType().getName() ) );
438 
439                 property.setValue( cProperty.getValue() != null
440                                    ? cProperty.getValue().toString()
441                                    : null );
442 
443                 this.map( property, cProperty );
444                 properties.getProperty().add( property );
445             }
446 
447             this.map( properties, dependency.getDeclaredProperties() );
448         }
449 
450         this.map( dep, dependency );
451         return dep;
452     }
453 
454     /**
455      * Gets the scope of a specification.
456      *
457      * @param specification The specification to get the scope of.
458      *
459      * @return The scope of {@code specification}.
460      *
461      * @throws NullPointerException if {@code specification} is {@code null}.
462      */
463     public Scope getScope(
464         final org.jdtaus.core.container.Specification specification )
465     {
466         if ( specification == null )
467         {
468             throw new NullPointerException( "specification" );
469         }
470 
471         final Scope scope;
472         switch ( specification.getScope() )
473         {
474             case org.jdtaus.core.container.Specification.SCOPE_CONTEXT:
475                 scope = Scope.CONTEXT;
476                 break;
477 
478             case org.jdtaus.core.container.Specification.SCOPE_MULTITON:
479                 scope = Scope.MULTITON;
480                 break;
481 
482             case org.jdtaus.core.container.Specification.SCOPE_SINGLETON:
483                 scope = Scope.SINGLETON;
484                 break;
485 
486             default:
487                 throw new AssertionError( Integer.toString(
488                     specification.getScope() ) );
489 
490         }
491 
492         return scope;
493     }
494 
495     /**
496      * Gets the multiplicity of a specification.
497      *
498      * @param specification The specification to get the multiplicity of.
499      *
500      * @return The multiplicity of {@code specification}.
501      *
502      * @throws NullPointerException if {@code specification} is {@code null}.
503      */
504     public Multiplicity getMultiplicity(
505         final org.jdtaus.core.container.Specification specification )
506     {
507         if ( specification == null )
508         {
509             throw new NullPointerException( "specification" );
510         }
511 
512         final Multiplicity multiplicity;
513         switch ( specification.getMultiplicity() )
514         {
515             case org.jdtaus.core.container.Specification.MULTIPLICITY_MANY:
516                 multiplicity = Multiplicity.MANY;
517                 break;
518 
519             case org.jdtaus.core.container.Specification.MULTIPLICITY_ONE:
520                 multiplicity = Multiplicity.ONE;
521                 break;
522 
523             default:
524                 throw new AssertionError( Integer.toString(
525                     specification.getMultiplicity() ) );
526 
527         }
528 
529         return multiplicity;
530     }
531 
532     /**
533      * Maps a container {@code Modules} instance to the spring container model.
534      *
535      * @param factoryBeanClassName the name of the {@code FactoryBean}
536      * implementation class.
537      * @param cModules the container model to map.
538      *
539      * @return {@code model} mapped to the spring container model.
540      *
541      * @throws JAXBException if mapping fails.
542      */
543     public BeansElement getSpringModel(
544         final String factoryBeanClassName,
545         final org.jdtaus.core.container.Modules cModules )
546         throws JAXBException
547     {
548         final org.jdtaus.core.container.mojo.model.spring.ObjectFactory f =
549             new org.jdtaus.core.container.mojo.model.spring.ObjectFactory();
550 
551         final BeansElement beans = f.createBeansElement();
552         for ( int s = cModules.getSpecifications().size() - 1; s >= 0; s-- )
553         {
554             final org.jdtaus.core.container.Specification spec =
555                 cModules.getSpecifications().getSpecification( s );
556 
557             for ( int i = spec.getImplementations().size() - 1; i >= 0; i-- )
558             {
559                 final org.jdtaus.core.container.Implementation impl =
560                     spec.getImplementations().getImplementation( i );
561 
562                 final String id = spec.getIdentifier() + '.' +
563                                   impl.getName().hashCode();
564 
565                 final BeanElement bean = f.createBeanElement();
566                 bean.setClazz( factoryBeanClassName );
567                 bean.setId( id );
568                 bean.setScope( this.getSpringScope( spec ) );
569 
570                 org.jdtaus.core.container.mojo.model.spring.PropertyElement property =
571                     f.createPropertyElement();
572 
573                 property.setName( "specificationIdentifier" );
574                 property.setShortcutValue( spec.getIdentifier() );
575                 bean.getMetaOrConstructorArgOrProperty().add( property );
576 
577                 property = f.createPropertyElement();
578                 property.setName( "implementationName" );
579                 property.setShortcutValue( impl.getName() );
580                 bean.getMetaOrConstructorArgOrProperty().add( property );
581 
582                 beans.getImportOrAliasOrBean().add( bean );
583             }
584         }
585 
586         return beans;
587     }
588 
589     /**
590      * Gets the spring scope identifier for a given specification.
591      *
592      * @param specification The specificatoin to get the corresponding spring
593      * scope identifier for.
594      *
595      * @return The spring scope identifier for {@code specification}.
596      */
597     public String getSpringScope(
598         final org.jdtaus.core.container.Specification specification )
599     {
600         if ( specification == null )
601         {
602             throw new NullPointerException( "specification" );
603         }
604 
605         final String springScope;
606 
607         if ( specification.getScope() ==
608              org.jdtaus.core.container.Specification.SCOPE_CONTEXT )
609         {
610             springScope = "jdtaus-context";
611         }
612         else if ( specification.getScope() ==
613                   org.jdtaus.core.container.Specification.SCOPE_MULTITON )
614         {
615             springScope = "prototype";
616         }
617         else if ( specification.getScope() ==
618                   org.jdtaus.core.container.Specification.SCOPE_SINGLETON )
619         {
620             springScope = "singleton";
621         }
622         else
623         {
624             throw new AssertionError(
625                 Integer.toString( specification.getScope() ) );
626 
627         }
628 
629         return springScope;
630     }
631 
632     /**
633      * Gets the java field name for a property.
634      *
635      * @param property the property to get the java field name for.
636      *
637      * @return The java field name for {@code property}.
638      *
639      * @throws NullPointerException if {@code property} is {@code null}.
640      */
641     public String getJavaFieldName(
642         final org.jdtaus.core.container.Property property )
643     {
644         if ( property == null )
645         {
646             throw new NullPointerException( "property" );
647         }
648 
649         final char[] c = property.getName().toCharArray();
650         c[0] = Character.toUpperCase( c[0] );
651         return "p" + String.valueOf( c );
652     }
653 
654     /**
655      * Gets the java field name for a dependency.
656      *
657      * @param dependency the dependency to get the java field name for.
658      *
659      * @return The java field name for {@code dependency}.
660      *
661      * @throws NullPointerException if {@code dependency} is {@code null}.
662      */
663     public String getJavaFieldName(
664         final org.jdtaus.core.container.Dependency dependency )
665     {
666         if ( dependency == null )
667         {
668             throw new NullPointerException( "dependency" );
669         }
670 
671         final char[] c = dependency.getName().toCharArray();
672         c[0] = Character.toUpperCase( c[0] );
673         return "d" + String.valueOf( c );
674     }
675 
676     /**
677      * Gets the java getter method name for a property.
678      *
679      * @param property the property to return the getter method name for.
680      *
681      * @return the getter method name for {@code property}.
682      *
683      * @throws NullPointerException if {@code property} is {@code null}.
684      */
685     public String getJavaGetterMethodName(
686         final org.jdtaus.core.container.Property property )
687     {
688         if ( property == null )
689         {
690             throw new NullPointerException( "property" );
691         }
692 
693         final boolean isFlag =
694             property.getType() == Boolean.class ||
695             property.getType() == boolean.class;
696 
697         final char[] name = property.getName().toCharArray();
698         name[0] = Character.toUpperCase( name[0] );
699         return ( isFlag ? "is" : "get" ) + String.valueOf( name );
700     }
701 
702     /**
703      * Gets the java getter method name for a dependency.
704      *
705      * @param dependency the dependency to return the getter method name for.
706      *
707      * @return the getter method name for {@code dependency}.
708      *
709      * @throws NullPointerException if {@code dependency} is {@code null}.
710      */
711     public String getJavaGetterMethodName(
712         final org.jdtaus.core.container.Dependency dependency )
713     {
714         if ( dependency == null )
715         {
716             throw new NullPointerException( "dependency" );
717         }
718 
719         final char[] name = dependency.getName().toCharArray();
720         name[0] = Character.toUpperCase( name[0] );
721         return "get" + String.valueOf( name );
722     }
723 
724     /**
725      * Gets the java getter method name for a message.
726      *
727      * @param message the message to return the getter method name for.
728      *
729      * @return the getter method name for {@code message}.
730      *
731      * @throws NullPointerException if {@code message} is {@code null}.
732      */
733     public String getJavaGetterMethodName(
734         final org.jdtaus.core.container.Message message )
735     {
736         if ( message == null )
737         {
738             throw new NullPointerException( "message" );
739         }
740 
741         final char[] name = message.getName().toCharArray();
742         name[0] = Character.toUpperCase( name[0] );
743         return "get" + String.valueOf( name ) + "Message";
744     }
745 
746     /**
747      * Gets the Java type of a given property.
748      *
749      * @param property The property to get the Java type of.
750      *
751      * @return The Java type of {@code property}.
752      */
753     public Class getJavaType( final PropertyElement property )
754     {
755         final Class propertyType;
756         final String typeName = property.getType().getValue();
757 
758         if ( typeName.equals( Boolean.TYPE.getName() ) )
759         {
760             propertyType = Boolean.TYPE;
761         }
762         else if ( typeName.equals( Byte.TYPE.getName() ) )
763         {
764             propertyType = Byte.TYPE;
765         }
766         else if ( typeName.equals( Character.TYPE.getName() ) )
767         {
768             propertyType = Character.TYPE;
769         }
770         else if ( typeName.equals( Double.TYPE.getName() ) )
771         {
772             propertyType = Double.TYPE;
773         }
774         else if ( typeName.equals( Float.TYPE.getName() ) )
775         {
776             propertyType = Float.TYPE;
777         }
778         else if ( typeName.equals( Integer.TYPE.getName() ) )
779         {
780             propertyType = Integer.TYPE;
781         }
782         else if ( typeName.equals( Long.TYPE.getName() ) )
783         {
784             propertyType = Long.TYPE;
785         }
786         else if ( typeName.equals( Short.TYPE.getName() ) )
787         {
788             propertyType = Short.TYPE;
789         }
790         else if ( typeName.equals( Boolean.class.getName() ) )
791         {
792             propertyType = Boolean.class;
793         }
794         else if ( typeName.equals( Byte.class.getName() ) )
795         {
796             propertyType = Byte.class;
797         }
798         else if ( typeName.equals( Character.class.getName() ) )
799         {
800             propertyType = Character.class;
801         }
802         else if ( typeName.equals( Double.class.getName() ) )
803         {
804             propertyType = Double.class;
805         }
806         else if ( typeName.equals( Float.class.getName() ) )
807         {
808             propertyType = Float.class;
809         }
810         else if ( typeName.equals( Integer.class.getName() ) )
811         {
812             propertyType = Integer.class;
813         }
814         else if ( typeName.equals( Long.class.getName() ) )
815         {
816             propertyType = Long.class;
817         }
818         else if ( typeName.equals( Short.class.getName() ) )
819         {
820             propertyType = Short.class;
821         }
822         else if ( typeName.equals( String.class.getName() ) )
823         {
824             propertyType = String.class;
825         }
826         else
827         {
828             throw new IllegalArgumentException( property.getType().getValue() );
829         }
830 
831         return propertyType;
832     }
833 
834     /**
835      * Maps a container {@code Specifications} instance to the plugin's model.
836      *
837      * @param cSpecifications the container model to map.
838      *
839      * @return {@code cSpecifications} mapped to the plugin's model.
840      *
841      * @throws JAXBException if mapping fails.
842      */
843     private SpecificationsElement map(
844         final org.jdtaus.core.container.Specifications cSpecifications )
845         throws JAXBException
846     {
847         final ObjectFactory f = new ObjectFactory();
848         final SpecificationsElement specs = f.createSpecificationsElement();
849 
850         for ( int i = cSpecifications.size() - 1; i >= 0; i-- )
851         {
852             specs.getSpecification().add( this.getSpecification(
853                 cSpecifications.getSpecification( i ) ) );
854 
855         }
856 
857         this.map( specs, cSpecifications );
858 
859         return specs.getSpecification().size() > 0 ? specs : null;
860     }
861 
862     /**
863      * Maps a container {@code Implementations} instance to the plugin's model.
864      *
865      * @param cImplementations the container model to map.
866      * @param module the module containing {@code cImplementations}.
867      *
868      * @return {@code cImplementations} mapped to the plugin's model.
869      *
870      * @throws JAXBException if mapping fails.
871      */
872     private ImplementationsElement map(
873         final org.jdtaus.core.container.Implementations cImplementations,
874         final Module module )
875         throws JAXBException
876     {
877         final ObjectFactory f = new ObjectFactory();
878         final ImplementationsElement impls = f.createImplementationsElement();
879 
880         for ( int i = cImplementations.size() - 1; i >= 0; i-- )
881         {
882             final ImplementationElement impl = f.createImplementationElement();
883 
884             impl.setDependencies(
885                 map( cImplementations.getImplementation( i ).
886                 getDeclaredDependencies() ) );
887 
888             impl.setFinal( cImplementations.getImplementation( i ).isFinal() );
889             impl.setIdentifier( cImplementations.getImplementation( i ).
890                 getIdentifier() );
891 
892             final SpecificationsElement is =
893                 f.createSpecificationsElement();
894 
895             for ( int s = cImplementations.getImplementation( i ).
896                 getDeclaredImplementedSpecifications().size() - 1;
897                   s >= 0; s-- )
898             {
899                 final SpecificationReference im =
900                     f.createSpecificationReference();
901 
902                 im.setIdentifier( cImplementations.getImplementation( i ).
903                     getImplementedSpecifications().
904                     getSpecification( s ).getIdentifier() );
905 
906                 if ( cImplementations.getImplementation( i ).
907                     getImplementedSpecifications().
908                     getSpecification( s ).getVersion() != null )
909                 {
910                     im.setVersion( cImplementations.getImplementation( i ).
911                         getImplementedSpecifications().
912                         getSpecification( s ).getVersion() );
913 
914                 }
915 
916                 is.getReference().add( im );
917             }
918 
919             if ( is.getReference().size() > 0 )
920             {
921                 impl.setSpecifications( is );
922             }
923 
924             impl.setName( cImplementations.getImplementation( i ).getName() );
925 
926             if ( cImplementations.getImplementation( i ).getParent() != null )
927             {
928                 impl.setParent( cImplementations.getImplementation( i ).
929                     getParent().getIdentifier() );
930 
931             }
932 
933             impl.setProperties(
934                 map( cImplementations.getImplementation( i ).
935                 getDeclaredProperties() ) );
936 
937             impl.setVendor( cImplementations.getImplementation( i ).getVendor() );
938             impl.setVersion(
939                 cImplementations.getImplementation( i ).getVersion() );
940 
941             final MessagesElement messages = f.createMessagesElement();
942             for ( int m = cImplementations.getImplementation( i ).
943                 getMessages().size() - 1; m >= 0; m-- )
944             {
945                 final org.jdtaus.core.container.Message cMessage =
946                     cImplementations.getImplementation( i ).getMessages().
947                     getMessage( m );
948 
949                 if ( this.getMessage( module, cMessage.getName() ) != null )
950                 {
951                     final MessageReference reference =
952                         f.createMessageReference();
953 
954                     reference.setName( cMessage.getName() );
955                     this.map( reference, cMessage );
956 
957                     messages.getReference().add( reference );
958                 }
959                 else
960                 {
961                     final MessageElement message = f.createMessageElement();
962                     message.setName( cMessage.getName() );
963                     message.setArguments( this.map( cMessage.getArguments() ) );
964                     message.setTemplate( this.map( cMessage.getTemplate() ) );
965 
966                     this.map( message, cMessage );
967                     messages.getMessage().add( message );
968                 }
969             }
970 
971             if ( !messages.getMessage().isEmpty() ||
972                  !messages.getReference().isEmpty() )
973             {
974                 impl.setMessages( messages );
975             }
976 
977             this.map( impl, cImplementations.getImplementation( i ) );
978 
979             impls.getImplementation().add( impl );
980         }
981 
982         this.map( impls, cImplementations );
983 
984         return impls.getImplementation().size() > 0 ? impls : null;
985     }
986 
987     /**
988      * Maps a container {@code Dependencies} instance to the plugin's model.
989      *
990      * @param cDependencies the container model to map.
991      *
992      * @return {@code cDependencies} mapped to the plugin's model.
993      *
994      * @throws JAXBException if mapping fails.
995      */
996     private DependenciesElement map(
997         final org.jdtaus.core.container.Dependencies cDependencies )
998         throws JAXBException
999     {
1000         final ObjectFactory f = new ObjectFactory();
1001         final DependenciesElement deps = f.createDependenciesElement();
1002 
1003         for ( int i = cDependencies.size() - 1; i >= 0; i-- )
1004         {
1005             deps.getDependency().add( this.getDependency( cDependencies.
1006                 getDependency( i ) ) );
1007 
1008         }
1009 
1010         this.map( deps, cDependencies );
1011 
1012         return deps.getDependency().size() > 0 ? deps : null;
1013     }
1014 
1015     /**
1016      * Maps a container {@code Properties} instance to the plugin's model.
1017      *
1018      * @param cProperties the container model to map.
1019      *
1020      * @return {@code cProperties} mapped to the plugin's model.
1021      *
1022      * @throws JAXBException if mapping fails.
1023      */
1024     private PropertiesElement map(
1025         final org.jdtaus.core.container.Properties cProperties )
1026         throws JAXBException
1027     {
1028         final ObjectFactory f = new ObjectFactory();
1029         final PropertiesElement properties = f.createPropertiesElement();
1030 
1031         for ( int i = cProperties.size() - 1; i >= 0; i-- )
1032         {
1033             final PropertyElement p = f.createPropertyElement();
1034 
1035             p.setName( cProperties.getProperty( i ).getName() );
1036             p.setType( PropertyType.fromValue( cProperties.getProperty( i ).
1037                 getType().getName() ) );
1038 
1039             if ( cProperties.getProperty( i ).getValue() != null )
1040             {
1041                 p.setValue( cProperties.getProperty( i ).getValue().
1042                     toString() );
1043 
1044             }
1045 
1046             this.map( p, cProperties.getProperty( i ) );
1047             properties.getProperty().add( p );
1048         }
1049 
1050         this.map( properties, cProperties );
1051         return properties.getProperty().size() > 0 ? properties : null;
1052     }
1053 
1054     /**
1055      * Maps a container {@code Messages} instance to the plugin's model.
1056      *
1057      * @param cMessages the container model to map.
1058      *
1059      * @return {@code cMessages} mapped to the plugin's model.
1060      *
1061      * @throws JAXBException if mapping fails.
1062      */
1063     private MessagesElement map(
1064         final org.jdtaus.core.container.Messages cMessages )
1065         throws JAXBException
1066     {
1067         final ObjectFactory f = new ObjectFactory();
1068         final MessagesElement messages = f.createMessagesElement();
1069 
1070         for ( int i = cMessages.size() - 1; i >= 0; i-- )
1071         {
1072             final MessageElement m = f.createMessageElement();
1073             m.setName( cMessages.getMessage( i ).getName() );
1074             m.setTemplate( this.map( cMessages.getMessage( i ).
1075                 getTemplate() ) );
1076 
1077             m.setArguments( this.map( cMessages.getMessage( i ).
1078                 getArguments() ) );
1079 
1080             this.map( m, cMessages.getMessage( i ) );
1081             messages.getMessage().add( m );
1082         }
1083 
1084         this.map( messages, cMessages );
1085         return messages.getMessage().size() > 0 ? messages : null;
1086     }
1087 
1088     /**
1089      * Maps a container {@code Arguments} instance to the plugin's model.
1090      *
1091      * @param cArguments the container model to map.
1092      *
1093      * @return {@code cArguments} mapped to the plugin's model.
1094      *
1095      * @throws JAXBException if mapping fails.
1096      */
1097     private ArgumentsElement map(
1098         final org.jdtaus.core.container.Arguments cArguments )
1099         throws JAXBException
1100     {
1101         final ObjectFactory f = new ObjectFactory();
1102         final ArgumentsElement arguments = f.createArgumentsElement();
1103 
1104         for ( int i = 0; i < cArguments.size(); i++ )
1105         {
1106             final ArgumentElement a = f.createArgumentElement();
1107             a.setIndex( BigInteger.valueOf( cArguments.getArgument( i ).
1108                 getIndex() ) );
1109 
1110             a.setName( cArguments.getArgument( i ).getName() );
1111 
1112             final ArgumentType type;
1113             if ( org.jdtaus.core.container.Argument.TYPE_DATE ==
1114                  cArguments.getArgument( i ).getType() )
1115             {
1116                 type = ArgumentType.DATE;
1117             }
1118             else if ( org.jdtaus.core.container.Argument.TYPE_NUMBER ==
1119                       cArguments.getArgument( i ).getType() )
1120             {
1121                 type = ArgumentType.NUMBER;
1122             }
1123             else if ( org.jdtaus.core.container.Argument.TYPE_TEXT ==
1124                       cArguments.getArgument( i ).getType() )
1125             {
1126                 type = ArgumentType.TEXT;
1127             }
1128             else if ( org.jdtaus.core.container.Argument.TYPE_TIME ==
1129                       cArguments.getArgument( i ).getType() )
1130             {
1131                 type = ArgumentType.TIME;
1132             }
1133             else
1134             {
1135                 throw new AssertionError(
1136                     Integer.toString(
1137                     cArguments.getArgument( i ).getType() ) );
1138 
1139             }
1140             a.setType( type );
1141 
1142             this.map( a, cArguments.getArgument( i ) );
1143             arguments.getArgument().add( a );
1144         }
1145 
1146         this.map( arguments, cArguments );
1147         return arguments.getArgument().size() > 0 ? arguments : null;
1148     }
1149 
1150     /**
1151      * Maps a container {@code Text} instance to the plugin's model.
1152      *
1153      * @param cText the container model to map.
1154      *
1155      * @return {@code cText} mapped to the plugin's model.
1156      *
1157      * @throws JAXBException if mapping fails.
1158      */
1159     private Texts map( final org.jdtaus.core.container.Text cText )
1160         throws JAXBException
1161     {
1162         final ObjectFactory f = new ObjectFactory();
1163         final Texts texts = f.createTexts();
1164 
1165         final Locale[] locales = cText.getLocales();
1166         if ( locales.length > 0 )
1167         {
1168             for ( int i = locales.length - 1; i >= 0; i-- )
1169             {
1170                 final Text text = f.createText();
1171                 final String value = cText.getValue( locales[i] );
1172                 text.setLanguage( locales[i].getLanguage().toLowerCase() );
1173                 text.setValue( value );
1174 
1175                 texts.getText().add( text );
1176 
1177                 if ( value.equals( cText.getValue() ) )
1178                 {
1179                     texts.setDefaultLanguage( locales[i].getLanguage().
1180                         toLowerCase() );
1181 
1182                 }
1183             }
1184         }
1185 
1186         return texts.getText().size() > 0 ? texts : null;
1187     }
1188 
1189     /**
1190      * Maps a container {@code ModelObject} instance to the plugin's model.
1191      *
1192      * @param object the object to map {@code cObject} to.
1193      * @param cObject the container model to map.
1194      *
1195      * @throws JAXBException if mapping fails.
1196      */
1197     private void map( final ModelObject object,
1198                       final org.jdtaus.core.container.ModelObject cObject )
1199         throws JAXBException
1200     {
1201         object.setModelVersion( cObject.getModelVersion() );
1202         object.setDocumentation( this.map( cObject.getDocumentation() ) );
1203     }
1204 
1205     /**
1206      * Gets a message form a module.
1207      *
1208      * @param module The module to get a message from.
1209      * @param name The name of the message to return.
1210      *
1211      * @return the message with name {@code name} from {@code module} or
1212      * {@code null} if {@code module} does not contain a message with name
1213      * {@code name}.
1214      */
1215     private Message getMessage( final Module module, final String name )
1216     {
1217         Message message = null;
1218 
1219         if ( module.getMessages() != null )
1220         {
1221             for ( final Iterator it = module.getMessages().getMessage().
1222                 iterator(); it.hasNext(); )
1223             {
1224                 final Message current = (Message) it.next();
1225                 if ( current.getName().equals( name ) )
1226                 {
1227                     message = current;
1228                     break;
1229                 }
1230             }
1231         }
1232 
1233         return message;
1234     }
1235 
1236     /**
1237      * Gets a specification form a set of specifications.
1238      *
1239      * @param specs The set of specifications to get a specification from.
1240      * @param identifier The identifier of the specification to return.
1241      *
1242      * @return The specification identified by {@code identifier} from
1243      * {@code specs} or {@code null} if {@code specs} does not contain a
1244      * specification identified by {@code identifier}.
1245      */
1246     private SpecificationElement getSpecification(
1247         final Specifications specs, final String identifier )
1248     {
1249         SpecificationElement s = null;
1250         for ( final Iterator it = specs.getSpecification().iterator();
1251               it.hasNext(); )
1252         {
1253             final SpecificationElement e = (SpecificationElement) it.next();
1254             if ( identifier.equals( e.getIdentifier() ) )
1255             {
1256                 s = e;
1257                 break;
1258             }
1259         }
1260 
1261         return s;
1262     }
1263 
1264 }