001: package org.andromda.templateengines.freemarker;
002:
003: import java.io.IOException;
004: import java.io.StringReader;
005: import java.io.StringWriter;
006: import java.io.Writer;
007:
008: import java.util.ArrayList;
009: import java.util.Enumeration;
010: import java.util.HashMap;
011: import java.util.List;
012: import java.util.Map;
013:
014: import freemarker.template.Configuration;
015: import freemarker.template.ObjectWrapper;
016: import freemarker.template.Template;
017:
018: import org.andromda.core.common.AndroMDALogger;
019: import org.andromda.core.common.ExceptionUtils;
020: import org.andromda.core.templateengine.TemplateEngine;
021: import org.andromda.core.templateengine.TemplateEngineException;
022: import org.apache.log4j.Appender;
023: import org.apache.log4j.FileAppender;
024: import org.apache.log4j.Logger;
025: import org.apache.log4j.PatternLayout;
026:
027: /**
028: * The TemplateEngine implementation for the FreeMarker template processor.
029: *
030: * @author Chad Brandon
031: * @author Olaf Muliawan
032: * @see http://www.freemarker.org
033: */
034: public class FreeMarkerTemplateEngine implements TemplateEngine {
035: /**
036: * @see org.andromda.core.templateengine.TemplateEngine#init(java.lang.String)
037: */
038: public void initialize(String namespace) throws Exception {
039: this .initLogger(namespace);
040: }
041:
042: /**
043: * The main Configuration object of Freemarker.
044: */
045: protected Configuration configuration = null;
046:
047: /**
048: * @see org.andromda.core.templateengine.TemplateEngine#processTemplate(java.lang.String,
049: * java.util.Map, java.io.Writer)
050: */
051: public void processTemplate(String templateFile,
052: Map templateObjects, Writer output) throws Exception {
053: ExceptionUtils.checkEmpty("templateFile", templateFile);
054: ExceptionUtils.checkNull("output", output);
055:
056: if (this .configuration == null) {
057: this .configuration = new Configuration();
058:
059: // - tell FreeMarker it should use the classpath when searching for templates
060: this .configuration.setClassForTemplateLoading(
061: org.andromda.core.AndroMDA.class, "/");
062:
063: // - use Bean Wrapper, in order to get maximal reflection capabilities
064: this .configuration
065: .setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
066: }
067:
068: // - create the template
069: final Template template = this .configuration
070: .getTemplate(templateFile);
071:
072: if (templateObjects == null) {
073: templateObjects = new HashMap();
074: }
075:
076: // - merge data model with template
077: template.process(templateObjects, output);
078: }
079:
080: /**
081: * @see org.andromda.core.templateengine.TemplateEngine#shutdown()
082: */
083: public void shutdown() {
084: this .shutdownLogger();
085: this .configuration = null;
086: }
087:
088: /**
089: * Stores the macro libraries the template.
090: */
091: private List macroLibraries = new ArrayList();
092:
093: /**
094: * @see org.andromda.core.templateengine.TemplateEngine#getMacroLibraries()
095: */
096: public List getMacroLibraries() {
097: return this .macroLibraries;
098: }
099:
100: /**
101: * @see org.andromda.core.templateengine.TemplateEngine#addMacroLibrary(java.lang.String)
102: */
103: public void addMacroLibrary(String macroLibrary) {
104: this .macroLibraries.add(macroLibrary);
105: }
106:
107: /**
108: * @see org.andromda.core.templateengine.TemplateEngine#setMergeLocation(java.lang.String)
109: */
110: public void setMergeLocation(String mergeLocation) {
111: }
112:
113: /**
114: * The name of the temporary string template.
115: */
116: private static final String STRING_TEMPLATE = "stringTemplate";
117:
118: /**
119: * @see org.andromda.core.templateengine.TemplateEngine#getEvaluatedExpression(java.lang.String, java.util.Map)
120: */
121: public String getEvaluatedExpression(final String expression,
122: Map templateObjects) {
123: try {
124: // - create the template
125: final Template template = new Template(STRING_TEMPLATE,
126: new StringReader(expression), new Configuration());
127:
128: if (templateObjects == null) {
129: templateObjects = new HashMap();
130: }
131:
132: final StringWriter output = new StringWriter();
133:
134: // - merge data model with template
135: template.process(templateObjects, output);
136:
137: return output.toString();
138: } catch (final Throwable throwable) {
139: throw new TemplateEngineException(throwable);
140: }
141: }
142:
143: protected static Logger logger = null;
144:
145: /**
146: * Opens a log file for this plugin.
147: *
148: * @throws IOException if the file cannot be opened
149: */
150: private void initLogger(String pluginName) throws IOException {
151: logger = AndroMDALogger.getNamespaceLogger(pluginName);
152: logger.setAdditivity(false);
153: FileAppender appender = new FileAppender(new PatternLayout(
154: "%-5p %d - %m%n"), AndroMDALogger
155: .getNamespaceLogFileName(pluginName), true);
156: logger.addAppender(appender);
157: }
158:
159: /**
160: * Shutdown the associated logger.
161: */
162: private void shutdownLogger() {
163: Enumeration appenders = logger.getAllAppenders();
164: while (appenders.hasMoreElements()) {
165: Appender appender = (Appender) appenders.nextElement();
166: if (appender.getName() != null) {
167: appender.close();
168: }
169: }
170: }
171: }
|