/* * Copyright 2007 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.omnytex; import freemarker.cache.ClassTemplateLoader; import freemarker.template.Configuration; import freemarker.template.DefaultObjectWrapper; import freemarker.template.Template; import java.io.StringWriter; import java.io.Writer; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * The Freemarker class is a class you remote with DWR which accepts input * data, and the name of a Freemarker template, and it generates output using * that template and data. To use it, add this to your dwr.xml file: * <br><br> * <allow><br> *   ...<br> *   <convert converter="bean" match="com.omnytex.FreemarkerData" * /><br> *   <create creator="new" javascript="Freemarker"><br> *     <param name="class" value="com.omnytex.Freemarker" * /><br> *   </create><br> *   ...<br> * </allow><br> * <signatures><br> *   <![CDATA[<br> *   import java.util.Map;<br> *   import com.omnytex.FreemarkerData;<br> *   FreemarkerData.setMapData(final Map<String, Map> * inMapData);<br> *   ]]><br> * </signatures><br> * <br><br> * Then, call it using this form: * <br><br> * var d = *   { template : "aaaaa", *     rootData : { bbbbb : ccccc, ... }, *     mapData : { *       xxxxx : { yyyyy : "zzzzz", ... }, ... *     } *   }; * Freemarker.run(d, callback ); * <br><br> * Where: * <br> * <ul> * <li><b>aaaaa</b> is the fully-qualified name of the Freemarker template to * execute. This template must be in the classpath, and you must use slashes * to specify it rather than dot notation. For example: com/omnytex/test/ftl * </li> * <li><b>bbbbb</b> is zero or more data elements to be placed at the root of * the Freemarker data model (<b>ccccc</b> is the value of the element) * </li> * <li>xxxxx</b> is the key for zero or more Map elements to be inserted into * the Freemarker data model (<b>yyyyy</b> is the key of an alement in the Map, * and <b>zzzzz</b> is the value fo that element) * </li> * </ul> * If you are unfamiliar with the Freemarker data model, please read the * Freemarker documentation. But, in short, it is a tree structure with leaves * directly off the root, and/or a collection of Maps off the root. * * @author <a href="mailto:fzammetti@omnytex.com">Frank W. Zammetti</a> */ public class Freemarker { /** * Log instance. */ private static Log log = LogFactory.getLog(Freemarker.class); /** * The run() is called to execute a Freemarker template. * * @param inData The FreemarkerData object populated from the incoming * data from the client. * @return The results of executing the template. * @throws Exception If anything goes wrong. */ public String run(FreemarkerData inData) throws Exception { log.trace("Freemarker.run() entry"); if (log.isDebugEnabled()) { log.debug(("inData = " + inData)); } // Create our data model. Map root = new HashMap(); // First, iterate over the data that will go directly into the root and // insert it now. Map rootData = inData.getRootData(); for (Iterator it = rootData.keySet().iterator(); it.hasNext();) { String nextKey = (String)it.next(); root.put(nextKey, rootData.get(nextKey)); } if (log.isDebugEnabled()) { log.debug(("root = " + root)); } // Next, iterate over the data that consists of Maps and insert it all // into the root. Map mapData = inData.getMapData(); for (Iterator it = mapData.keySet().iterator(); it.hasNext();) { String nextKey = (String)it.next(); root.put(nextKey, mapData.get(nextKey)); } if (log.isDebugEnabled()) { log.debug(("root = " + root)); } // Set up Freemarker. Configuration fmConfig = new Configuration(); fmConfig.setObjectWrapper(new DefaultObjectWrapper()); fmConfig.setTemplateLoader(new ClassTemplateLoader( new Freemarker().getClass(), "/")); // Read in the Freemarker template specified. Template template = null; try { template = fmConfig.getTemplate(inData.getTemplate()); } catch (Exception e) { log.error("Could not load Freemarker template " + inData.getTemplate() + "... is it in the classpath in the " + "expected location? Is the template value passed in " + "fully-qualified? (Error: " + e); return "error"; } // Generate the output. Writer out = new StringWriter(); template.process(root, out); out.flush(); if (log.isDebugEnabled()) { log.debug("Generated output = " + out); } // Return output. log.trace("Freemarker.run() exit"); return out.toString(); } // End run(). } // End class.