1 /**
2 * Copyright 2010 The Kuali Foundation Licensed under the
3 * Educational Community License, Version 2.0 (the "License"); you may
4 * not use this file except in compliance with the License. You may
5 * obtain a copy of the License at
6 *
7 * http://www.osedu.org/licenses/ECL-2.0
8 *
9 * Unless required by applicable law or agreed to in writing,
10 * software distributed under the License is distributed on an "AS IS"
11 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12 * or implied. See the License for the specific language governing
13 * permissions and limitations under the License.
14 */
15
16 package org.kuali.student.common.util;
17
18 import java.io.BufferedReader;
19 import java.io.IOException;
20 import java.io.Reader;
21 import java.io.StringReader;
22 import java.io.StringWriter;
23 import java.util.HashMap;
24 import java.util.Map;
25
26 import org.apache.velocity.VelocityContext;
27 import org.apache.velocity.app.VelocityEngine;
28 import org.apache.velocity.exception.VelocityException;
29 import org.apache.velocity.tools.generic.ComparisonDateTool;
30 import org.apache.velocity.tools.generic.DateTool;
31 import org.apache.velocity.tools.generic.MathTool;
32 import org.apache.velocity.tools.generic.NumberTool;
33 import org.apache.velocity.tools.generic.SortTool;
34
35 /**
36 * Velocity template engine.
37 * <p>Velocity tools supported (See <a href="http://velocity.apache.org/tools/devel/generic.html">http://velocity.apache.org/tools/devel/generic.html<a/>}:</p>
38 * <ul>
39 * <li><a href="http://velocity.apache.org/tools/devel/javadoc/org/apache/velocity/tools/generic/DateTool.html">DateTool</a></li>
40 * <li><a href="http://velocity.apache.org/tools/devel/javadoc/org/apache/velocity/tools/generic/ComparisonDateTool.html">ComparisonDateTool</a></li>
41 * <li><a href="http://velocity.apache.org/tools/devel/javadoc/org/apache/velocity/tools/generic/MathTool.html">MathTool</a></li>
42 * <li><a href="http://velocity.apache.org/tools/devel/javadoc/org/apache/velocity/tools/generic/NumberTool.html">NumberTool</a></li>
43 * <li><a href="http://velocity.apache.org/tools/devel/javadoc/org/apache/velocity/tools/generic/SortTool.html">SortTool</a></li>
44 * </ul>
45 *
46 * Examples:
47 * <pre>
48 * $dateTool: <code>$dateTool.get('yyyy-M-d H:m:s') -> 2003-10-19 21:54:50</code>
49 *
50 * $dateComparisonTool: <code>$dateComparisonTool.difference('2005-07-04','2007-02-15').abbr -> 1 yr</code>
51 *
52 * $mathTool: <code>$mathTool.toNumber($value) -> Converts java.lang.String $value to a java.lang.Number</code>
53 *
54 * $numberTool: <code>$numberTool.currency($myNumber) -> $13.55</code>
55 *
56 * $sortTool: <code>$sorter.sort($collection, "name:asc") -> Sorts $collection with property 'name' in ascending order</code>
57 * </pre>
58 */
59 public class VelocityTemplateEngine {
60
61 private final VelocityEngine velocityEngine = new VelocityEngine();
62 private VelocityContext defaultContext;
63 private Map<String,Object> configMap = new HashMap<String, Object>();
64
65 /**
66 * Constructs a velocity template engine.
67 */
68 public VelocityTemplateEngine() {
69 init();
70 }
71
72 /**
73 * Constructs a velocity template engine with velocity tools configurations.
74 *
75 * @param config Velocity tools configurations
76 */
77 public VelocityTemplateEngine(final Map<String,Object> config) {
78 this.configMap = config;
79 init();
80 }
81
82 /**
83 * Initializes Velocity engine
84 */
85 private void init() {
86 velocityEngine.setProperty(VelocityEngine.RESOURCE_LOADER, "class");
87 velocityEngine.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
88 setLogFile();
89
90 DateTool dateTool = new DateTool();
91 dateTool.configure(this.configMap);
92 MathTool mathTool = new MathTool();
93 NumberTool numberTool = new NumberTool();
94 numberTool.configure(this.configMap);
95 SortTool sortTool = new SortTool();
96
97 defaultContext = new VelocityContext();
98 defaultContext.put("dateTool", dateTool);
99 defaultContext.put("dateComparisonTool", new ComparisonDateTool());
100 defaultContext.put("mathTool", mathTool);
101 defaultContext.put("numberTool", numberTool);
102 defaultContext.put("sortTool", sortTool);
103 // Following tools need VelocityTools version 2.0+
104 //defaultContext.put("displayTool", new DisplayTool());
105 //defaultContext.put("xmlTool", new XmlTool());
106
107 try {
108 velocityEngine.init();
109 } catch (Exception e) {
110 throw new VelocityException(e);
111 }
112 }
113
114 /**
115 * Sets logging on or off.
116 *
117 * @param enableLogging True enables logging; false disables logging
118 */
119 public void setLogging(boolean enableLogging) {
120 if (!enableLogging) {
121 // Line below to disables logging, remove to enable
122 velocityEngine.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.NullLogSystem");
123 } else {
124 velocityEngine.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS, null);
125 setLogFile();
126 }
127 }
128
129 /**
130 * Sets the Velocity Log File to the default location. Either
131 * <code>{catalina.base}/velocity.log</code> or <code>target/velocity.log</code>.
132 */
133 public void setLogFile() {
134 if (System.getProperty("catalina.base") != null) {
135 setLogFile(System.getProperty("catalina.base") + "/logs/velocity.log");
136 } else {
137 setLogFile("target/velocity.log");
138 }
139 }
140
141 /**
142 * Sets the Velocity Log File.
143 *
144 * @param logFile the path and filename for velocity logging
145 */
146 public void setLogFile(final String logfile) {
147 velocityEngine.setProperty(VelocityEngine.RUNTIME_LOG, logfile);
148 }
149
150 /**
151 * Evaluates a template with a map of objects. <code>contextMap</code> can
152 * be null if no keys/tokens are referenced in the <code>template</code>
153 *
154 * @param contextMap Map of objects to be used in the template
155 * @param template Velocity Template
156 * @return Evaluated template
157 */
158 public String evaluate(final Map<String, Object> contextMap, final String template) throws VelocityException {
159 Reader readerOut = null;
160 try {
161 readerOut = new BufferedReader(new StringReader(template));
162 return evaluate(contextMap, readerOut);
163 } finally {
164 if(readerOut != null) {
165 try {
166 readerOut.close();
167 } catch (IOException e) {
168 throw new VelocityException(e);
169 }
170
171 }
172 }
173 }
174
175 /**
176 * Evaluates a template with a map of objects.
177 *
178 * @param mapContext Map of Objects to be used in the template
179 * @param template Velocity Template
180 * @return Evaluated template
181 */
182 public String evaluate(final Map<String, Object> mapContext, final Reader template) throws VelocityException {
183 VelocityContext context = new VelocityContext(mapContext, defaultContext);
184
185 StringWriter writerOut = new StringWriter();
186 try {
187 velocityEngine.evaluate(context, writerOut, "VelocityEngine", template);
188 return writerOut.toString();
189 } catch(Exception e) {
190 throw new VelocityException(e);
191 }
192 }
193
194 }