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 }