View Javadoc
1   /**
2    * Copyright 2005-2015 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krms.impl.repository.language;
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 }
195