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 * Wandelt HashMap <code>mergeData</code> in freemarker-Struktur und mischt diese mit
162 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
165 * @param templateFilename
166 * @param mergeData - a HashMap with mergeData to be converted in SimpleHash
168 * @exception HTMLParseException
170 public static void process(HttpServletResponse res, String templateFilename,
171 HashMap mergeData, PrintWriter out, Locale locale)
172 throws HTMLParseException {
173 process(res, templateFilename, makeSimpleHash(mergeData), out, locale);
177 * Gibt Template <code>templateFilename</code> an den PrintWriter
180 * @param templateFilename
183 * @exception HTMLParseException
185 public static void process(String templateFilename, PrintWriter out,
187 throws HTMLParseException {
188 process(null, templateFilename, (TemplateModelRoot) null, out, locale);
193 * Mischt die freemarker-Struktur <code>tmr</code> mit
194 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
197 * @param templateFilename
200 * @exception HTMLParseException
202 public static void process(HttpServletResponse res, String templateFilename,
203 TemplateModelRoot tmr, PrintWriter out, Locale locale)
204 throws HTMLParseException {
205 process(res, templateFilename, tmr, null, out, locale, "bundles.admin");
210 * Mischt die freemarker-Struktur <code>tmr</code> mit
211 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
214 * @param templateFilename
217 * @exception HTMLParseException
219 public static void process(HttpServletResponse res, String templateFilename,
220 TemplateModelRoot tmr, TemplateModelRoot extra,
221 PrintWriter out, Locale locale, String bundles)
222 throws HTMLParseException {
223 if (out == null) throw new HTMLParseException("no outputstream");
224 Template tmpl = getTemplateFor(templateFilename);
225 if (tmpl == null) throw new HTMLParseException("no template: " + templateFilename);
226 if (tmr == null) tmr = new SimpleHash();
228 /** @todo what is this for? (rk) */
231 session = res.encodeURL("");
234 SimpleHash configHash = new SimpleHash();
236 // pass the whole config hash to the templates
237 Enumeration en = MirConfig.getResourceKeys();
239 while (en.hasMoreElements()) {
240 key = (String) en.nextElement();
241 configHash.put(key, new SimpleScalar(MirConfig.getProp(key)));
244 // this does not come directly from the config file
245 configHash.put("docRoot", new SimpleScalar(docRoot));
246 configHash.put("actionRoot", new SimpleScalar(actionRoot + session));
247 configHash.put("now", new SimpleScalar(StringUtil.date2readableDateTime(new GregorianCalendar())));
249 // this conform to updated freemarker syntax
250 configHash.put("compressWhitespace", new freemarker.template.utility.CompressWhitespace());
252 SimpleHash utilityHash = new SimpleHash();
254 utilityHash.put("compressWhitespace", new freemarker.template.utility.CompressWhitespace());
255 utilityHash.put("encodeURI", FreemarkerGenerator.makeAdapter(new GeneratorHTMLFunctions.encodeURIGeneratorFunction()));
256 utilityHash.put("encodeHTML", FreemarkerGenerator.makeAdapter(new GeneratorHTMLFunctions.encodeHTMLGeneratorFunction()));
258 catch (Throwable t) {
259 throw new HTMLParseException(t.getMessage());
263 SimpleHash outPutHash = new SimpleHash();
266 outPutHash.put("extra", extra);
268 while (((SimpleList) extra).hasNext()) {
269 theLog.printDebugInfo(((SimpleList) extra).next().toString());
271 } catch (Exception e) {
274 outPutHash.put("data", tmr);
275 outPutHash.put("config", configHash);
276 outPutHash.put("utility", utilityHash);
278 MessageResources messages = MessageResources.getMessageResources(bundles);
279 outPutHash.put("lang", new MessageMethodModel(locale, messages));
281 tmpl.process(outPutHash, out);
286 * Converts Entity-List to SimpleList of SimpleHashes.
287 * @param aList ist eine Liste von Entity
288 * @return eine freemarker.template.SimpleList von SimpleHashes.
290 * @deprecated EntityLists comply with TemplateListModel now.
292 public static SimpleList makeSimpleList(EntityList aList) throws StorageObjectException {
293 theLog.printWarning("## using deprecated makeSimpleList(entityList) - a waste of resources");
294 SimpleList simpleList = new SimpleList();
296 for (int i = 0; i < aList.size(); i++) {
297 simpleList.add(aList.elementAt(i));
304 * Konvertiert ein EntityList in ein freemarker.template.SimpleHash-Modell. Im Hash
305 * sind die einzelnen Entities ueber ihre id zu erreichen.
306 * @param aList ist die EntityList
307 * @return SimpleHash mit den entsprechenden freemarker Daten
310 public static SimpleHash makeSimpleHash(EntityList aList) throws StorageObjectException {
311 SimpleHash simpleHash = new SimpleHash();
312 Entity currentEntity;
315 for (int i = 0; i < aList.size(); i++) {
316 currentEntity = (Entity) aList.elementAt(i);
317 simpleHash.put(currentEntity.getId(), currentEntity);
324 * Konvertiert ein Entity in ein freemarker.template.SimpleHash-Modell
325 * @param entity ist die Entity
326 * @return SimpleHash mit den entsprechenden freemarker Daten
328 * @deprecated This method is deprecated and will be deleted in the next
329 * release. Entity interfaces freemarker.template.TemplateHashModel now
330 * and can be used in the same way as SimpleHash. It is not necessary any
331 * more to make a SimpleHash from an Entity
333 public static SimpleHash makeSimpleHash(Entity entity) {
334 if (entity != null) {
335 theLog.printWarning("## using deprecated makeSimpleHash(entity) - a waste of resources");
336 return makeSimpleHash(entity.getValues());
342 * Konvertiert ein Hashtable mit den keys und values als String
343 * in ein freemarker.template.SimpleHash-Modell
344 * @param mergeData der HashMap mit den String / String Daten
345 * @return SimpleHash mit den entsprechenden freemarker Daten
348 public static SimpleHash makeSimpleHash(HashMap mergeData) {
349 SimpleHash modelRoot = new SimpleHash();
351 if (mergeData != null) {
352 Set set = mergeData.keySet();
353 Iterator it = set.iterator();
354 for (int i = 0; i < set.size(); i++) {
355 aField = (String) it.next();
356 modelRoot.put(aField, (String) mergeData.get(aField));
364 * Converts EntityList in SimpleHash and adds additional information
365 * to the returned SimpleHash
368 * @return SimpleHash returns SimpleHash with the converted EntityList plus
369 * additional Data about the list.
370 * @exception StorageObjectException
373 public static SimpleHash makeSimpleHashWithEntitylistInfos(EntityList entList) throws StorageObjectException {
374 SimpleHash modelRoot = new SimpleHash();
375 if (entList != null) {
376 modelRoot.put("contentlist", entList);
377 modelRoot.put("count", new SimpleScalar((new Integer(entList.getCount())).toString()));
378 if (entList.getWhere() != null) {
379 modelRoot.put("where", new SimpleScalar(entList.getWhere()));
380 modelRoot.put("where_encoded", new SimpleScalar(URLEncoder.encode(entList.getWhere())));
382 if (entList.getOrder() != null) {
383 modelRoot.put("order", new SimpleScalar(entList.getOrder()));
384 modelRoot.put("order_encoded", new SimpleScalar(URLEncoder.encode(entList.getOrder())));
386 modelRoot.put("from", new SimpleScalar((new Integer(entList.getFrom())).toString()));
387 modelRoot.put("to", new SimpleScalar((new Integer(entList.getTo())).toString()));
389 if (entList.hasNextBatch())
390 modelRoot.put("next", new SimpleScalar((new Integer(entList.getNextBatch())).toString()));
391 if (entList.hasPrevBatch())
392 modelRoot.put("prev", new SimpleScalar((new Integer(entList.getPrevBatch())).toString()));
398 * Private methods to get template from a templateFilename
399 * @param templateFilename
401 * @exception HTMLParseException
403 private static Template getTemplateFor(String templateFilename) throws HTMLParseException {
404 Template returnTemplate = null;
405 if (templateFilename != null)
406 returnTemplate = (Template) templateCache.getItem(templateFilename, "template");
409 if (returnTemplate == null) {
410 theLog.printError("CACHE (ERR): Unknown template: " + templateFilename);
411 throw new HTMLParseException("Templatefile: " + templateFilename + " not found.");
414 return returnTemplate;
417 public static void stopAutoUpdate() {
418 templateCache.stopAutoUpdate();
419 templateCache = null;