Source Code Cross Referenced for VelocityTemplateEngine.java in  » UML » AndroMDA-3.2 » org » andromda » templateengines » velocity » 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 » UML » AndroMDA 3.2 » org.andromda.templateengines.velocity 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.andromda.templateengines.velocity;
002:
003:        import java.io.File;
004:        import java.io.IOException;
005:        import java.io.InputStream;
006:        import java.io.StringWriter;
007:        import java.io.Writer;
008:        import java.net.URL;
009:        import java.util.ArrayList;
010:        import java.util.Collection;
011:        import java.util.HashMap;
012:        import java.util.Iterator;
013:        import java.util.List;
014:        import java.util.Map;
015:        import java.util.Properties;
016:
017:        import org.andromda.core.common.AndroMDALogger;
018:        import org.andromda.core.common.Constants;
019:        import org.andromda.core.common.ExceptionUtils;
020:        import org.andromda.core.common.Merger;
021:        import org.andromda.core.common.ResourceUtils;
022:        import org.andromda.core.common.ResourceWriter;
023:        import org.andromda.core.templateengine.TemplateEngine;
024:        import org.andromda.core.templateengine.TemplateEngineException;
025:        import org.apache.commons.collections.ExtendedProperties;
026:        import org.apache.commons.lang.StringUtils;
027:        import org.apache.log4j.FileAppender;
028:        import org.apache.log4j.Logger;
029:        import org.apache.log4j.PatternLayout;
030:        import org.apache.velocity.Template;
031:        import org.apache.velocity.VelocityContext;
032:        import org.apache.velocity.app.VelocityEngine;
033:        import org.apache.velocity.runtime.RuntimeServices;
034:        import org.apache.velocity.runtime.log.LogSystem;
035:        import org.apache.velocity.runtime.resource.loader.FileResourceLoader;
036:
037:        /**
038:         * The TemplateEngine implementation for VelocityTemplateEngine template processor.
039:         *
040:         * @author <a href="http://www.mbohlen.de">Matthias Bohlen </a>
041:         * @author Chad Brandon
042:         * @see http://jakarta.apache.org/velocity/
043:         */
044:        public class VelocityTemplateEngine implements  TemplateEngine {
045:            protected static Logger logger = null;
046:
047:            /**
048:             * The directory we look in to find velocity properties.
049:             */
050:            private static final String PROPERTIES_DIR = "META-INF/";
051:
052:            /**
053:             * The suffix for the the velocity properties.
054:             */
055:            private static final String PROPERTIES_SUFFIX = "-velocity.properties";
056:
057:            /**
058:             * The location to which temporary templates are written
059:             */
060:            private static final String TEMPORARY_TEMPLATE_LOCATION = Constants.TEMPORARY_DIRECTORY
061:                    + "velocity/merged";
062:
063:            /**
064:             * The location of external templates
065:             */
066:            private String mergeLocation;
067:
068:            /**
069:             * Stores additional properties specified within the plugin within the file META-INF/'plugin
070:             * name'-velocity.properties
071:             */
072:            private Properties properties = null;
073:
074:            /**
075:             * The current namespace this template engine is running within.
076:             */
077:            private String namespace;
078:
079:            /**
080:             * the VelocityEngine instance to use
081:             */
082:            private VelocityEngine velocityEngine;
083:            private VelocityContext velocityContext;
084:            private final List macroLibraries = new ArrayList();
085:
086:            /**
087:             * Stores a collection of templates that have already been
088:             * discovered by the velocity engine
089:             */
090:            private final Map discoveredTemplates = new HashMap();
091:
092:            /**
093:             * Stores the merged template files that are deleted at shutdown.
094:             */
095:            private final Collection mergedTemplateFiles = new ArrayList();
096:
097:            /**
098:             * @see org.andromda.core.templateengine.TemplateEngine#init(java.lang.String)
099:             */
100:            public void initialize(final String namespace) throws Exception {
101:                this .namespace = namespace;
102:                this .initLogger(namespace);
103:
104:                ExtendedProperties engineProperties = new ExtendedProperties();
105:
106:                // Tell VelocityTemplateEngine it should also use the
107:                // classpath when searching for templates
108:                // IMPORTANT: file,andromda.plugins the ordering of these
109:                // two things matters, the ordering allows files to override
110:                // the resources found on the classpath.
111:                engineProperties.setProperty(VelocityEngine.RESOURCE_LOADER,
112:                        "file,classpath");
113:
114:                engineProperties.setProperty("file."
115:                        + VelocityEngine.RESOURCE_LOADER + ".class",
116:                        FileResourceLoader.class.getName());
117:
118:                engineProperties.setProperty("classpath."
119:                        + VelocityEngine.RESOURCE_LOADER + ".class",
120:                        ClasspathResourceLoader.class.getName());
121:
122:                // Tell VelocityTemplateEngine not to use its own logger
123:                // the logger but to use of this plugin.
124:                engineProperties.setProperty(
125:                        VelocityEngine.RUNTIME_LOG_LOGSYSTEM,
126:                        new VelocityLoggingReceiver());
127:
128:                // Let this template engine know about the macro libraries.
129:                for (final Iterator iterator = getMacroLibraries().iterator(); iterator
130:                        .hasNext();) {
131:                    engineProperties.addProperty(VelocityEngine.VM_LIBRARY,
132:                            iterator.next());
133:                }
134:
135:                this .velocityEngine = new VelocityEngine();
136:                this .velocityEngine.setExtendedProperties(engineProperties);
137:
138:                if (this .mergeLocation != null) {
139:                    // set the file resource path (to the merge location)
140:                    velocityEngine.addProperty(
141:                            VelocityEngine.FILE_RESOURCE_LOADER_PATH,
142:                            this .mergeLocation);
143:                }
144:
145:                // if the namespace requires a merge add the temporary template
146:                // location to which merged templates are written
147:                if (Merger.instance().requiresMerge(this .namespace)) {
148:                    velocityEngine.addProperty(
149:                            VelocityEngine.FILE_RESOURCE_LOADER_PATH, this 
150:                                    .getMergedTemplatesLocation());
151:                }
152:
153:                this .addProperties(namespace);
154:                this .velocityEngine.init();
155:            }
156:
157:            /**
158:             * Adds any properties found within META-INF/'plugin name'-velocity.properties
159:             */
160:            private void addProperties(String pluginName) throws IOException {
161:                // reset any properties from previous processing
162:                this .properties = null;
163:
164:                // see if the velocity properties exist for the current
165:                // plugin
166:                URL propertiesUri = ResourceUtils.getResource(PROPERTIES_DIR
167:                        + StringUtils.trimToEmpty(pluginName)
168:                        + PROPERTIES_SUFFIX);
169:
170:                if (propertiesUri != null) {
171:                    if (logger.isDebugEnabled()) {
172:                        logger.debug("loading properties from --> '"
173:                                + propertiesUri + "'");
174:                    }
175:
176:                    this .properties = new Properties();
177:                    this .properties.load(propertiesUri.openStream());
178:
179:                    for (final Iterator iterator = this .properties.keySet()
180:                            .iterator(); iterator.hasNext();) {
181:                        final String property = (String) iterator.next();
182:                        final String value = this .properties
183:                                .getProperty(property);
184:                        if (logger.isDebugEnabled()) {
185:                            logger.debug("setting property '" + property
186:                                    + "' with --> '" + value + "'");
187:                        }
188:                        this .velocityEngine.setProperty(property, value);
189:                    }
190:                }
191:            }
192:
193:            /**
194:             * @see org.andromda.core.templateengine.TemplateEngine#processTemplate(java.lang.String, java.util.Map,
195:             *      java.io.StringWriter)
196:             */
197:            public void processTemplate(final String templateFile,
198:                    final Map templateObjects, final Writer output)
199:                    throws Exception {
200:                final String methodName = "VelocityTemplateEngine.processTemplate";
201:
202:                if (logger.isDebugEnabled()) {
203:                    logger
204:                            .debug("performing " + methodName
205:                                    + " with templateFile '" + templateFile
206:                                    + "' and templateObjects '"
207:                                    + templateObjects + "'");
208:                }
209:                ExceptionUtils.checkEmpty("templateFile", templateFile);
210:                ExceptionUtils.checkNull("output", output);
211:                this .velocityContext = new VelocityContext();
212:                this .loadVelocityContext(templateObjects);
213:
214:                Template template = (Template) this .discoveredTemplates
215:                        .get(templateFile);
216:                if (template == null) {
217:                    template = this .velocityEngine.getTemplate(templateFile);
218:
219:                    // We check to see if the namespace requires a merge, and if so 
220:                    final Merger merger = Merger.instance();
221:                    if (merger.requiresMerge(this .namespace)) {
222:                        final String mergedTemplateLocation = this 
223:                                .getMergedTemplateLocation(templateFile);
224:                        final InputStream resource = template
225:                                .getResourceLoader().getResourceStream(
226:                                        templateFile);
227:                        ResourceWriter.instance().writeStringToFile(
228:                                merger
229:                                        .getMergedString(resource,
230:                                                this .namespace),
231:                                mergedTemplateLocation);
232:                        template = this .velocityEngine
233:                                .getTemplate(templateFile);
234:                        this .mergedTemplateFiles.add(new File(
235:                                mergedTemplateLocation));
236:                    }
237:                    this .discoveredTemplates.put(templateFile, template);
238:                }
239:                template.merge(velocityContext, output);
240:            }
241:
242:            /**
243:             * Loads the internal {@link #velocityContext} from the 
244:             * given Map of template objects.
245:             * 
246:             * @param a Map containing objects to add to the template context.
247:             */
248:            private final void loadVelocityContext(final Map templateObjects) {
249:                if (templateObjects != null && !templateObjects.isEmpty()) {
250:                    // copy the templateObjects to the velocityContext
251:                    if (templateObjects != null) {
252:                        for (final Iterator namesIterator = templateObjects
253:                                .keySet().iterator(); namesIterator.hasNext();) {
254:                            final String name = (String) namesIterator.next();
255:                            final Object value = templateObjects.get(name);
256:                            this .velocityContext.put(name, value);
257:                        }
258:                    }
259:                }
260:            }
261:
262:            /**
263:             * Gets location to which the given <code>templateName</code>
264:             * has its merged output written.
265:             * @param templatePath the relative path to the template.
266:             * @return the complete merged template location.
267:             */
268:            private String getMergedTemplateLocation(String templatePath) {
269:                return this .getMergedTemplatesLocation() + "/" + templatePath;
270:            }
271:
272:            /**
273:             * Gets the location to which merge templates are written.  These
274:             * must be written in order to replace the unmerged ones when Velocity
275:             * performs its template search.
276:             *
277:             * @return the merged templates location.
278:             */
279:            private String getMergedTemplatesLocation() {
280:                return TEMPORARY_TEMPLATE_LOCATION + "/" + this .namespace;
281:            }
282:
283:            /**
284:             * The log tag used for evaluation (this can be any abitrary name).
285:             */
286:            private static final String LOG_TAG = "logtag";
287:
288:            /**
289:             * @see org.andromda.core.templateengine.TemplateEngine#getEvaluatedExpression(java.lang.String, java.util.Map)
290:             */
291:            public String getEvaluatedExpression(final String expression,
292:                    final Map templateObjects) {
293:                String evaluatedExpression = null;
294:                if (StringUtils.isNotEmpty(expression)
295:                        && templateObjects != null
296:                        && !templateObjects.isEmpty()) {
297:                    if (this .velocityContext == null) {
298:                        this .velocityContext = new VelocityContext();
299:                        this .loadVelocityContext(templateObjects);
300:                    }
301:                    try {
302:                        final StringWriter writer = new StringWriter();
303:                        this .velocityEngine.evaluate(this .velocityContext,
304:                                writer, LOG_TAG, expression);
305:                        evaluatedExpression = writer.toString();
306:                    } catch (final Throwable throwable) {
307:                        throw new TemplateEngineException(throwable);
308:                    }
309:                }
310:                return evaluatedExpression;
311:            }
312:
313:            /**
314:             * @see org.andromda.core.templateengine.TemplateEngine#getMacroLibraries()
315:             */
316:            public List getMacroLibraries() {
317:                return this .macroLibraries;
318:            }
319:
320:            /**
321:             * @see org.andromda.core.templateengine.TemplateEngine#addMacroLibrary(java.lang.String)
322:             */
323:            public void addMacroLibrary(String libraryName) {
324:                this .macroLibraries.add(libraryName);
325:            }
326:
327:            /**
328:             * @see org.andromda.core.templateengine.TemplateEngine#setMergeLocation(java.lang.String)
329:             */
330:            public void setMergeLocation(String mergeLocation) {
331:                this .mergeLocation = mergeLocation;
332:            }
333:
334:            /**
335:             * @see org.andromda.core.templateengine.TemplateEngine#shutdown()
336:             */
337:            public void shutdown() {
338:                this .deleteMergedTemplatesLocation();
339:                this .discoveredTemplates.clear();
340:                this .velocityEngine = null;
341:            }
342:
343:            /**
344:             * Deletes the merged templates location (these
345:             * are the templates that were created just for merging
346:             * purposes and so therefore are no longer needed after
347:             * the engine is shutdown).
348:             */
349:            private final void deleteMergedTemplatesLocation() {
350:                File directory = new File(TEMPORARY_TEMPLATE_LOCATION);
351:                if (directory.getParentFile().isDirectory()) {
352:                    directory = directory.getParentFile();
353:                    ResourceUtils.deleteDirectory(directory);
354:                    directory.delete();
355:                }
356:            }
357:
358:            /**
359:             * Opens a log file for this namespace.
360:             *
361:             * @throws IOException if the file cannot be opened
362:             */
363:            private final void initLogger(final String pluginName)
364:                    throws IOException {
365:                logger = AndroMDALogger.getNamespaceLogger(pluginName);
366:                logger.setAdditivity(false);
367:
368:                final FileAppender appender = new FileAppender(
369:                        new PatternLayout("%-5p %d - %m%n"), AndroMDALogger
370:                                .getNamespaceLogFileName(pluginName), true);
371:                logger.addAppender(appender);
372:            }
373:
374:            /**
375:             * <p/>
376:             * This class receives log messages from VelocityTemplateEngine and forwards them to the concrete logger that is
377:             * configured for this cartridge. </p>
378:             * <p/>
379:             * This avoids creation of one large VelocityTemplateEngine log file where errors are difficult to find and track.
380:             * </p>
381:             * <p/>
382:             * Error messages can now be traced to plugin activities. </p>
383:             */
384:            private static class VelocityLoggingReceiver implements  LogSystem {
385:                /**
386:                 * @see org.apache.velocity.runtime.log.LogSystem#init(org.apache.velocity.runtime.RuntimeServices)
387:                 */
388:                public void init(RuntimeServices services) throws Exception {
389:                }
390:
391:                /**
392:                 * @see org.apache.velocity.runtime.log.LogSystem#logVelocityMessage(int, java.lang.String)
393:                 */
394:                public void logVelocityMessage(int level, String message) {
395:                    switch (level) {
396:                    case LogSystem.WARN_ID:
397:                        logger.info(message);
398:                        break;
399:                    case LogSystem.INFO_ID:
400:                        logger.info(message);
401:                        break;
402:                    case LogSystem.DEBUG_ID:
403:                        logger.debug(message);
404:                        break;
405:                    case LogSystem.ERROR_ID:
406:                        logger.info(message);
407:                        break;
408:                    default:
409:                        logger.debug(message);
410:                        break;
411:                    }
412:                }
413:            }
414:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.