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