Source Code Cross Referenced for TexenTask.java in  » Template-Engine » Velocity » org » apache » velocity » texen » ant » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Template Engine » Velocity » org.apache.velocity.texen.ant 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.apache.velocity.texen.ant;
002:
003:        /*
004:         * Licensed to the Apache Software Foundation (ASF) under one
005:         * or more contributor license agreements.  See the NOTICE file
006:         * distributed with this work for additional information
007:         * regarding copyright ownership.  The ASF licenses this file
008:         * to you under the Apache License, Version 2.0 (the
009:         * "License"); you may not use this file except in compliance
010:         * with the License.  You may obtain a copy of the License at
011:         *
012:         *   http://www.apache.org/licenses/LICENSE-2.0
013:         *
014:         * Unless required by applicable law or agreed to in writing,
015:         * software distributed under the License is distributed on an
016:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017:         * KIND, either express or implied.  See the License for the
018:         * specific language governing permissions and limitations
019:         * under the License.    
020:         */
021:
022:        import java.io.File;
023:        import java.io.FileInputStream;
024:        import java.io.IOException;
025:        import java.io.InputStream;
026:        import java.io.Writer;
027:        import java.util.Date;
028:        import java.util.Iterator;
029:        import java.util.StringTokenizer;
030:
031:        import org.apache.commons.collections.ExtendedProperties;
032:        import org.apache.tools.ant.BuildException;
033:        import org.apache.tools.ant.Project;
034:        import org.apache.tools.ant.Task;
035:        import org.apache.velocity.VelocityContext;
036:        import org.apache.velocity.app.VelocityEngine;
037:        import org.apache.velocity.context.Context;
038:        import org.apache.velocity.exception.MethodInvocationException;
039:        import org.apache.velocity.exception.ParseErrorException;
040:        import org.apache.velocity.exception.ResourceNotFoundException;
041:        import org.apache.velocity.runtime.RuntimeConstants;
042:        import org.apache.velocity.texen.Generator;
043:        import org.apache.velocity.util.StringUtils;
044:
045:        /**
046:         * An ant task for generating output by using Velocity
047:         *
048:         * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
049:         * @author <a href="robertdonkin@mac.com">Robert Burrell Donkin</a>
050:         * @version $Id: TexenTask.java 463298 2006-10-12 16:10:32Z henning $
051:         */
052:        public class TexenTask extends Task {
053:            /**
054:             * This message fragment (telling users to consult the log or
055:             * invoke ant with the -debug flag) is appended to rethrown
056:             * exception messages.
057:             */
058:            private final static String ERR_MSG_FRAGMENT = ". For more information consult the velocity log, or invoke ant "
059:                    + "with the -debug flag.";
060:
061:            /**
062:             * This is the control template that governs the output.
063:             * It may or may not invoke the services of worker
064:             * templates.
065:             */
066:            protected String controlTemplate;
067:
068:            /**
069:             * This is where Velocity will look for templates
070:             * using the file template loader.
071:             */
072:            protected String templatePath;
073:
074:            /**
075:             * This is where texen will place all the output
076:             * that is a product of the generation process.
077:             */
078:            protected String outputDirectory;
079:
080:            /**
081:             * This is the file where the generated text
082:             * will be placed.
083:             */
084:            protected String outputFile;
085:
086:            /**
087:             * This is the encoding for the output file(s).
088:             */
089:            protected String outputEncoding;
090:
091:            /**
092:             * This is the encoding for the input file(s)
093:             * (templates).
094:             */
095:            protected String inputEncoding;
096:
097:            /**
098:             * <p>
099:             * These are properties that are fed into the
100:             * initial context from a properties file. This
101:             * is simply a convenient way to set some values
102:             * that you wish to make available in the context.
103:             * </p>
104:             * <p>
105:             * These values are not critical, like the template path
106:             * or output path, but allow a convenient way to
107:             * set a value that may be specific to a particular
108:             * generation task.
109:             * </p>
110:             * <p>
111:             * For example, if you are generating scripts to allow
112:             * user to automatically create a database, then
113:             * you might want the <code>$databaseName</code>
114:             * to be placed
115:             * in the initial context so that it is available
116:             * in a script that might look something like the
117:             * following:
118:             * <code><pre>
119:             * #!bin/sh
120:             *
121:             * echo y | mysqladmin create $databaseName
122:             * </pre></code>
123:             * The value of <code>$databaseName</code> isn't critical to
124:             * output, and you obviously don't want to change
125:             * the ant task to simply take a database name.
126:             * So initial context values can be set with
127:             * properties file.
128:             */
129:            protected ExtendedProperties contextProperties;
130:
131:            /**
132:             * Property which controls whether the classpath
133:             * will be used when trying to locate templates.
134:             */
135:            protected boolean useClasspath;
136:
137:            /**
138:             * The LogFile (incl. path) to log to.
139:             */
140:            protected String logFile;
141:
142:            /**
143:             *   Property which controls whether the resource
144:             *   loader will be told to cache.  Default false
145:             */
146:
147:            protected String useResourceLoaderCache = "false";
148:            /**
149:             *
150:             */
151:            protected String resourceLoaderModificationCheckInterval = "2";
152:
153:            /**
154:             * [REQUIRED] Set the control template for the
155:             * generating process.
156:             * @param controlTemplate
157:             */
158:            public void setControlTemplate(String controlTemplate) {
159:                this .controlTemplate = controlTemplate;
160:            }
161:
162:            /**
163:             * Get the control template for the
164:             * generating process.
165:             * @return The current control template.
166:             */
167:            public String getControlTemplate() {
168:                return controlTemplate;
169:            }
170:
171:            /**
172:             * [REQUIRED] Set the path where Velocity will look
173:             * for templates using the file template
174:             * loader.
175:             * @param templatePath
176:             * @throws Exception
177:             */
178:
179:            public void setTemplatePath(String templatePath) throws Exception {
180:                StringBuffer resolvedPath = new StringBuffer();
181:                StringTokenizer st = new StringTokenizer(templatePath, ",");
182:                while (st.hasMoreTokens()) {
183:                    // resolve relative path from basedir and leave
184:                    // absolute path untouched.
185:                    File fullPath = project.resolveFile(st.nextToken());
186:                    resolvedPath.append(fullPath.getCanonicalPath());
187:                    if (st.hasMoreTokens()) {
188:                        resolvedPath.append(",");
189:                    }
190:                }
191:                this .templatePath = resolvedPath.toString();
192:
193:                System.out.println(templatePath);
194:            }
195:
196:            /**
197:             * Get the path where Velocity will look
198:             * for templates using the file template
199:             * loader.
200:             * @return The template path.
201:             */
202:            public String getTemplatePath() {
203:                return templatePath;
204:            }
205:
206:            /**
207:             * [REQUIRED] Set the output directory. It will be
208:             * created if it doesn't exist.
209:             * @param outputDirectory
210:             */
211:            public void setOutputDirectory(File outputDirectory) {
212:                try {
213:                    this .outputDirectory = outputDirectory.getCanonicalPath();
214:                } catch (java.io.IOException ioe) {
215:                    throw new BuildException(ioe);
216:                }
217:            }
218:
219:            /**
220:             * Get the output directory.
221:             * @return The output directory.
222:             */
223:            public String getOutputDirectory() {
224:                return outputDirectory;
225:            }
226:
227:            /**
228:             * [REQUIRED] Set the output file for the
229:             * generation process.
230:             * @param outputFile
231:             */
232:            public void setOutputFile(String outputFile) {
233:                this .outputFile = outputFile;
234:            }
235:
236:            /**
237:             * Set the output encoding.
238:             * @param outputEncoding
239:             */
240:            public void setOutputEncoding(String outputEncoding) {
241:                this .outputEncoding = outputEncoding;
242:            }
243:
244:            /**
245:             * Set the input (template) encoding.
246:             * @param inputEncoding
247:             */
248:            public void setInputEncoding(String inputEncoding) {
249:                this .inputEncoding = inputEncoding;
250:            }
251:
252:            /**
253:             * Get the output file for the
254:             * generation process.
255:             * @return The output file.
256:             */
257:            public String getOutputFile() {
258:                return outputFile;
259:            }
260:
261:            /**
262:             * Sets the log file.
263:             * @param log
264:             */
265:            public void setLogFile(String log) {
266:                this .logFile = log;
267:            }
268:
269:            /**
270:             * Gets the log file.
271:             * @return The log file.
272:             */
273:            public String getLogFile() {
274:                return this .logFile;
275:            }
276:
277:            /**
278:             * Set the context properties that will be
279:             * fed into the initial context be the
280:             * generating process starts.
281:             * @param file
282:             */
283:            public void setContextProperties(String file) {
284:                String[] sources = StringUtils.split(file, ",");
285:                contextProperties = new ExtendedProperties();
286:
287:                // Always try to get the context properties resource
288:                // from a file first. Templates may be taken from a JAR
289:                // file but the context properties resource may be a
290:                // resource in the filesystem. If this fails than attempt
291:                // to get the context properties resource from the
292:                // classpath.
293:                for (int i = 0; i < sources.length; i++) {
294:                    ExtendedProperties source = new ExtendedProperties();
295:
296:                    try {
297:                        // resolve relative path from basedir and leave
298:                        // absolute path untouched.
299:                        File fullPath = project.resolveFile(sources[i]);
300:                        log("Using contextProperties file: " + fullPath);
301:                        source.load(new FileInputStream(fullPath));
302:                    } catch (IOException e) {
303:                        ClassLoader classLoader = this .getClass()
304:                                .getClassLoader();
305:
306:                        try {
307:                            InputStream inputStream = classLoader
308:                                    .getResourceAsStream(sources[i]);
309:
310:                            if (inputStream == null) {
311:                                throw new BuildException(
312:                                        "Context properties file "
313:                                                + sources[i]
314:                                                + " could not be found in the file system or on the classpath!");
315:                            } else {
316:                                source.load(inputStream);
317:                            }
318:                        } catch (IOException ioe) {
319:                            source = null;
320:                        }
321:                    }
322:
323:                    if (source != null) {
324:                        for (Iterator j = source.getKeys(); j.hasNext();) {
325:                            String name = (String) j.next();
326:                            String value = StringUtils.nullTrim(source
327:                                    .getString(name));
328:                            contextProperties.setProperty(name, value);
329:                        }
330:                    }
331:                }
332:            }
333:
334:            /**
335:             * Get the context properties that will be
336:             * fed into the initial context be the
337:             * generating process starts.
338:             * @return The current context properties.
339:             */
340:            public ExtendedProperties getContextProperties() {
341:                return contextProperties;
342:            }
343:
344:            /**
345:             * Set the use of the classpath in locating templates
346:             *
347:             * @param useClasspath true means the classpath will be used.
348:             */
349:            public void setUseClasspath(boolean useClasspath) {
350:                this .useClasspath = useClasspath;
351:            }
352:
353:            /**
354:             * @param useResourceLoaderCache
355:             */
356:            public void setUseResourceLoaderCache(String useResourceLoaderCache) {
357:                this .useResourceLoaderCache = useResourceLoaderCache;
358:            }
359:
360:            /**
361:             * @param resourceLoaderModificationCheckInterval
362:             */
363:            public void setResourceLoaderModificationCheckInterval(
364:                    String resourceLoaderModificationCheckInterval) {
365:                this .resourceLoaderModificationCheckInterval = resourceLoaderModificationCheckInterval;
366:            }
367:
368:            /**
369:             * Creates a VelocityContext.
370:             *
371:             * @return new Context
372:             * @throws Exception the execute method will catch
373:             *         and rethrow as a <code>BuildException</code>
374:             */
375:            public Context initControlContext() throws Exception {
376:                return new VelocityContext();
377:            }
378:
379:            /**
380:             * Execute the input script with Velocity
381:             *
382:             * @throws BuildException
383:             * BuildExceptions are thrown when required attributes are missing.
384:             * Exceptions thrown by Velocity are rethrown as BuildExceptions.
385:             */
386:            public void execute() throws BuildException {
387:                // Make sure the template path is set.
388:                if (templatePath == null && useClasspath == false) {
389:                    throw new BuildException(
390:                            "The template path needs to be defined if you are not using "
391:                                    + "the classpath for locating templates!");
392:                }
393:
394:                // Make sure the control template is set.
395:                if (controlTemplate == null) {
396:                    throw new BuildException(
397:                            "The control template needs to be defined!");
398:                }
399:
400:                // Make sure the output directory is set.
401:                if (outputDirectory == null) {
402:                    throw new BuildException(
403:                            "The output directory needs to be defined!");
404:                }
405:
406:                // Make sure there is an output file.
407:                if (outputFile == null) {
408:                    throw new BuildException(
409:                            "The output file needs to be defined!");
410:                }
411:
412:                VelocityEngine ve = new VelocityEngine();
413:
414:                try {
415:                    // Setup the Velocity Runtime.
416:                    if (templatePath != null) {
417:                        log("Using templatePath: " + templatePath,
418:                                Project.MSG_VERBOSE);
419:                        ve.setProperty(
420:                                RuntimeConstants.FILE_RESOURCE_LOADER_PATH,
421:                                templatePath);
422:                    }
423:
424:                    if (useClasspath) {
425:                        log("Using classpath");
426:                        ve.addProperty(VelocityEngine.RESOURCE_LOADER,
427:                                "classpath");
428:
429:                        ve
430:                                .setProperty("classpath."
431:                                        + VelocityEngine.RESOURCE_LOADER
432:                                        + ".class",
433:                                        "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
434:
435:                        ve.setProperty("classpath."
436:                                + VelocityEngine.RESOURCE_LOADER + ".cache",
437:                                useResourceLoaderCache);
438:
439:                        ve.setProperty("classpath."
440:                                + VelocityEngine.RESOURCE_LOADER
441:                                + ".modificationCheckInterval",
442:                                resourceLoaderModificationCheckInterval);
443:                    }
444:
445:                    if (this .logFile != null) {
446:                        ve.setProperty(RuntimeConstants.RUNTIME_LOG,
447:                                this .logFile);
448:                    }
449:
450:                    ve.init();
451:
452:                    // Create the text generator.
453:                    Generator generator = Generator.getInstance();
454:                    generator.setVelocityEngine(ve);
455:                    generator.setOutputPath(outputDirectory);
456:                    generator.setInputEncoding(inputEncoding);
457:                    generator.setOutputEncoding(outputEncoding);
458:
459:                    if (templatePath != null) {
460:                        generator.setTemplatePath(templatePath);
461:                    }
462:
463:                    // Make sure the output directory exists, if it doesn't
464:                    // then create it.
465:                    File file = new File(outputDirectory);
466:                    if (!file.exists()) {
467:                        file.mkdirs();
468:                    }
469:
470:                    String path = outputDirectory + File.separator + outputFile;
471:                    log("Generating to file " + path, Project.MSG_INFO);
472:                    Writer writer = generator.getWriter(path, outputEncoding);
473:
474:                    // The generator and the output path should
475:                    // be placed in the init context here and
476:                    // not in the generator class itself.
477:                    Context c = initControlContext();
478:
479:                    // Everything in the generator class should be
480:                    // pulled out and placed in here. What the generator
481:                    // class does can probably be added to the Velocity
482:                    // class and the generator class can probably
483:                    // be removed all together.
484:                    populateInitialContext(c);
485:
486:                    // Feed all the options into the initial
487:                    // control context so they are available
488:                    // in the control/worker templates.
489:                    if (contextProperties != null) {
490:                        Iterator i = contextProperties.getKeys();
491:
492:                        while (i.hasNext()) {
493:                            String property = (String) i.next();
494:                            String value = StringUtils
495:                                    .nullTrim(contextProperties
496:                                            .getString(property));
497:
498:                            // Now lets quickly check to see if what
499:                            // we have is numeric and try to put it
500:                            // into the context as an Integer.
501:                            try {
502:                                c.put(property, new Integer(value));
503:                            } catch (NumberFormatException nfe) {
504:                                // Now we will try to place the value into
505:                                // the context as a boolean value if it
506:                                // maps to a valid boolean value.
507:                                String booleanString = contextProperties
508:                                        .testBoolean(value);
509:
510:                                if (booleanString != null) {
511:                                    c.put(property, Boolean
512:                                            .valueOf(booleanString));
513:                                } else {
514:                                    // We are going to do something special
515:                                    // for properties that have a "file.contents"
516:                                    // suffix: for these properties will pull
517:                                    // in the contents of the file and make
518:                                    // them available in the context. So for
519:                                    // a line like the following in a properties file:
520:                                    //
521:                                    // license.file.contents = license.txt
522:                                    //
523:                                    // We will pull in the contents of license.txt
524:                                    // and make it available in the context as
525:                                    // $license. This should make texen a little
526:                                    // more flexible.
527:                                    if (property.endsWith("file.contents")) {
528:                                        // We need to turn the license file from relative to
529:                                        // absolute, and let Ant help :)
530:                                        value = StringUtils
531:                                                .fileContentsToString(project
532:                                                        .resolveFile(value)
533:                                                        .getCanonicalPath());
534:
535:                                        property = property
536:                                                .substring(
537:                                                        0,
538:                                                        property
539:                                                                .indexOf("file.contents") - 1);
540:                                    }
541:
542:                                    c.put(property, value);
543:                                }
544:                            }
545:                        }
546:                    }
547:
548:                    writer.write(generator.parse(controlTemplate, c));
549:                    writer.flush();
550:                    writer.close();
551:                    generator.shutdown();
552:                    cleanup();
553:                } catch (BuildException e) {
554:                    throw e;
555:                } catch (MethodInvocationException e) {
556:                    throw new BuildException("Exception thrown by '"
557:                            + e.getReferenceName() + "." + e.getMethodName()
558:                            + "'" + ERR_MSG_FRAGMENT, e.getWrappedThrowable());
559:                } catch (ParseErrorException e) {
560:                    throw new BuildException("Velocity syntax error"
561:                            + ERR_MSG_FRAGMENT, e);
562:                } catch (ResourceNotFoundException e) {
563:                    throw new BuildException("Resource not found"
564:                            + ERR_MSG_FRAGMENT, e);
565:                } catch (Exception e) {
566:                    throw new BuildException("Generation failed"
567:                            + ERR_MSG_FRAGMENT, e);
568:                }
569:            }
570:
571:            /**
572:             * <p>Place useful objects into the initial context.</p>
573:             *
574:             * <p>TexenTask places <code>Date().toString()</code> into the
575:             * context as <code>$now</code>.  Subclasses who want to vary the
576:             * objects in the context should override this method.</p>
577:             *
578:             * <p><code>$generator</code> is not put into the context in this
579:             * method.</p>
580:             *
581:             * @param context The context to populate, as retrieved from
582:             * {@link #initControlContext()}.
583:             *
584:             * @throws Exception Error while populating context.  The {@link
585:             * #execute()} method will catch and rethrow as a
586:             * <code>BuildException</code>.
587:             */
588:            protected void populateInitialContext(Context context)
589:                    throws Exception {
590:                context.put("now", new Date().toString());
591:            }
592:
593:            /**
594:             * A hook method called at the end of {@link #execute()} which can
595:             * be overridden to perform any necessary cleanup activities (such
596:             * as the release of database connections, etc.).  By default,
597:             * does nothing.
598:             *
599:             * @exception Exception Problem cleaning up.
600:             */
601:            protected void cleanup() throws Exception {
602:            }
603:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.