1 package org.apache.velocity.texen.ant;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.Writer;
27 import java.util.Date;
28 import java.util.Iterator;
29 import java.util.StringTokenizer;
30
31 import org.apache.commons.collections.ExtendedProperties;
32 import org.apache.tools.ant.BuildException;
33 import org.apache.tools.ant.Project;
34 import org.apache.tools.ant.Task;
35 import org.apache.velocity.VelocityContext;
36 import org.apache.velocity.app.VelocityEngine;
37 import org.apache.velocity.context.Context;
38 import org.apache.velocity.exception.MethodInvocationException;
39 import org.apache.velocity.exception.ParseErrorException;
40 import org.apache.velocity.exception.ResourceNotFoundException;
41 import org.apache.velocity.runtime.RuntimeConstants;
42 import org.apache.velocity.texen.Generator;
43 import org.apache.velocity.util.StringUtils;
44
45
46
47
48
49
50
51
52 public class TexenTask
53 extends Task
54 {
55
56
57
58
59
60 private final static String ERR_MSG_FRAGMENT =
61 ". For more information consult the velocity log, or invoke ant " +
62 "with the -debug flag.";
63
64
65
66
67
68
69 protected String controlTemplate;
70
71
72
73
74
75 protected String templatePath;
76
77
78
79
80
81 protected String outputDirectory;
82
83
84
85
86
87 protected String outputFile;
88
89
90
91
92 protected String outputEncoding;
93
94
95
96
97
98 protected String inputEncoding;
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132 protected ExtendedProperties contextProperties;
133
134
135
136
137
138 protected boolean useClasspath;
139
140
141
142
143 protected String logFile;
144
145
146
147
148
149
150 protected String useResourceLoaderCache = "false";
151
152
153
154 protected String resourceLoaderModificationCheckInterval = "2";
155
156
157
158
159
160
161 public void setControlTemplate (String controlTemplate)
162 {
163 this.controlTemplate = controlTemplate;
164 }
165
166
167
168
169
170
171 public String getControlTemplate()
172 {
173 return controlTemplate;
174 }
175
176
177
178
179
180
181
182
183
184 public void setTemplatePath(String templatePath) throws Exception
185 {
186 StringBuffer resolvedPath = new StringBuffer();
187 StringTokenizer st = new StringTokenizer(templatePath, ",");
188 while ( st.hasMoreTokens() )
189 {
190
191
192 File fullPath = project.resolveFile(st.nextToken());
193 resolvedPath.append(fullPath.getCanonicalPath());
194 if ( st.hasMoreTokens() )
195 {
196 resolvedPath.append(",");
197 }
198 }
199 this.templatePath = resolvedPath.toString();
200
201 System.out.println(templatePath);
202 }
203
204
205
206
207
208
209
210 public String getTemplatePath()
211 {
212 return templatePath;
213 }
214
215
216
217
218
219
220 public void setOutputDirectory(File outputDirectory)
221 {
222 try
223 {
224 this.outputDirectory = outputDirectory.getCanonicalPath();
225 }
226 catch (java.io.IOException ioe)
227 {
228 throw new BuildException(ioe);
229 }
230 }
231
232
233
234
235
236 public String getOutputDirectory()
237 {
238 return outputDirectory;
239 }
240
241
242
243
244
245
246 public void setOutputFile(String outputFile)
247 {
248 this.outputFile = outputFile;
249 }
250
251
252
253
254
255 public void setOutputEncoding(String outputEncoding)
256 {
257 this.outputEncoding = outputEncoding;
258 }
259
260
261
262
263
264 public void setInputEncoding(String inputEncoding)
265 {
266 this.inputEncoding = inputEncoding;
267 }
268
269
270
271
272
273
274 public String getOutputFile()
275 {
276 return outputFile;
277 }
278
279
280
281
282
283 public void setLogFile(String log)
284 {
285 this.logFile = log;
286 }
287
288
289
290
291
292 public String getLogFile()
293 {
294 return this.logFile;
295 }
296
297
298
299
300
301
302
303 public void setContextProperties( String file )
304 {
305 String[] sources = StringUtils.split(file,",");
306 contextProperties = new ExtendedProperties();
307
308
309
310
311
312
313
314 for (int i = 0; i < sources.length; i++)
315 {
316 ExtendedProperties source = new ExtendedProperties();
317
318 try
319 {
320
321
322 File fullPath = project.resolveFile(sources[i]);
323 log("Using contextProperties file: " + fullPath);
324 source.load(new FileInputStream(fullPath));
325 }
326 catch (IOException e)
327 {
328 ClassLoader classLoader = this.getClass().getClassLoader();
329
330 try
331 {
332 InputStream inputStream = classLoader.getResourceAsStream(sources[i]);
333
334 if (inputStream == null)
335 {
336 throw new BuildException("Context properties file " + sources[i] +
337 " could not be found in the file system or on the classpath!");
338 }
339 else
340 {
341 source.load(inputStream);
342 }
343 }
344 catch (IOException ioe)
345 {
346 source = null;
347 }
348 }
349
350 if (source != null)
351 {
352 for (Iterator j = source.getKeys(); j.hasNext(); )
353 {
354 String name = (String) j.next();
355 String value = StringUtils.nullTrim(source.getString(name));
356 contextProperties.setProperty(name,value);
357 }
358 }
359 }
360 }
361
362
363
364
365
366
367
368 public ExtendedProperties getContextProperties()
369 {
370 return contextProperties;
371 }
372
373
374
375
376
377
378 public void setUseClasspath(boolean useClasspath)
379 {
380 this.useClasspath = useClasspath;
381 }
382
383
384
385
386 public void setUseResourceLoaderCache(String useResourceLoaderCache)
387 {
388 this.useResourceLoaderCache = useResourceLoaderCache;
389 }
390
391
392
393
394 public void setResourceLoaderModificationCheckInterval(String resourceLoaderModificationCheckInterval)
395 {
396 this.resourceLoaderModificationCheckInterval = resourceLoaderModificationCheckInterval;
397 }
398
399
400
401
402
403
404
405 public Context initControlContext()
406 throws Exception
407 {
408 return new VelocityContext();
409 }
410
411
412
413
414
415
416
417
418 public void execute ()
419 throws BuildException
420 {
421
422 if (templatePath == null && useClasspath == false)
423 {
424 throw new BuildException(
425 "The template path needs to be defined if you are not using " +
426 "the classpath for locating templates!");
427 }
428
429
430 if (controlTemplate == null)
431 {
432 throw new BuildException("The control template needs to be defined!");
433 }
434
435
436 if (outputDirectory == null)
437 {
438 throw new BuildException("The output directory needs to be defined!");
439 }
440
441
442 if (outputFile == null)
443 {
444 throw new BuildException("The output file needs to be defined!");
445 }
446
447 VelocityEngine ve = new VelocityEngine();
448
449 try
450 {
451
452 if (templatePath != null)
453 {
454 log("Using templatePath: " + templatePath, Project.MSG_VERBOSE);
455 ve.setProperty(
456 RuntimeConstants.FILE_RESOURCE_LOADER_PATH, templatePath);
457 }
458
459 if (useClasspath)
460 {
461 log("Using classpath");
462 ve.addProperty(
463 VelocityEngine.RESOURCE_LOADER, "classpath");
464
465 ve.setProperty(
466 "classpath." + VelocityEngine.RESOURCE_LOADER + ".class",
467 "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
468
469 ve.setProperty(
470 "classpath." + VelocityEngine.RESOURCE_LOADER +
471 ".cache", useResourceLoaderCache);
472
473 ve.setProperty(
474 "classpath." + VelocityEngine.RESOURCE_LOADER +
475 ".modificationCheckInterval", resourceLoaderModificationCheckInterval);
476 }
477
478 if (this.logFile != null)
479 {
480 ve.setProperty(RuntimeConstants.RUNTIME_LOG, this.logFile);
481 }
482
483 ve.init();
484
485
486 Generator generator = Generator.getInstance();
487 generator.setVelocityEngine(ve);
488 generator.setOutputPath(outputDirectory);
489 generator.setInputEncoding(inputEncoding);
490 generator.setOutputEncoding(outputEncoding);
491
492 if (templatePath != null)
493 {
494 generator.setTemplatePath(templatePath);
495 }
496
497
498
499 File file = new File(outputDirectory);
500 if (! file.exists())
501 {
502 file.mkdirs();
503 }
504
505 String path = outputDirectory + File.separator + outputFile;
506 log("Generating to file " + path, Project.MSG_INFO);
507 Writer writer = generator.getWriter(path, outputEncoding);
508
509
510
511
512 Context c = initControlContext();
513
514
515
516
517
518
519 populateInitialContext(c);
520
521
522
523
524 if (contextProperties != null)
525 {
526 Iterator i = contextProperties.getKeys();
527
528 while (i.hasNext())
529 {
530 String property = (String) i.next();
531 String value = StringUtils.nullTrim(contextProperties.getString(property));
532
533
534
535
536 try
537 {
538 c.put(property, new Integer(value));
539 }
540 catch (NumberFormatException nfe)
541 {
542
543
544
545 String booleanString =
546 contextProperties.testBoolean(value);
547
548 if (booleanString != null)
549 {
550 c.put(property, Boolean.valueOf(booleanString));
551 }
552 else
553 {
554
555
556
557
558
559
560
561
562
563
564
565
566
567 if (property.endsWith("file.contents"))
568 {
569
570
571 value = StringUtils.fileContentsToString(
572 project.resolveFile(value).getCanonicalPath());
573
574 property = property.substring(
575 0, property.indexOf("file.contents") - 1);
576 }
577
578 c.put(property, value);
579 }
580 }
581 }
582 }
583
584 writer.write(generator.parse(controlTemplate, c));
585 writer.flush();
586 writer.close();
587 generator.shutdown();
588 cleanup();
589 }
590 catch( BuildException e)
591 {
592 throw e;
593 }
594 catch( MethodInvocationException e )
595 {
596 throw new BuildException(
597 "Exception thrown by '" + e.getReferenceName() + "." +
598 e.getMethodName() +"'" + ERR_MSG_FRAGMENT,
599 e.getWrappedThrowable());
600 }
601 catch( ParseErrorException e )
602 {
603 throw new BuildException("Velocity syntax error" + ERR_MSG_FRAGMENT ,e);
604 }
605 catch( ResourceNotFoundException e )
606 {
607 throw new BuildException("Resource not found" + ERR_MSG_FRAGMENT,e);
608 }
609 catch( Exception e )
610 {
611 throw new BuildException("Generation failed" + ERR_MSG_FRAGMENT ,e);
612 }
613 }
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632 protected void populateInitialContext(Context context)
633 throws Exception
634 {
635 context.put("now", new Date().toString());
636 }
637
638
639
640
641
642
643
644
645
646 protected void cleanup()
647 throws Exception
648 {
649 }
650 }