2 * Copyright (C) 2001, 2002 The Mir-coders group
\r
4 * This file is part of Mir.
\r
6 * Mir is free software; you can redistribute it and/or modify
\r
7 * it under the terms of the GNU General Public License as published by
\r
8 * the Free Software Foundation; either version 2 of the License, or
\r
9 * (at your option) any later version.
\r
11 * Mir is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License
\r
17 * along with Mir; if not, write to the Free Software
\r
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
20 * In addition, as a special exception, The Mir-coders gives permission to link
\r
21 * the code of this program with the com.oreilly.servlet library, any library
\r
22 * licensed under the Apache Software License, The Sun (tm) Java Advanced
\r
23 * Imaging library (JAI), The Sun JIMI library (or with modified versions of
\r
24 * the above that use the same license as the above), and distribute linked
\r
25 * combinations including the two. You must obey the GNU General Public
\r
26 * License in all respects for all of the code used other than the above
\r
27 * mentioned libraries. If you modify this file, you may extend this exception
\r
28 * to your version of the file, but you are not obligated to do so. If you do
\r
29 * not wish to do so, delete this exception statement from your version.
\r
34 import freemarker.template.*;
\r
36 import mir.generator.*;
\r
37 import mir.entity.Entity;
\r
38 import mir.entity.EntityList;
\r
39 import mir.storage.StorageObjectException;
\r
40 import org.apache.struts.util.MessageResources;
\r
42 import javax.servlet.http.HttpServletResponse;
\r
43 import java.io.PrintWriter;
\r
44 import java.net.URLEncoder;
\r
49 * Hilfsklasse zum Mergen von Template und Daten
\r
51 public final class HTMLTemplateProcessor {
\r
53 public static String templateDir;
\r
54 private static FileTemplateCache templateCache;
\r
55 private static Logfile theLog;
\r
56 private static String docRoot;
\r
57 private static String actionRoot;
\r
60 templateDir = MirConfig.getPropWithHome("HTMLTemplateProcessor.Dir");
\r
61 templateCache = new FileTemplateCache(templateDir);
\r
62 templateCache.setLoadingPolicy(templateCache.LOAD_ON_DEMAND);
\r
63 // gone in freemarker 1.7.1: templateCache.startAutoUpdate();
\r
64 theLog = Logfile.getInstance(MirConfig.getPropWithHome(
\r
65 "HTMLTemplateProcessor.Logfile"));
\r
67 docRoot = MirConfig.getProp("RootUri");
\r
69 actionRoot = docRoot + MirConfig.getProp("Producer.ActionServlet");
\r
71 catch (ConfigException ce) {
\r
72 // if Producer.ActionServlet is not set in the conf file
\r
73 actionRoot = docRoot + "/Mir";
\r
78 * empty private constructor, to avoid instantiation
\r
80 private HTMLTemplateProcessor() {
\r
83 // process-methods to merge different datastructures
\r
84 // with freemarker templates
\r
87 * Wandelt <code>anEntity</code> in freemarker-Struktur um, mischt die Daten mit
\r
88 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
\r
91 * @param templateFilename
\r
94 * @exception HTMLParseException
\r
97 public static void process(String templateFilename, Entity anEntity,
\r
98 PrintWriter out) throws HTMLParseException {
\r
99 if (anEntity == null)
\r
100 throw new HTMLParseException("entity is empty!");
\r
102 process(templateFilename, anEntity, out);
\r
106 * Wandelt Liste mit Entities <code>entList</code> in freemarker-Struktur um, mischt die Daten mit
\r
107 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
\r
110 * @param templateFilename
\r
113 * @exception HTMLParseException
\r
115 public static void process(HttpServletResponse res, String templateFilename,
\r
116 EntityList entList, PrintWriter out, Locale locale) throws HTMLParseException {
\r
117 process(res, templateFilename, entList, (String)null, (TemplateModelRoot)null,
\r
122 * Wandelt Entitylist in freemarker-Struktur um, fügt <code>additionalModel</code>
\r
123 * unter dem Namen <code>additionalModelName</code> ein und mischt die Daten mit
\r
124 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
\r
127 * @param templateFilename
\r
129 * @param additionalModelName
\r
130 * @param additionalModel
\r
132 * @exception HTMLParseException
\r
134 public static void process(HttpServletResponse res, String templateFilename,
\r
135 EntityList entList, String additionalModelName,
\r
136 TemplateModelRoot additionalModel, PrintWriter out,
\r
137 Locale locale) throws HTMLParseException {
\r
139 SimpleHash modelRoot = new SimpleHash();
\r
141 if (entList == null) {
\r
142 process(null, templateFilename, modelRoot, out, locale);
\r
146 modelRoot = makeSimpleHashWithEntitylistInfos(entList);
\r
148 // Quickhack um mal ein Popup mit reinzunhemen ..
\r
149 if (additionalModelName != null && additionalModel != null)
\r
150 modelRoot.put(additionalModelName, additionalModel);
\r
152 process(res, templateFilename, modelRoot, out, locale);
\r
154 catch (StorageObjectException e) {
\r
155 throw new HTMLParseException(e.toString());
\r
161 * Gibt Template <code>templateFilename</code> an den PrintWriter
\r
164 * @param templateFilename
\r
167 * @exception HTMLParseException
\r
169 public static void process(String templateFilename, PrintWriter out,
\r
170 Locale locale) throws HTMLParseException {
\r
171 process(null, templateFilename, (TemplateModelRoot)null, out, locale);
\r
175 * Mischt die freemarker-Struktur <code>tmr</code> mit
\r
176 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
\r
179 * @param templateFilename
\r
182 * @exception HTMLParseException
\r
184 public static void process(HttpServletResponse res, String templateFilename,
\r
185 TemplateModelRoot tmr, PrintWriter out,
\r
186 Locale locale) throws HTMLParseException {
\r
187 process(res, templateFilename, tmr, null, out, locale);
\r
190 public static void process(HttpServletResponse res, String templateFilename,
\r
191 TemplateModelRoot tmr, TemplateModelRoot extra,
\r
192 PrintWriter out, Locale locale) throws HTMLParseException {
\r
193 process(res, templateFilename, tmr, extra, out, locale, "bundles.adminlocal", "bundles.admin");
\r
196 public static void process(HttpServletResponse res, String templateFilename,
\r
197 TemplateModelRoot tmr, TemplateModelRoot extra, PrintWriter out,
\r
198 Locale locale, String bundles) throws HTMLParseException {
\r
199 process(res, templateFilename, tmr, extra, out, locale, bundles, null);
\r
203 * Mischt die freemarker-Struktur <code>tmr</code> mit
\r
204 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
\r
207 * @param templateFilename
\r
210 * @exception HTMLParseException
\r
212 public static void process(HttpServletResponse res, String templateFilename,
\r
213 TemplateModelRoot tmr, TemplateModelRoot extra,
\r
214 PrintWriter out, Locale locale, String bundles,
\r
215 String bundles2) throws
\r
216 HTMLParseException {
\r
218 throw new HTMLParseException("no outputstream");
\r
219 Template tmpl = getTemplateFor(templateFilename);
\r
221 throw new HTMLParseException("no template: " + templateFilename);
\r
223 tmr = new SimpleHash();
\r
225 /** @todo what is this for? (rk) */
\r
226 String session = "";
\r
228 session = res.encodeURL("");
\r
231 SimpleHash configHash = new SimpleHash();
\r
233 // pass the whole config hash to the templates
\r
234 Enumeration en = MirConfig.getResourceKeys();
\r
236 while (en.hasMoreElements()) {
\r
237 key = (String) en.nextElement();
\r
238 configHash.put(key, new SimpleScalar(MirConfig.getProp(key)));
\r
241 // this does not come directly from the config file
\r
242 configHash.put("docRoot", new SimpleScalar(docRoot));
\r
243 configHash.put("actionRoot", new SimpleScalar(actionRoot + session));
\r
244 configHash.put("now",
\r
245 new SimpleScalar(StringUtil.date2readableDateTime(new GregorianCalendar())));
\r
247 // this conform to updated freemarker syntax
\r
248 configHash.put("compressWhitespace",
\r
249 new freemarker.template.utility.CompressWhitespace());
\r
251 SimpleHash utilityHash = new SimpleHash();
\r
253 utilityHash.put("compressWhitespace",
\r
254 new freemarker.template.utility.CompressWhitespace());
\r
255 utilityHash.put("encodeURI",
\r
256 FreemarkerGenerator.makeAdapter(new GeneratorHTMLFunctions.
\r
257 encodeURIGeneratorFunction()));
\r
258 utilityHash.put("encodeHTML",
\r
259 FreemarkerGenerator.makeAdapter(new GeneratorHTMLFunctions.
\r
260 encodeHTMLGeneratorFunction()));
\r
261 utilityHash.put("isOdd",
\r
262 FreemarkerGenerator.makeAdapter(new GeneratorIntegerFunctions.
\r
264 utilityHash.put("increment",
\r
265 FreemarkerGenerator.makeAdapter(new GeneratorIntegerFunctions.
\r
266 incrementFunction()));
\r
268 catch (Throwable t) {
\r
269 throw new HTMLParseException(t.getMessage());
\r
272 SimpleHash outPutHash = new SimpleHash();
\r
274 if (extra != null) {
\r
275 outPutHash.put("extra", extra);
\r
277 while ( ( (SimpleList) extra).hasNext()) {
\r
278 theLog.printDebugInfo( ( (SimpleList) extra).next().toString());
\r
281 catch (Exception e) {
\r
284 outPutHash.put("data", tmr);
\r
285 outPutHash.put("config", configHash);
\r
286 outPutHash.put("utility", utilityHash);
\r
288 MessageResources messages = MessageResources.getMessageResources(bundles);
\r
289 if (bundles2!=null) {
\r
290 outPutHash.put("lang", new MessageMethodModel(locale, MessageResources.getMessageResources(bundles), MessageResources.getMessageResources(bundles2)));
\r
293 outPutHash.put("lang", new MessageMethodModel(locale, MessageResources.getMessageResources(bundles)));
\r
296 tmpl.process(outPutHash, out);
\r
300 * Converts Entity-List to SimpleList of SimpleHashes.
\r
301 * @param aList ist eine Liste von Entity
\r
302 * @return eine freemarker.template.SimpleList von SimpleHashes.
\r
304 * @deprecated EntityLists comply with TemplateListModel now.
\r
306 public static SimpleList makeSimpleList(EntityList aList) throws
\r
307 StorageObjectException {
\r
308 theLog.printWarning(
\r
309 "## using deprecated makeSimpleList(entityList) - a waste of resources");
\r
310 SimpleList simpleList = new SimpleList();
\r
311 if (aList != null) {
\r
312 for (int i = 0; i < aList.size(); i++) {
\r
313 simpleList.add(aList.elementAt(i));
\r
320 * Konvertiert ein EntityList in ein freemarker.template.SimpleHash-Modell. Im Hash
\r
321 * sind die einzelnen Entities ueber ihre id zu erreichen.
\r
322 * @param aList ist die EntityList
\r
323 * @return SimpleHash mit den entsprechenden freemarker Daten
\r
326 public static SimpleHash makeSimpleHash(EntityList aList) throws
\r
327 StorageObjectException {
\r
328 SimpleHash simpleHash = new SimpleHash();
\r
329 Entity currentEntity;
\r
331 if (aList != null) {
\r
332 for (int i = 0; i < aList.size(); i++) {
\r
333 currentEntity = (Entity) aList.elementAt(i);
\r
334 simpleHash.put(currentEntity.getId(), currentEntity);
\r
341 * Konvertiert ein Hashtable mit den keys und values als String
\r
342 * in ein freemarker.template.SimpleHash-Modell
\r
343 * @param mergeData der HashMap mit den String / String Daten
\r
344 * @return SimpleHash mit den entsprechenden freemarker Daten
\r
347 public static SimpleHash makeSimpleHash(HashMap mergeData) {
\r
348 SimpleHash modelRoot = new SimpleHash();
\r
350 if (mergeData != null) {
\r
351 Set set = mergeData.keySet();
\r
352 Iterator it = set.iterator();
\r
353 for (int i = 0; i < set.size(); i++) {
\r
354 aField = (String) it.next();
\r
355 modelRoot.put(aField, (String) mergeData.get(aField));
\r
362 * Converts EntityList in SimpleHash and adds additional information
\r
363 * to the returned SimpleHash
\r
366 * @return SimpleHash returns SimpleHash with the converted EntityList plus
\r
367 * additional Data about the list.
\r
368 * @exception StorageObjectException
\r
371 public static SimpleHash makeSimpleHashWithEntitylistInfos(EntityList entList) throws
\r
372 StorageObjectException {
\r
373 SimpleHash modelRoot = new SimpleHash();
\r
374 if (entList != null) {
\r
375 modelRoot.put("contentlist", entList);
\r
376 modelRoot.put("count",
\r
377 new SimpleScalar( (new Integer(entList.getCount())).toString()));
\r
378 if (entList.getWhere() != null) {
\r
379 modelRoot.put("where", new SimpleScalar(entList.getWhere()));
\r
380 modelRoot.put("where_encoded",
\r
381 new SimpleScalar(URLEncoder.encode(entList.getWhere())));
\r
383 if (entList.getOrder() != null) {
\r
384 modelRoot.put("order", new SimpleScalar(entList.getOrder()));
\r
385 modelRoot.put("order_encoded",
\r
386 new SimpleScalar(URLEncoder.encode(entList.getOrder())));
\r
388 modelRoot.put("from",
\r
389 new SimpleScalar( (new Integer(entList.getFrom())).toString()));
\r
390 modelRoot.put("to",
\r
391 new SimpleScalar( (new Integer(entList.getTo())).toString()));
\r
393 if (entList.hasNextBatch())
\r
394 modelRoot.put("next",
\r
395 new SimpleScalar( (new Integer(entList.getNextBatch())).
\r
397 if (entList.hasPrevBatch())
\r
398 modelRoot.put("prev",
\r
399 new SimpleScalar( (new Integer(entList.getPrevBatch())).
\r
406 * Private methods to get template from a templateFilename
\r
407 * @param templateFilename
\r
409 * @exception HTMLParseException
\r
411 private static Template getTemplateFor(String templateFilename) throws
\r
412 HTMLParseException {
\r
413 Template returnTemplate = null;
\r
414 if (templateFilename != null)
\r
415 returnTemplate = (Template) templateCache.getItem(templateFilename,
\r
418 if (returnTemplate == null) {
\r
419 theLog.printError("CACHE (ERR): Unknown template: " + templateFilename);
\r
420 throw new HTMLParseException("Templatefile: " + templateFilename +
\r
424 return returnTemplate;
\r
427 public static void stopAutoUpdate() {
\r
428 templateCache.stopAutoUpdate();
\r
429 templateCache = null;
\r