View Javadoc

1   /*
2    *   Copyright (C) Christian Schulte, 2005-206
3    *   All rights reserved.
4    *
5    *   Redistribution and use in source and binary forms, with or without
6    *   modification, are permitted provided that the following conditions
7    *   are met:
8    *
9    *     o Redistributions of source code must retain the above copyright
10   *       notice, this list of conditions and the following disclaimer.
11   *
12   *     o Redistributions in binary form must reproduce the above copyright
13   *       notice, this list of conditions and the following disclaimer in
14   *       the documentation and/or other materials provided with the
15   *       distribution.
16   *
17   *   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18   *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19   *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20   *   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
21   *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22   *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23   *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24   *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25   *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26   *   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27   *
28   *   $JOMC: JomcToolTask.java 4613 2012-09-22 10:07:08Z schulte $
29   *
30   */
31  package org.jomc.ant;
32  
33  import java.io.IOException;
34  import java.net.URL;
35  import java.util.ArrayList;
36  import java.util.Iterator;
37  import java.util.LinkedList;
38  import java.util.List;
39  import java.util.Locale;
40  import java.util.Map;
41  import java.util.logging.Level;
42  import org.apache.commons.lang.StringEscapeUtils;
43  import org.apache.commons.lang.StringUtils;
44  import org.apache.tools.ant.BuildException;
45  import org.apache.tools.ant.Project;
46  import org.jomc.ant.types.KeyValueType;
47  import org.jomc.ant.types.LocaleType;
48  import org.jomc.ant.types.PropertiesResourceType;
49  import org.jomc.model.Implementation;
50  import org.jomc.model.Module;
51  import org.jomc.model.Modules;
52  import org.jomc.model.Specification;
53  import org.jomc.model.modlet.ModelHelper;
54  import org.jomc.modlet.Model;
55  import org.jomc.tools.JomcTool;
56  
57  /**
58   * Base class for executing tool based tasks.
59   *
60   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
61   * @version $JOMC: JomcToolTask.java 4613 2012-09-22 10:07:08Z schulte $
62   */
63  public class JomcToolTask extends JomcModelTask
64  {
65  
66      /** The default encoding to use for reading templates. */
67      private String defaultTemplateEncoding;
68  
69      /** The default template profile to use when accessing templates. */
70      private String defaultTemplateProfile;
71  
72      /** The encoding to use for reading files. */
73      private String inputEncoding;
74  
75      /** The encoding to use for writing files. */
76      private String outputEncoding;
77  
78      /** The encoding to use for reading templates. */
79      private String templateEncoding;
80  
81      /** Additional location to search for templates. */
82      private String templateLocation;
83  
84      /** The template profile to use when accessing templates. */
85      private String templateProfile;
86  
87      /** The indentation string ('\t' for tab). */
88      private String indentation;
89  
90      /** The line separator ('\r\n' for DOS, '\r' for Mac, '\n' for Unix). */
91      private String lineSeparator;
92  
93      /** The locale. */
94      private LocaleType locale;
95  
96      /** The identifier of a specification to process. */
97      private String specification;
98  
99      /** The identifier of an implementation to process. */
100     private String implementation;
101 
102     /** The name of a module to process. */
103     private String module;
104 
105     /** The Velocity runtime properties. */
106     private List<KeyValueType> velocityProperties;
107 
108     /** The Velocity runtime property resources. */
109     private List<PropertiesResourceType> velocityPropertyResources;
110 
111     /** The template parameters. */
112     private List<KeyValueType> templateParameters;
113 
114     /** The template parameter resources. */
115     private List<PropertiesResourceType> templateParameterResources;
116 
117     /** Creates a new {@code JomcToolTask} instance. */
118     public JomcToolTask()
119     {
120         super();
121     }
122 
123     /**
124      * Gets the encoding to use for reading files.
125      *
126      * @return The encoding to use for reading files or {@code null}.
127      *
128      * @see #setInputEncoding(java.lang.String)
129      */
130     public final String getInputEncoding()
131     {
132         return this.inputEncoding;
133     }
134 
135     /**
136      * Sets the encoding to use for reading files.
137      *
138      * @param value The new encoding to use for reading files or {@code null}.
139      *
140      * @see #getInputEncoding()
141      */
142     public final void setInputEncoding( final String value )
143     {
144         this.inputEncoding = value;
145     }
146 
147     /**
148      * Gets the encoding to use for writing files.
149      *
150      * @return The encoding to use for writing files or {@code null}.
151      *
152      * @see #setOutputEncoding(java.lang.String)
153      */
154     public final String getOutputEncoding()
155     {
156         return this.outputEncoding;
157     }
158 
159     /**
160      * Sets the encoding to use for writing files.
161      *
162      * @param value The new encoding to use for writing files or {@code null}.
163      *
164      * @see #getOutputEncoding()
165      */
166     public final void setOutputEncoding( final String value )
167     {
168         this.outputEncoding = value;
169     }
170 
171     /**
172      * Gets the encoding to use for reading templates.
173      *
174      * @return The encoding to use for reading templates or {@code null}.
175      *
176      * @see #setTemplateEncoding(java.lang.String)
177      *
178      * @deprecated As of JOMC 1.3, replaced by method {@link #getDefaultTemplateEncoding()}. This method will be removed
179      * in JOMC 2.0.
180      */
181     @Deprecated
182     public final String getTemplateEncoding()
183     {
184         return this.templateEncoding;
185     }
186 
187     /**
188      * Sets the encoding to use for reading templates.
189      *
190      * @param value The new encoding to use for reading templates or {@code null}.
191      *
192      * @see #getTemplateEncoding()
193      *
194      * @deprecated As of JOMC 1.3, replaced by method {@link #setDefaultTemplateEncoding(java.lang.String)}. This method
195      * will be removed in JOMC 2.0.
196      */
197     @Deprecated
198     public final void setTemplateEncoding( final String value )
199     {
200         this.templateEncoding = value;
201     }
202 
203     /**
204      * Gets the encoding to use for reading templates.
205      *
206      * @return The encoding to use for reading templates or {@code null}.
207      *
208      * @see #setDefaultTemplateEncoding(java.lang.String)
209      *
210      * @since 1.3
211      */
212     public final String getDefaultTemplateEncoding()
213     {
214         return this.defaultTemplateEncoding;
215     }
216 
217     /**
218      * Sets the encoding to use for reading templates.
219      *
220      * @param value The new encoding to use for reading templates or {@code null}.
221      *
222      * @see #getDefaultTemplateEncoding()
223      *
224      * @since 1.3
225      */
226     public final void setDefaultTemplateEncoding( final String value )
227     {
228         this.defaultTemplateEncoding = value;
229     }
230 
231     /**
232      * Gets the location to search for templates in addition to searching the class path of the task.
233      *
234      * @return The location to search for templates in addition to searching the class path of the task or {@code null}.
235      *
236      * @see #setTemplateLocation(java.lang.String)
237      */
238     public final String getTemplateLocation()
239     {
240         return this.templateLocation;
241     }
242 
243     /**
244      * Sets the location to search for templates in addition to searching the class path of the task.
245      *
246      * @param value The new location to search for templates in addition to searching the class path of the task or
247      * {@code null}.
248      *
249      * @see #getTemplateLocation()
250      */
251     public final void setTemplateLocation( final String value )
252     {
253         this.templateLocation = value;
254     }
255 
256     /**
257      * Gets the default template profile to use when accessing templates.
258      *
259      * @return The default template profile to use when accessing templates or {@code null}.
260      *
261      * @see #setDefaultTemplateProfile(java.lang.String)
262      */
263     public final String getDefaultTemplateProfile()
264     {
265         return this.defaultTemplateProfile;
266     }
267 
268     /**
269      * Sets the default template profile to use when accessing templates.
270      *
271      * @param value The new default template profile to use when accessing templates or {@code null}.
272      *
273      * @see #getDefaultTemplateProfile()
274      */
275     public final void setDefaultTemplateProfile( final String value )
276     {
277         this.defaultTemplateProfile = value;
278     }
279 
280     /**
281      * Gets the template profile to use when accessing templates.
282      *
283      * @return The template profile to use when accessing templates or {@code null}.
284      *
285      * @see #setTemplateProfile(java.lang.String)
286      */
287     public final String getTemplateProfile()
288     {
289         return this.templateProfile;
290     }
291 
292     /**
293      * Sets the template profile to use when accessing templates.
294      *
295      * @param value The new template profile to use when accessing templates or {@code null}.
296      *
297      * @see #getTemplateProfile()
298      */
299     public final void setTemplateProfile( final String value )
300     {
301         this.templateProfile = value;
302     }
303 
304     /**
305      * Gets the indentation string ('\t' for tab).
306      *
307      * @return The indentation string ('\t' for tab) or {@code null}.
308      *
309      * @see #setIndentation(java.lang.String)
310      */
311     public final String getIndentation()
312     {
313         return this.indentation;
314     }
315 
316     /**
317      * Sets the indentation string ('\t' for tab).
318      *
319      * @param value The new indentation string ('\t' for tab) or {@code null}.
320      *
321      * @see #getIndentation()
322      */
323     public final void setIndentation( final String value )
324     {
325         this.indentation = value;
326     }
327 
328     /**
329      * Gets the line separator ('\r\n' for DOS, '\r' for Mac, '\n' for Unix).
330      *
331      * @return The line separator ('\r\n' for DOS, '\r' for Mac, '\n' for Unix) or {@code null}.
332      *
333      * @see #setLineSeparator(java.lang.String)
334      */
335     public final String getLineSeparator()
336     {
337         return this.lineSeparator;
338     }
339 
340     /**
341      * Sets the line separator ('\r\n' for DOS, '\r' for Mac, '\n' for Unix).
342      *
343      * @param value The new line separator ('\r\n' for DOS, '\r' for Mac, '\n' for Unix) or {@code null}.
344      *
345      * @see #getLineSeparator()
346      */
347     public final void setLineSeparator( final String value )
348     {
349         this.lineSeparator = value;
350     }
351 
352     /**
353      * Gets the locale.
354      *
355      * @return The locale or {@code null}.
356      *
357      * @see #createLocale()
358      */
359     public final LocaleType getLocale()
360     {
361         return this.locale;
362     }
363 
364     /**
365      * Creates a new {@code locale} element instance.
366      *
367      * @return A new {@code locale} element instance.
368      *
369      * @throws BuildException if a value already has been created.
370      *
371      * @see #getLocale()
372      */
373     public LocaleType createLocale()
374     {
375         if ( this.locale != null )
376         {
377             throw new BuildException( Messages.getMessage( "multipleElements", "locale" ), this.getLocation() );
378         }
379 
380         this.locale = new LocaleType();
381         return this.locale;
382     }
383 
384     /**
385      * Gets the identifier of a specification to process.
386      *
387      * @return The identifier of a specification to process or {@code null}.
388      *
389      * @see #setSpecification(java.lang.String)
390      */
391     public final String getSpecification()
392     {
393         return this.specification;
394     }
395 
396     /**
397      * Sets the identifier of a specification to process.
398      *
399      * @param value The new identifier of a specification to process or {@code null}.
400      *
401      * @see #getSpecification()
402      */
403     public final void setSpecification( final String value )
404     {
405         this.specification = value;
406     }
407 
408     /**
409      * Gets the specification to process from a given model.
410      *
411      * @param model The model to get the specification to process from.
412      *
413      * @return The specification to process or {@code null}.
414      *
415      * @throws NullPointerException if {@code model} is {@code null}.
416      *
417      * @see #getSpecification()
418      */
419     public final Specification getSpecification( final Model model )
420     {
421         if ( model == null )
422         {
423             throw new NullPointerException( "model" );
424         }
425 
426         Specification s = null;
427 
428         if ( this.getSpecification() != null )
429         {
430             final Modules modules = ModelHelper.getModules( model );
431 
432             if ( modules != null )
433             {
434                 s = modules.getSpecification( this.getSpecification() );
435             }
436 
437             if ( s == null )
438             {
439                 this.log( Messages.getMessage( "specificationNotFound", this.getSpecification() ), Project.MSG_WARN );
440             }
441         }
442 
443         return s;
444     }
445 
446     /**
447      * Gets the identifier of an implementation to process.
448      *
449      * @return The identifier of an implementation to process or {@code null}.
450      *
451      * @see #setImplementation(java.lang.String)
452      */
453     public final String getImplementation()
454     {
455         return this.implementation;
456     }
457 
458     /**
459      * Sets the identifier of an implementation to process.
460      *
461      * @param value The new identifier of an implementation to process or {@code null}.
462      *
463      * @see #getImplementation()
464      */
465     public final void setImplementation( final String value )
466     {
467         this.implementation = value;
468     }
469 
470     /**
471      * Gets the implementation to process from a given model.
472      *
473      * @param model The model to get the implementation to process from.
474      *
475      * @return The implementation to process or {@code null}.
476      *
477      * @throws NullPointerException if {@code model} is {@code null}.
478      *
479      * @see #getImplementation()
480      */
481     public final Implementation getImplementation( final Model model )
482     {
483         if ( model == null )
484         {
485             throw new NullPointerException( "model" );
486         }
487 
488         Implementation i = null;
489 
490         if ( this.getImplementation() != null )
491         {
492             final Modules modules = ModelHelper.getModules( model );
493 
494             if ( modules != null )
495             {
496                 i = modules.getImplementation( this.getImplementation() );
497             }
498 
499             if ( i == null )
500             {
501                 this.log( Messages.getMessage( "implementationNotFound", this.getImplementation() ), Project.MSG_WARN );
502             }
503         }
504 
505         return i;
506     }
507 
508     /**
509      * Gets the identifier of a module to process.
510      *
511      * @return The identifier of a module to process or {@code null}.
512      *
513      * @see #setModule(java.lang.String)
514      */
515     public final String getModule()
516     {
517         return this.module;
518     }
519 
520     /**
521      * Sets the identifier of a module to process.
522      *
523      * @param value The new identifier of a module to process or {@code null}.
524      *
525      * @see #getModule()
526      */
527     public final void setModule( final String value )
528     {
529         this.module = value;
530     }
531 
532     /**
533      * Gets the module to process from a given model.
534      *
535      * @param model The model to get the module to process from.
536      *
537      * @return The module to process or {@code null}.
538      *
539      * @throws NullPointerException if {@code model} is {@code null}.
540      *
541      * @see #getModule()
542      */
543     public final Module getModule( final Model model )
544     {
545         if ( model == null )
546         {
547             throw new NullPointerException( "model" );
548         }
549 
550         Module m = null;
551 
552         if ( this.getModule() != null )
553         {
554             final Modules modules = ModelHelper.getModules( model );
555 
556             if ( modules != null )
557             {
558                 m = modules.getModule( this.getModule() );
559             }
560 
561             if ( m == null )
562             {
563                 this.log( Messages.getMessage( "moduleNotFound", this.getModule() ), Project.MSG_WARN );
564             }
565         }
566 
567         return m;
568     }
569 
570     /**
571      * Gets a flag indicating all modules are requested to be processed.
572      *
573      * @return {@code true}, if processing of all modules is requested; {@code false}, else.
574      *
575      * @see #getSpecification()
576      * @see #getImplementation()
577      * @see #getModule()
578      */
579     public boolean isModulesProcessingRequested()
580     {
581         return this.getSpecification() == null && this.getImplementation() == null && this.getModule() == null;
582     }
583 
584     /**
585      * Gets the Velocity runtime properties to apply.
586      * <p>This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make
587      * to the returned list will be present inside the object. This is why there is no {@code set} method for the
588      * velocity properties property.</p>
589      *
590      * @return The Velocity runtime properties to apply.
591      *
592      * @see #createVelocityProperty()
593      */
594     public final List<KeyValueType> getVelocityProperties()
595     {
596         if ( this.velocityProperties == null )
597         {
598             this.velocityProperties = new LinkedList<KeyValueType>();
599         }
600 
601         return this.velocityProperties;
602     }
603 
604     /**
605      * Creates a new {@code velocityProperty} element instance.
606      *
607      * @return A new {@code velocityProperty} element instance.
608      *
609      * @see #getVelocityProperties()
610      */
611     public KeyValueType createVelocityProperty()
612     {
613         final KeyValueType velocityProperty = new KeyValueType();
614         this.getVelocityProperties().add( velocityProperty );
615         return velocityProperty;
616     }
617 
618     /**
619      * Gets the Velocity runtime property resources to apply.
620      * <p>This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make
621      * to the returned list will be present inside the object. This is why there is no {@code set} method for the
622      * velocity property resources property.</p>
623      *
624      * @return The Velocity runtime property resources to apply.
625      *
626      * @see #createVelocityPropertyResource()
627      */
628     public final List<PropertiesResourceType> getVelocityPropertyResources()
629     {
630         if ( this.velocityPropertyResources == null )
631         {
632             this.velocityPropertyResources = new LinkedList<PropertiesResourceType>();
633         }
634 
635         return this.velocityPropertyResources;
636     }
637 
638     /**
639      * Creates a new {@code velocityPropertyResource} element instance.
640      *
641      * @return A new {@code velocityPropertyResource} element instance.
642      *
643      * @see #getVelocityPropertyResources()
644      */
645     public PropertiesResourceType createVelocityPropertyResource()
646     {
647         final PropertiesResourceType velocityPropertyResource = new PropertiesResourceType();
648         this.getVelocityPropertyResources().add( velocityPropertyResource );
649         return velocityPropertyResource;
650     }
651 
652     /**
653      * Gets the template parameters to apply.
654      * <p>This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make
655      * to the returned list will be present inside the object. This is why there is no {@code set} method for the
656      * template parameters property.</p>
657      *
658      * @return The template parameters to apply.
659      *
660      * @see #createTemplateParameter()
661      */
662     public final List<KeyValueType> getTemplateParameters()
663     {
664         if ( this.templateParameters == null )
665         {
666             this.templateParameters = new LinkedList<KeyValueType>();
667         }
668 
669         return this.templateParameters;
670     }
671 
672     /**
673      * Creates a new {@code templateParameter} element instance.
674      *
675      * @return A new {@code templateParameter} element instance.
676      *
677      * @see #getTemplateParameters()
678      */
679     public KeyValueType createTemplateParameter()
680     {
681         final KeyValueType templateParameter = new KeyValueType();
682         this.getTemplateParameters().add( templateParameter );
683         return templateParameter;
684     }
685 
686     /**
687      * Gets the template parameter resources to apply.
688      * <p>This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make
689      * to the returned list will be present inside the object. This is why there is no {@code set} method for the
690      * template parameter resources property.</p>
691      *
692      * @return The template parameter resources to apply.
693      *
694      * @see #createTemplateParameterResource()
695      */
696     public final List<PropertiesResourceType> getTemplateParameterResources()
697     {
698         if ( this.templateParameterResources == null )
699         {
700             this.templateParameterResources = new LinkedList<PropertiesResourceType>();
701         }
702 
703         return this.templateParameterResources;
704     }
705 
706     /**
707      * Creates a new {@code templateParameterResource} element instance.
708      *
709      * @return A new {@code templateParameterResource} element instance.
710      *
711      * @see #getTemplateParameterResources()
712      */
713     public PropertiesResourceType createTemplateParameterResource()
714     {
715         final PropertiesResourceType templateParameterResource = new PropertiesResourceType();
716         this.getTemplateParameterResources().add( templateParameterResource );
717         return templateParameterResource;
718     }
719 
720     /** {@inheritDoc} */
721     @Override
722     public void preExecuteTask() throws BuildException
723     {
724         super.preExecuteTask();
725 
726         this.assertKeysNotNull( this.getVelocityProperties() );
727         this.assertKeysNotNull( this.getTemplateParameters() );
728         this.assertLocationsNotNull( this.getTemplateParameterResources() );
729         this.assertLocationsNotNull( this.getVelocityPropertyResources() );
730     }
731 
732     /** {@inheritDoc} */
733     @Override
734     public void postExecuteTask() throws BuildException
735     {
736         JomcTool.setDefaultTemplateProfile( null );
737 
738         super.postExecuteTask();
739     }
740 
741     /**
742      * Configures a given {@code JomcTool} instance using the properties of the instance.
743      *
744      * @param tool The tool to configure.
745      *
746      * @throws NullPointerException if {@code tool} is {@code null}.
747      * @throws BuildException if configuring {@code tool} fails.
748      */
749     public void configureJomcTool( final JomcTool tool ) throws BuildException
750     {
751         if ( tool == null )
752         {
753             throw new NullPointerException( "tool" );
754         }
755 
756         try
757         {
758             tool.setLogLevel( Level.ALL );
759             tool.setIndentation( StringEscapeUtils.unescapeJava( this.getIndentation() ) );
760             tool.setInputEncoding( this.getInputEncoding() );
761             tool.setLineSeparator( StringEscapeUtils.unescapeJava( this.getLineSeparator() ) );
762             tool.setOutputEncoding( this.getOutputEncoding() );
763             tool.setDefaultTemplateProfile( this.getDefaultTemplateProfile() );
764             tool.setTemplateProfile( this.getTemplateProfile() );
765             tool.getListeners().add( new JomcTool.Listener()
766             {
767 
768                 @Override
769                 public void onLog( final Level level, final String message, final Throwable throwable )
770                 {
771                     super.onLog( level, message, throwable );
772 
773                     if ( level.intValue() >= Level.SEVERE.intValue() )
774                     {
775                         log( message, throwable, Project.MSG_ERR );
776                     }
777                     else if ( level.intValue() >= Level.WARNING.intValue() )
778                     {
779                         log( message, throwable, Project.MSG_WARN );
780                     }
781                     else if ( level.intValue() >= Level.INFO.intValue() )
782                     {
783                         log( message, throwable, Project.MSG_INFO );
784                     }
785                     else
786                     {
787                         log( message, throwable, Project.MSG_DEBUG );
788                     }
789                 }
790 
791             } );
792 
793             if ( this.getTemplateEncoding() != null )
794             {
795                 this.log( Messages.getMessage( "deprecationWarning", "templateEncoding", "defaultTemplateEncoding" ),
796                           null, Project.MSG_WARN );
797 
798                 tool.setDefaultTemplateEncoding( this.getTemplateEncoding() );
799             }
800             else
801             {
802                 tool.setDefaultTemplateEncoding( this.getDefaultTemplateEncoding() );
803             }
804 
805             for ( int i = 0, s0 = this.getVelocityPropertyResources().size(); i < s0; i++ )
806             {
807                 for ( Map.Entry<Object, Object> e :
808                       this.getProperties( this.getVelocityPropertyResources().get( i ) ).entrySet() )
809                 {
810                     if ( e.getValue() != null )
811                     {
812                         tool.getVelocityEngine().setProperty( e.getKey().toString(), e.getValue() );
813                     }
814                     else
815                     {
816                         tool.getVelocityEngine().clearProperty( e.getKey().toString() );
817                     }
818                 }
819             }
820 
821             for ( int i = 0, s0 = this.getVelocityProperties().size(); i < s0; i++ )
822             {
823                 final KeyValueType p = this.getVelocityProperties().get( i );
824                 final Object object = p.getObject( this.getLocation() );
825 
826                 if ( object != null )
827                 {
828                     tool.getVelocityEngine().setProperty( p.getKey(), object );
829                 }
830                 else
831                 {
832                     tool.getVelocityEngine().clearProperty( p.getKey() );
833                 }
834             }
835 
836             for ( Map.Entry<Object, Object> e : System.getProperties().entrySet() )
837             {
838                 tool.getTemplateParameters().put( e.getKey().toString(), e.getValue() );
839             }
840 
841             for ( final Iterator<Map.Entry<?, ?>> it = this.getProject().getProperties().entrySet().iterator();
842                   it.hasNext(); )
843             {
844                 final Map.Entry<?, ?> e = it.next();
845                 tool.getTemplateParameters().put( e.getKey().toString(), e.getValue() );
846             }
847 
848             for ( int i = 0, s0 = this.getTemplateParameterResources().size(); i < s0; i++ )
849             {
850                 for ( Map.Entry<Object, Object> e :
851                       this.getProperties( this.getTemplateParameterResources().get( i ) ).entrySet() )
852                 {
853                     if ( e.getValue() != null )
854                     {
855                         tool.getTemplateParameters().put( e.getKey().toString(), e.getValue() );
856                     }
857                     else
858                     {
859                         tool.getTemplateParameters().remove( e.getKey().toString() );
860                     }
861                 }
862             }
863 
864             for ( int i = 0, s0 = this.getTemplateParameters().size(); i < s0; i++ )
865             {
866                 final KeyValueType p = this.getTemplateParameters().get( i );
867                 final Object object = p.getObject( this.getLocation() );
868 
869                 if ( object != null )
870                 {
871                     tool.getTemplateParameters().put( p.getKey(), object );
872                 }
873                 else
874                 {
875                     tool.getTemplateParameters().remove( p.getKey() );
876                 }
877             }
878 
879             if ( this.getTemplateLocation() != null )
880             {
881                 final URL url = this.getDirectory( this.getTemplateLocation() );
882                 tool.setTemplateLocation( url );
883 
884                 if ( url == null )
885                 {
886                     this.log( Messages.getMessage( "templateLocationNotFound", this.getTemplateLocation() ),
887                               Project.MSG_WARN );
888 
889                 }
890             }
891 
892             if ( this.getLocale() != null )
893             {
894                 tool.setLocale( new Locale( StringUtils.defaultString( this.getLocale().getLanguage() ),
895                                             StringUtils.defaultString( this.getLocale().getCountry() ),
896                                             StringUtils.defaultString( this.getLocale().getVariant() ) ) );
897 
898             }
899         }
900         catch ( final IOException e )
901         {
902             throw new BuildException( Messages.getMessage( e ), e, this.getLocation() );
903         }
904     }
905 
906     /** {@inheritDoc} */
907     @Override
908     public JomcToolTask clone()
909     {
910         final JomcToolTask clone = (JomcToolTask) super.clone();
911 
912         if ( this.locale != null )
913         {
914             clone.locale = this.locale.clone();
915         }
916 
917         if ( this.velocityPropertyResources != null )
918         {
919             clone.velocityPropertyResources =
920                 new ArrayList<PropertiesResourceType>( this.velocityPropertyResources.size() );
921 
922             for ( PropertiesResourceType e : this.velocityPropertyResources )
923             {
924                 clone.velocityPropertyResources.add( e.clone() );
925             }
926         }
927 
928         if ( this.velocityProperties != null )
929         {
930             clone.velocityProperties = new ArrayList<KeyValueType>( this.velocityProperties.size() );
931 
932             for ( KeyValueType e : this.velocityProperties )
933             {
934                 clone.velocityProperties.add( e.clone() );
935             }
936         }
937 
938         if ( this.velocityPropertyResources != null )
939         {
940             clone.velocityPropertyResources =
941                 new ArrayList<PropertiesResourceType>( this.velocityPropertyResources.size() );
942 
943             for ( PropertiesResourceType e : this.velocityPropertyResources )
944             {
945                 clone.velocityPropertyResources.add( e.clone() );
946             }
947         }
948 
949         if ( this.templateParameters != null )
950         {
951             clone.templateParameters = new ArrayList<KeyValueType>( this.templateParameters.size() );
952 
953             for ( KeyValueType e : this.templateParameters )
954             {
955                 clone.templateParameters.add( e.clone() );
956             }
957         }
958 
959         if ( this.templateParameterResources != null )
960         {
961             clone.templateParameterResources =
962                 new ArrayList<PropertiesResourceType>( this.templateParameterResources.size() );
963 
964             for ( PropertiesResourceType e : this.templateParameterResources )
965             {
966                 clone.templateParameterResources.add( e.clone() );
967             }
968         }
969 
970         return clone;
971     }
972 
973 }