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.config.MirPropertiesConfiguration;
\r
38 import mir.config.MirPropertiesConfiguration.PropertiesConfigExc;
\r
39 import mir.entity.Entity;
\r
40 import mir.entity.EntityList;
\r
41 import mir.storage.StorageObjectFailure;
\r
42 import org.apache.struts.util.MessageResources;
\r
44 import javax.servlet.http.HttpServletResponse;
\r
45 import java.io.PrintWriter;
\r
46 import java.net.URLEncoder;
\r
51 * Hilfsklasse zum Mergen von Template und Daten
\r
53 public final class HTMLTemplateProcessor {
\r
55 public static String templateDir;
\r
56 private static MirPropertiesConfiguration configuration;
\r
57 private static FileTemplateCache templateCache;
\r
58 private static Logfile theLog;
\r
59 private static String docRoot;
\r
60 private static String actionRoot;
\r
64 configuration = MirPropertiesConfiguration.instance();
\r
65 } catch (PropertiesConfigExc e) {
\r
66 e.printStackTrace();
\r
68 theLog = Logfile.getInstance(
\r
69 configuration.getStringWithHome("HTMLTemplateProcessor.Logfile"));
\r
71 configuration.getStringWithHome("HTMLTemplateProcessor.Dir");
\r
72 theLog.printDebugInfo("templateDir: " + templateDir);
\r
73 templateCache = new FileTemplateCache(templateDir);
\r
74 templateCache.setLoadingPolicy(FileTemplateCache.LOAD_ON_DEMAND);
\r
75 // gone in freemarker 1.7.1: templateCache.startAutoUpdate();
\r
78 docRoot = configuration.getString("RootUri");
\r
80 actionRoot = docRoot +configuration.getString("Producer.ActionServlet");
\r
82 catch (ConfigException ce) {
\r
83 // if Producer.ActionServlet is not set in the conf file
\r
84 actionRoot = docRoot + "/Mir";
\r
89 * empty private constructor, to avoid instantiation
\r
91 private HTMLTemplateProcessor() {
\r
94 // process-methods to merge different datastructures
\r
95 // with freemarker templates
\r
98 * Wandelt <code>anEntity</code> in freemarker-Struktur um, mischt die Daten mit
\r
99 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
\r
102 * @param templateFilename
\r
105 * @exception HTMLParseException
\r
108 public static void process(String templateFilename, Entity anEntity,
\r
109 PrintWriter out) throws HTMLParseException {
\r
110 if (anEntity == null)
\r
111 throw new HTMLParseException("entity is empty!");
\r
113 process(templateFilename, anEntity, out);
\r
117 * Wandelt Liste mit Entities <code>entList</code> in freemarker-Struktur um, mischt die Daten mit
\r
118 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
\r
121 * @param templateFilename
\r
124 * @exception HTMLParseException
\r
126 public static void process(HttpServletResponse res, String templateFilename,
\r
127 EntityList entList, PrintWriter out, Locale locale) throws HTMLParseException {
\r
128 process(res, templateFilename, entList, (String)null, (TemplateModelRoot)null,
\r
133 * Wandelt Entitylist in freemarker-Struktur um, f?gt <code>additionalModel</code>
\r
134 * unter dem Namen <code>additionalModelName</code> ein und mischt die Daten mit
\r
135 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
\r
138 * @param templateFilename
\r
140 * @param additionalModelName
\r
141 * @param additionalModel
\r
143 * @exception HTMLParseException
\r
146 public static void process(HttpServletResponse res, String templateFilename,
\r
147 EntityList entList, String additionalModelName,
\r
148 TemplateModelRoot additionalModel, PrintWriter out,
\r
149 Locale locale) throws HTMLParseException {
\r
151 SimpleHash modelRoot = new SimpleHash();
\r
153 if (entList == null) {
\r
154 process(null, templateFilename, modelRoot, out, locale);
\r
158 modelRoot = makeSimpleHashWithEntitylistInfos(entList);
\r
160 // Quickhack um mal ein Popup mit reinzunhemen ..
\r
161 if (additionalModelName != null && additionalModel != null)
\r
162 modelRoot.put(additionalModelName, additionalModel);
\r
164 process(res, templateFilename, modelRoot, out, locale);
\r
166 catch (StorageObjectFailure e) {
\r
167 throw new HTMLParseException(e.toString());
\r
174 * Gibt Template <code>templateFilename</code> an den PrintWriter
\r
177 * @param templateFilename
\r
180 * @exception HTMLParseException
\r
182 public static void process(String templateFilename, PrintWriter out,
\r
183 Locale locale) throws HTMLParseException {
\r
184 process(null, templateFilename, (TemplateModelRoot)null, out, locale);
\r
188 * Mischt die freemarker-Struktur <code>tmr</code> mit
\r
189 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
\r
192 * @param templateFilename
\r
195 * @exception HTMLParseException
\r
197 public static void process(HttpServletResponse res, String templateFilename,
\r
198 TemplateModelRoot tmr, PrintWriter out,
\r
199 Locale locale) throws HTMLParseException {
\r
200 process(res, templateFilename, tmr, null, out, locale);
\r
203 public static void process(HttpServletResponse res, String templateFilename,
\r
204 TemplateModelRoot tmr, TemplateModelRoot extra,
\r
205 PrintWriter out, Locale locale) throws HTMLParseException {
\r
206 process(res, templateFilename, tmr, extra, out, locale, "bundles.adminlocal", "bundles.admin");
\r
209 public static void process(HttpServletResponse res, String templateFilename,
\r
210 TemplateModelRoot tmr, TemplateModelRoot extra, PrintWriter out,
\r
211 Locale locale, String bundles) throws HTMLParseException {
\r
212 process(res, templateFilename, tmr, extra, out, locale, bundles, null);
\r
216 * Mischt die freemarker-Struktur <code>tmr</code> mit
\r
217 * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
\r
220 * @param templateFilename
\r
223 * @exception HTMLParseException
\r
225 public static void process(HttpServletResponse res, String templateFilename,
\r
226 TemplateModelRoot tmr, TemplateModelRoot extra,
\r
227 PrintWriter out, Locale locale, String bundles,
\r
228 String bundles2) throws
\r
229 HTMLParseException {
\r
231 throw new HTMLParseException("no outputstream");
\r
232 Template tmpl = getTemplateFor(templateFilename);
\r
234 throw new HTMLParseException("no template: " + templateFilename);
\r
236 tmr = new SimpleHash();
\r
238 /** @todo what is this for? (rk) */
\r
239 String session = "";
\r
241 session = res.encodeURL("");
\r
244 SimpleHash configHash = new SimpleHash();
\r
246 // pass the whole config hash to the templates
\r
247 Iterator it = configuration.getKeys();
\r
249 while (it.hasNext()) {
\r
250 key = (String) it.next();
\r
251 configHash.put(key, new SimpleScalar(
\r
252 configuration.getString(key))
\r
256 // this does not come directly from the config file
\r
257 configHash.put("docRoot", new SimpleScalar(docRoot));
\r
258 configHash.put("actionRoot", new SimpleScalar(actionRoot + session));
\r
259 configHash.put("now",
\r
260 new SimpleScalar(StringUtil.date2readableDateTime(new GregorianCalendar())));
\r
262 // this conform to updated freemarker syntax
\r
263 configHash.put("compressWhitespace",
\r
264 new freemarker.template.utility.CompressWhitespace());
\r
266 SimpleHash utilityHash = new SimpleHash();
\r
268 utilityHash.put("compressWhitespace",
\r
269 new freemarker.template.utility.CompressWhitespace());
\r
270 utilityHash.put("encodeURI",
\r
271 FreemarkerGenerator.makeAdapter(new GeneratorHTMLFunctions.
\r
272 encodeURIGeneratorFunction()));
\r
273 utilityHash.put("encodeHTML",
\r
274 FreemarkerGenerator.makeAdapter(new GeneratorHTMLFunctions.
\r
275 encodeHTMLGeneratorFunction()));
\r
276 utilityHash.put("isOdd",
\r
277 FreemarkerGenerator.makeAdapter(new GeneratorIntegerFunctions.
\r
279 utilityHash.put("increment",
\r
280 FreemarkerGenerator.makeAdapter(new GeneratorIntegerFunctions.
\r
281 incrementFunction()));
\r
283 catch (Throwable t) {
\r
284 throw new HTMLParseException(t.getMessage());
\r
287 SimpleHash outPutHash = new SimpleHash();
\r
289 if (extra != null) {
\r
290 outPutHash.put("extra", extra);
\r
292 while ( ( (SimpleList) extra).hasNext()) {
\r
293 theLog.printDebugInfo( ( (SimpleList) extra).next().toString());
\r
296 catch (Exception e) {
\r
299 outPutHash.put("data", tmr);
\r
300 outPutHash.put("config", configHash);
\r
301 outPutHash.put("utility", utilityHash);
\r
303 MessageResources messages = MessageResources.getMessageResources(bundles);
\r
304 if (bundles2!=null) {
\r
305 outPutHash.put("lang", new MessageMethodModel(locale, MessageResources.getMessageResources(bundles), MessageResources.getMessageResources(bundles2)));
\r
308 outPutHash.put("lang", new MessageMethodModel(locale, MessageResources.getMessageResources(bundles)));
\r
311 tmpl.process(outPutHash, out);
\r
315 * Converts Entity-List to SimpleList of SimpleHashes.
\r
316 * @param aList ist eine Liste von Entity
\r
317 * @return eine freemarker.template.SimpleList von SimpleHashes.
\r
319 * @deprecated EntityLists comply with TemplateListModel now.
\r
321 public static SimpleList makeSimpleList(EntityList aList) throws
\r
322 StorageObjectFailure {
\r
323 theLog.printWarning(
\r
324 "## using deprecated makeSimpleList(entityList) - a waste of resources");
\r
325 SimpleList simpleList = new SimpleList();
\r
326 if (aList != null) {
\r
327 for (int i = 0; i < aList.size(); i++) {
\r
328 simpleList.add(aList.elementAt(i));
\r
335 * Konvertiert ein EntityList in ein freemarker.template.SimpleHash-Modell. Im Hash
\r
336 * sind die einzelnen Entities ueber ihre id zu erreichen.
\r
337 * @param aList ist die EntityList
\r
338 * @return SimpleHash mit den entsprechenden freemarker Daten
\r
341 public static SimpleHash makeSimpleHash(EntityList aList) throws
\r
342 StorageObjectFailure {
\r
343 SimpleHash simpleHash = new SimpleHash();
\r
344 Entity currentEntity;
\r
346 if (aList != null) {
\r
347 for (int i = 0; i < aList.size(); i++) {
\r
348 currentEntity = (Entity) aList.elementAt(i);
\r
349 simpleHash.put(currentEntity.getId(), currentEntity);
\r
356 * Konvertiert ein Hashtable mit den keys und values als String
\r
357 * in ein freemarker.template.SimpleHash-Modell
\r
358 * @param mergeData der HashMap mit den String / String Daten
\r
359 * @return SimpleHash mit den entsprechenden freemarker Daten
\r
362 public static SimpleHash makeSimpleHash(HashMap mergeData) {
\r
363 SimpleHash modelRoot = new SimpleHash();
\r
365 if (mergeData != null) {
\r
366 Set set = mergeData.keySet();
\r
367 Iterator it = set.iterator();
\r
368 for (int i = 0; i < set.size(); i++) {
\r
369 aField = (String) it.next();
\r
370 modelRoot.put(aField, (String) mergeData.get(aField));
\r
377 * Converts EntityList in SimpleHash and adds additional information
\r
378 * to the returned SimpleHash
\r
381 * @return SimpleHash returns SimpleHash with the converted EntityList plus
\r
382 * additional Data about the list.
\r
383 * @exception StorageObjectException
\r
386 public static SimpleHash makeSimpleHashWithEntitylistInfos(EntityList entList) throws
\r
387 StorageObjectFailure {
\r
388 SimpleHash modelRoot = new SimpleHash();
\r
389 if (entList != null) {
\r
390 modelRoot.put("contentlist", entList);
\r
391 modelRoot.put("count",
\r
392 new SimpleScalar( (new Integer(entList.getCount())).toString()));
\r
393 if (entList.getWhere() != null) {
\r
394 modelRoot.put("where", new SimpleScalar(entList.getWhere()));
\r
395 modelRoot.put("where_encoded",
\r
396 new SimpleScalar(URLEncoder.encode(entList.getWhere())));
\r
398 if (entList.getOrder() != null) {
\r
399 modelRoot.put("order", new SimpleScalar(entList.getOrder()));
\r
400 modelRoot.put("order_encoded",
\r
401 new SimpleScalar(URLEncoder.encode(entList.getOrder())));
\r
403 modelRoot.put("from",
\r
404 new SimpleScalar( (new Integer(entList.getFrom())).toString()));
\r
405 modelRoot.put("to",
\r
406 new SimpleScalar( (new Integer(entList.getTo())).toString()));
\r
408 if (entList.hasNextBatch())
\r
409 modelRoot.put("next",
\r
410 new SimpleScalar( (new Integer(entList.getNextBatch())).
\r
412 if (entList.hasPrevBatch())
\r
413 modelRoot.put("prev",
\r
414 new SimpleScalar( (new Integer(entList.getPrevBatch())).
\r
421 * Private methods to get template from a templateFilename
\r
422 * @param templateFilename
\r
424 * @exception HTMLParseException
\r
426 private static Template getTemplateFor(String templateFilename) throws
\r
427 HTMLParseException {
\r
428 Template returnTemplate = null;
\r
429 if (templateFilename != null)
\r
430 returnTemplate = (Template) templateCache.getItem(templateFilename,
\r
433 if (returnTemplate == null) {
\r
434 theLog.printError("CACHE (ERR): Unknown template: " + templateFilename);
\r
435 throw new HTMLParseException("Templatefile: " + templateFilename +
\r
439 return returnTemplate;
\r
442 public static void stopAutoUpdate() {
\r
443 templateCache.stopAutoUpdate();
\r
444 templateCache = null;
\r