2 * Copyright (C) 2001, 2002 The Mir-coders group
4 * This file is part of Mir.
6 * Mir is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Mir is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Mir; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * In addition, as a special exception, The Mir-coders gives permission to link
21 * the code of this program with the com.oreilly.servlet library, any library
22 * licensed under the Apache Software License, The Sun (tm) Java Advanced
23 * Imaging library (JAI), The Sun JIMI library (or with modified versions of
24 * the above that use the same license as the above), and distribute linked
25 * combinations including the two. You must obey the GNU General Public
26 * License in all respects for all of the code used other than the above
27 * mentioned libraries. If you modify this file, you may extend this exception
28 * to your version of the file, but you are not obligated to do so. If you do
29 * not wish to do so, delete this exception statement from your version.
34 import freemarker.template.*;
36 import mir.generator.*;
37 import mir.entity.Entity;
38 import mir.entity.EntityList;
39 import mir.storage.StorageObjectException;
40 import org.apache.struts.util.MessageResources;
42 import javax.servlet.http.HttpServletResponse;
43 import java.io.PrintWriter;
44 import java.net.URLEncoder;
49 * Hilfsklasse zum Mergen von Template und Daten
51 public final class HTMLTemplateProcessor {
53 public static String templateDir;
54 private static FileTemplateCache templateCache;
55 private static Logfile theLog;
56 private static String docRoot;
57 private static String actionRoot;
60 templateDir = MirConfig.getPropWithHome("HTMLTemplateProcessor.Dir");
61 templateCache = new FileTemplateCache(templateDir);
62 templateCache.setLoadingPolicy(templateCache.LOAD_ON_DEMAND);
63 // gone in freemarker 1.7.1: templateCache.startAutoUpdate();
64 theLog = Logfile.getInstance(MirConfig.getPropWithHome("HTMLTemplateProcessor.Logfile"));
66 docRoot = MirConfig.getProp("RootUri");
68 actionRoot = docRoot + MirConfig.getProp("Producer.ActionServlet");
69 } catch (ConfigException ce) {
70 // if Producer.ActionServlet is not set in the conf file
71 actionRoot = docRoot + "/Mir";
76 * empty private constructor, to avoid instantiation
78 private HTMLTemplateProcessor() {
82 // process-methods to merge different datastructures
83 // with freemarker templates
87 * Wandelt <code>anEntity</code> in freemarker-Struktur um, mischt die Daten mit
88 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
91 * @param templateFilename
94 * @exception HTMLParseException
97 public static void process(String templateFilename, Entity anEntity, PrintWriter out)
98 throws HTMLParseException {
100 throw new HTMLParseException("entity is empty!");
102 process(templateFilename, anEntity, out);
107 * Wandelt Liste mit Entities <code>entList</code> in freemarker-Struktur um, mischt die Daten mit
108 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
111 * @param templateFilename
114 * @exception HTMLParseException
116 public static void process(HttpServletResponse res, String templateFilename,
117 EntityList entList, PrintWriter out, Locale locale)
118 throws HTMLParseException {
119 process(res, templateFilename, entList, (String) null, (TemplateModelRoot) null, out, locale);
123 * Wandelt Entitylist in freemarker-Struktur um, fügt <code>additionalModel</code>
124 * unter dem Namen <code>additionalModelName</code> ein und mischt die Daten mit
125 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
128 * @param templateFilename
130 * @param additionalModelName
131 * @param additionalModel
133 * @exception HTMLParseException
135 public static void process(HttpServletResponse res, String templateFilename,
136 EntityList entList, String additionalModelName,
137 TemplateModelRoot additionalModel, PrintWriter out,
139 throws HTMLParseException {
141 SimpleHash modelRoot = new SimpleHash();
143 if (entList == null) {
144 process(null, templateFilename, modelRoot, out, locale);
147 modelRoot = makeSimpleHashWithEntitylistInfos(entList);
149 // Quickhack um mal ein Popup mit reinzunhemen ..
150 if (additionalModelName != null && additionalModel != null)
151 modelRoot.put(additionalModelName, additionalModel);
153 process(res, templateFilename, modelRoot, out, locale);
154 } catch (StorageObjectException e) {
155 throw new HTMLParseException(e.toString());
161 * Gibt Template <code>templateFilename</code> an den PrintWriter
164 * @param templateFilename
167 * @exception HTMLParseException
169 public static void process(String templateFilename, PrintWriter out,
171 throws HTMLParseException {
172 process(null, templateFilename, (TemplateModelRoot) null, out, locale);
177 * Mischt die freemarker-Struktur <code>tmr</code> mit
178 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
181 * @param templateFilename
184 * @exception HTMLParseException
186 public static void process(HttpServletResponse res, String templateFilename,
187 TemplateModelRoot tmr, PrintWriter out, Locale locale)
188 throws HTMLParseException {
189 process(res, templateFilename, tmr, null, out, locale, "bundles.admin");
194 * Mischt die freemarker-Struktur <code>tmr</code> mit
195 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
198 * @param templateFilename
201 * @exception HTMLParseException
203 public static void process(HttpServletResponse res, String templateFilename,
204 TemplateModelRoot tmr, TemplateModelRoot extra,
205 PrintWriter out, Locale locale, String bundles)
206 throws HTMLParseException {
207 if (out == null) throw new HTMLParseException("no outputstream");
208 Template tmpl = getTemplateFor(templateFilename);
209 if (tmpl == null) throw new HTMLParseException("no template: " + templateFilename);
210 if (tmr == null) tmr = new SimpleHash();
212 /** @todo what is this for? (rk) */
215 session = res.encodeURL("");
218 SimpleHash configHash = new SimpleHash();
220 // pass the whole config hash to the templates
221 Enumeration en = MirConfig.getResourceKeys();
223 while (en.hasMoreElements()) {
224 key = (String) en.nextElement();
225 configHash.put(key, new SimpleScalar(MirConfig.getProp(key)));
228 // this does not come directly from the config file
229 configHash.put("docRoot", new SimpleScalar(docRoot));
230 configHash.put("actionRoot", new SimpleScalar(actionRoot + session));
231 configHash.put("now", new SimpleScalar(StringUtil.date2readableDateTime(new GregorianCalendar())));
233 // this conform to updated freemarker syntax
234 configHash.put("compressWhitespace", new freemarker.template.utility.CompressWhitespace());
236 SimpleHash utilityHash = new SimpleHash();
238 utilityHash.put("compressWhitespace", new freemarker.template.utility.CompressWhitespace());
239 utilityHash.put("encodeURI", FreemarkerGenerator.makeAdapter(new GeneratorHTMLFunctions.encodeURIGeneratorFunction()));
240 utilityHash.put("encodeHTML", FreemarkerGenerator.makeAdapter(new GeneratorHTMLFunctions.encodeHTMLGeneratorFunction()));
241 utilityHash.put("isOdd", FreemarkerGenerator.makeAdapter(new GeneratorIntegerFunctions.isOddFunction()));
242 utilityHash.put("increment", FreemarkerGenerator.makeAdapter(new GeneratorIntegerFunctions.incrementFunction()));
244 catch (Throwable t) {
245 throw new HTMLParseException(t.getMessage());
249 SimpleHash outPutHash = new SimpleHash();
252 outPutHash.put("extra", extra);
254 while (((SimpleList) extra).hasNext()) {
255 theLog.printDebugInfo(((SimpleList) extra).next().toString());
257 } catch (Exception e) {
260 outPutHash.put("data", tmr);
261 outPutHash.put("config", configHash);
262 outPutHash.put("utility", utilityHash);
264 MessageResources messages = MessageResources.getMessageResources(bundles);
265 outPutHash.put("lang", new MessageMethodModel(locale, messages));
267 tmpl.process(outPutHash, out);
272 * Converts Entity-List to SimpleList of SimpleHashes.
273 * @param aList ist eine Liste von Entity
274 * @return eine freemarker.template.SimpleList von SimpleHashes.
276 * @deprecated EntityLists comply with TemplateListModel now.
278 public static SimpleList makeSimpleList(EntityList aList) throws StorageObjectException {
279 theLog.printWarning("## using deprecated makeSimpleList(entityList) - a waste of resources");
280 SimpleList simpleList = new SimpleList();
282 for (int i = 0; i < aList.size(); i++) {
283 simpleList.add(aList.elementAt(i));
290 * Konvertiert ein EntityList in ein freemarker.template.SimpleHash-Modell. Im Hash
291 * sind die einzelnen Entities ueber ihre id zu erreichen.
292 * @param aList ist die EntityList
293 * @return SimpleHash mit den entsprechenden freemarker Daten
296 public static SimpleHash makeSimpleHash(EntityList aList) throws StorageObjectException {
297 SimpleHash simpleHash = new SimpleHash();
298 Entity currentEntity;
301 for (int i = 0; i < aList.size(); i++) {
302 currentEntity = (Entity) aList.elementAt(i);
303 simpleHash.put(currentEntity.getId(), currentEntity);
310 * Konvertiert ein Hashtable mit den keys und values als String
311 * in ein freemarker.template.SimpleHash-Modell
312 * @param mergeData der HashMap mit den String / String Daten
313 * @return SimpleHash mit den entsprechenden freemarker Daten
316 public static SimpleHash makeSimpleHash(HashMap mergeData) {
317 SimpleHash modelRoot = new SimpleHash();
319 if (mergeData != null) {
320 Set set = mergeData.keySet();
321 Iterator it = set.iterator();
322 for (int i = 0; i < set.size(); i++) {
323 aField = (String) it.next();
324 modelRoot.put(aField, (String) mergeData.get(aField));
332 * Converts EntityList in SimpleHash and adds additional information
333 * to the returned SimpleHash
336 * @return SimpleHash returns SimpleHash with the converted EntityList plus
337 * additional Data about the list.
338 * @exception StorageObjectException
341 public static SimpleHash makeSimpleHashWithEntitylistInfos(EntityList entList) throws StorageObjectException {
342 SimpleHash modelRoot = new SimpleHash();
343 if (entList != null) {
344 modelRoot.put("contentlist", entList);
345 modelRoot.put("count", new SimpleScalar((new Integer(entList.getCount())).toString()));
346 if (entList.getWhere() != null) {
347 modelRoot.put("where", new SimpleScalar(entList.getWhere()));
348 modelRoot.put("where_encoded", new SimpleScalar(URLEncoder.encode(entList.getWhere())));
350 if (entList.getOrder() != null) {
351 modelRoot.put("order", new SimpleScalar(entList.getOrder()));
352 modelRoot.put("order_encoded", new SimpleScalar(URLEncoder.encode(entList.getOrder())));
354 modelRoot.put("from", new SimpleScalar((new Integer(entList.getFrom())).toString()));
355 modelRoot.put("to", new SimpleScalar((new Integer(entList.getTo())).toString()));
357 if (entList.hasNextBatch())
358 modelRoot.put("next", new SimpleScalar((new Integer(entList.getNextBatch())).toString()));
359 if (entList.hasPrevBatch())
360 modelRoot.put("prev", new SimpleScalar((new Integer(entList.getPrevBatch())).toString()));
366 * Private methods to get template from a templateFilename
367 * @param templateFilename
369 * @exception HTMLParseException
371 private static Template getTemplateFor(String templateFilename) throws HTMLParseException {
372 Template returnTemplate = null;
373 if (templateFilename != null)
374 returnTemplate = (Template) templateCache.getItem(templateFilename, "template");
377 if (returnTemplate == null) {
378 theLog.printError("CACHE (ERR): Unknown template: " + templateFilename);
379 throw new HTMLParseException("Templatefile: " + templateFilename + " not found.");
382 return returnTemplate;
385 public static void stopAutoUpdate() {
386 templateCache.stopAutoUpdate();
387 templateCache = null;