first cut of merge of STABLE-pre1_0 into HEAD. I won't even guarantee that it
[mir.git] / source / mir / misc / HTMLTemplateProcessor.java
1 /*
2  * put your module comment here
3  */
4
5
6 package mir.misc;
7
8 import  java.lang.*;
9 import  java.util.*;
10 import  java.io.*;
11 import  java.net.*;
12 import  freemarker.template.*;
13 import  mir.entity.*;
14 import  mir.storage.*;
15 import javax.servlet.http.*;
16
17
18 /**
19  * Hilfsklasse zum Mergen von Template und Daten
20  */
21 public final class HTMLTemplateProcessor {
22
23   public static String                templateDir;
24   private static FileTemplateCache    templateCache;
25   private static Logfile              theLog;
26   private static String               docRoot;
27   private static String               actionRoot;
28   private static String               productionHost;
29   private static String               audioHost;
30   private static String               videoHost;
31   private static String               imageHost;
32   private static String               openAction;
33   protected static String producerDocRoot = MirConfig.getProp("Producer.DocRoot");
34   protected static String producerStorageRoot = MirConfig.getProp("Producer.StorageRoot");
35
36
37   //
38   // init
39
40   static {
41     /** @todo either in the above block or here :) //rk */
42     templateDir = MirConfig.getPropWithHome("HTMLTemplateProcessor.Dir");
43     templateCache = new FileTemplateCache(templateDir);
44     templateCache.setLoadingPolicy(templateCache.LOAD_ON_DEMAND);
45     // gone in freemarker 1.7.1
46     // templateCache.startAutoUpdate();
47     theLog = Logfile.getInstance(MirConfig.getPropWithHome("HTMLTemplateProcessor.Logfile"));
48     docRoot = MirConfig.getProp("RootUri");
49     //the quick hack is back in effect as it was more broken than ever before
50     // -mh
51     // sorry: nadir back in town, i have to debug the mirbase.jar in the
52     // nadir evironment. from my point of coding, this needs an urgent
53     // fixxx.
54     // yeah, from my point too - tob.
55           //actionRoot = docRoot + "/servlet/" + MirConfig.getProp("ServletName");
56     //actionRoot = docRoot + "/servlet/NadirAktuell";
57
58     actionRoot = docRoot + "/servlet/Mir";
59
60     openAction = MirConfig.getProp("Producer.OpenAction");
61     productionHost = MirConfig.getProp("Producer.ProductionHost");
62     videoHost = MirConfig.getProp("Producer.VideoHost");
63     audioHost = MirConfig.getProp("Producer.AudioHost");
64     imageHost = MirConfig.getProp("Producer.Image.Host");
65     producerDocRoot = MirConfig.getProp("Producer.DocRoot");
66     producerStorageRoot = MirConfig.getProp("Producer.StorageRoot");
67   }
68
69   /**
70    * empty private constructor, to avoid instantiation
71    */
72   private HTMLTemplateProcessor () { }
73
74
75   // process-methods to merge different datastructures
76   // with freemarker templates
77
78
79   /**
80    * Wandelt <code>anEntity</code> in freemarker-Struktur um, mischt die Daten mit
81    * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
82    * <code>out</code>
83    *
84    * @param templateFilename
85    * @param anEntity
86    * @param out
87    * @exception HTMLParseException
88    */
89
90     public static void process(String templateFilename, Entity anEntity, PrintWriter out)
91       throws HTMLParseException {
92         if (anEntity == null)  throw new HTMLParseException("entity is empty!");
93         else process(templateFilename, anEntity, out);
94     }
95
96
97   /**
98    * Wandelt Liste mit Entities <code>entList</code> in freemarker-Struktur um, mischt die Daten mit
99    * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
100    * <code>out</code>
101    *
102    * @param templateFilename
103    * @param entList
104    * @param out
105    * @exception HTMLParseException
106    */
107   public static void process(HttpServletResponse res,String templateFilename, EntityList entList, PrintWriter out)
108       throws HTMLParseException {
109     process(res, templateFilename,  entList,  (String)null, (TemplateModelRoot)null,  out);
110   }
111
112   /**
113    * Wandelt Entitylist in freemarker-Struktur um, fügt <code>additionalModel</code>
114    * unter dem Namen <code>additionalModelName</code> ein und mischt die Daten mit
115    * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
116    * <code>out</code>
117    *
118    * @param templateFilename
119    * @param entList
120    * @param additionalModelName
121    * @param additionalModel
122    * @param out
123    * @exception HTMLParseException
124    */
125     public static void process(HttpServletResponse res,String templateFilename, EntityList entList, String additionalModelName,
126              TemplateModelRoot additionalModel, PrintWriter out)
127       throws HTMLParseException {
128
129       SimpleHash modelRoot = new SimpleHash();
130
131       if (entList == null) {
132          process(null,templateFilename, modelRoot, out);
133       } else {
134         try {
135           modelRoot = makeSimpleHashWithEntitylistInfos(entList);
136
137           // Quickhack um mal ein Popup mit reinzunhemen ..
138           if (additionalModelName != null && additionalModel != null)
139               modelRoot.put(additionalModelName, additionalModel);
140
141           process(res,templateFilename, modelRoot, out);
142         } catch (StorageObjectException e) {
143           throw new HTMLParseException(e.toString());
144         }
145       }
146     }
147
148   /**
149    * Wandelt HashMap <code>mergeData</code> in freemarker-Struktur und mischt diese mit
150    * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
151    * <code>out</code>
152    *
153    * @param templateFilename
154    * @param mergeData - a HashMap with mergeData to be converted in SimpleHash
155    * @param out
156    * @exception HTMLParseException
157    */
158     public static void process(HttpServletResponse res,String templateFilename, HashMap mergeData, PrintWriter out)
159       throws HTMLParseException {
160       process(res,templateFilename, makeSimpleHash(mergeData), out);
161     }
162
163   /**
164    * Gibt Template <code>templateFilename</code> an den PrintWriter
165    * <code>out</code>
166    *
167    * @param templateFilename
168    * @param mergeData
169    * @param out
170    * @exception HTMLParseException
171    */
172     public static void process(String templateFilename, PrintWriter out)
173       throws HTMLParseException {
174       process(null,templateFilename, (TemplateModelRoot)null, out);
175     }
176
177
178   /**
179    * Mischt die freemarker-Struktur <code>tmr</code> mit
180    * Template <code>templateFilename</code> und gibt das Ergebnis an den PrintWriter
181    * <code>out</code>
182    *
183    * @param templateFilename
184    * @param mergeData
185    * @param out
186    * @exception HTMLParseException
187    */
188     public static void process(HttpServletResponse res,String templateFilename, TemplateModelRoot tmr, PrintWriter out)
189       throws HTMLParseException {
190       if (out==null) throw new HTMLParseException("no outputstream");
191       Template tmpl = getTemplateFor(templateFilename);
192       if (tmpl == null) throw new HTMLParseException("no template: " + templateFilename);
193       if (tmr==null) tmr = new SimpleHash();
194
195       /** @todo  what is this for? (rk) */
196       String session="";
197       if (res!=null) {
198         session=res.encodeURL("");
199       }
200
201       /** @todo why do we double those? should be cleaned up and
202        *  statically initialized, we do not need to assemble a config
203        *  hash everytime we give out a page, only exception is
204        *  date "now" // rk */
205       // put standard configuration into tempalteRootmodel
206       SimpleHash configHash = new SimpleHash();
207       configHash.put("docroot", new SimpleScalar(producerDocRoot));
208       configHash.put("storageroot", new SimpleScalar(producerStorageRoot));
209       configHash.put("productionhost", new SimpleScalar(productionHost));
210       configHash.put("openaction", new SimpleScalar(openAction));
211       configHash.put("actionRootLogin",new SimpleScalar(actionRoot));
212
213
214       tmr.put("docRoot", new SimpleScalar(docRoot));
215       tmr.put("now", new SimpleScalar(StringUtil.date2readableDateTime(new GregorianCalendar())));
216       tmr.put("actionRoot", new SimpleScalar(actionRoot+session));
217       tmr.put("openAction", new SimpleScalar(openAction));
218       tmr.put("productionHost", new SimpleScalar(productionHost));
219       tmr.put("videoHost", new SimpleScalar(videoHost));
220       tmr.put("audioHost", new SimpleScalar(audioHost));
221       tmr.put("imageHost", new SimpleScalar(imageHost));
222       // this conform to updated freemarker syntax
223       tmr.put("compressWhitespace", new freemarker.template.utility.CompressWhitespace() );
224
225       tmr.put("config", configHash);
226       tmpl.process(tmr, out);
227
228     }
229
230
231   /**
232    *   Converts Entity-List to SimpleList of SimpleHashes.
233    *   @param aList ist eine Liste von Entity
234    *   @return eine freemarker.template.SimpleList von SimpleHashes.
235    *
236    *    @deprecated EntityLists comply with TemplateListModel now.
237    */
238   public static SimpleList makeSimpleList(EntityList aList) throws StorageObjectException
239   {
240     theLog.printWarning("## using deprecated makeSimpleList(entityList) - a waste of resources");
241     SimpleList  simpleList = new SimpleList();
242     if (aList != null) {
243       for(int i=0;i<aList.size();i++) {
244         simpleList.add(aList.elementAt(i));
245       }
246     }
247     return simpleList;
248   }
249
250   /**
251    *  Konvertiert ein EntityList in ein freemarker.template.SimpleHash-Modell. Im Hash
252    *  sind die einzelnen Entities ueber ihre id zu erreichen.
253    *  @param aList ist die EntityList
254    *  @return SimpleHash mit den entsprechenden freemarker Daten
255    *
256    */
257   public static SimpleHash makeSimpleHash(EntityList aList) throws StorageObjectException
258   {
259     SimpleHash      simpleHash = new SimpleHash();
260     Entity          currentEntity;
261
262     if (aList != null) {
263       for (int i=0;i<aList.size();i++) {
264          currentEntity = (Entity)aList.elementAt(i);
265          simpleHash.put(currentEntity.getId(), currentEntity);
266       }
267     }
268     return simpleHash;
269   }
270
271   /**
272    *  Konvertiert ein Entity in ein freemarker.template.SimpleHash-Modell
273    *  @param entity ist die Entity
274    *  @return SimpleHash mit den entsprechenden freemarker Daten
275    *
276    *  @deprecated This method is deprecated and will be deleted in the next
277    *  release. Entity interfaces freemarker.template.TemplateHashModel now
278    *  and can be used in the same way as SimpleHash. It is not necessary any
279    *  more to make a SimpleHash from an Entity
280    */
281   public static SimpleHash makeSimpleHash(Entity entity) {
282     if (entity != null) {
283       theLog.printWarning("## using deprecated makeSimpleHash(entity) - a waste of resources");
284       return makeSimpleHash(entity.getValues());
285     }
286     else
287       return null;
288   }
289
290   /**
291    *  Konvertiert ein Hashtable mit den keys und values als String
292    *  in ein freemarker.template.SimpleHash-Modell
293    *  @param mergeData der HashMap mit den String / String Daten
294    *  @return SimpleHash mit den entsprechenden freemarker Daten
295    *
296    */
297   public static SimpleHash makeSimpleHash(HashMap mergeData)
298   {
299     SimpleHash modelRoot = new SimpleHash();
300     String aField;
301     if (mergeData != null) {
302       Set set = mergeData.keySet();
303       Iterator it =  set.iterator();
304       for (int i=0; i<set.size();i++)  {
305         aField = (String)it.next();
306         modelRoot.put(aField, (String)mergeData.get(aField));
307       }
308     }
309     return modelRoot;
310   }
311
312
313   /**
314    * Converts EntityList in SimpleHash and adds additional information
315    * to the returned SimpleHash
316    *
317    * @param entList
318    * @return SimpleHash returns SimpleHash with the converted EntityList plus
319    *        additional Data about the list.
320    * @exception StorageObjectException
321    */
322
323   public static SimpleHash makeSimpleHashWithEntitylistInfos(EntityList entList) throws StorageObjectException {
324     SimpleHash modelRoot = new SimpleHash();
325     if (entList!=null) {
326       modelRoot.put("contentlist", entList);
327       modelRoot.put("count", new SimpleScalar((new Integer(entList.getCount())).toString()));
328       if (entList.getWhere()!=null) {
329         modelRoot.put("where", new SimpleScalar(entList.getWhere()));
330         modelRoot.put("where_encoded", new SimpleScalar(URLEncoder.encode(entList.getWhere())));
331       }
332       if(entList.getOrder()!=null) {
333         modelRoot.put("order", new SimpleScalar(entList.getOrder()));
334         modelRoot.put("order_encoded", new SimpleScalar(URLEncoder.encode(entList.getOrder())));
335       }
336       modelRoot.put("from", new SimpleScalar((new Integer(entList.getFrom())).toString()));
337       modelRoot.put("to", new SimpleScalar((new Integer(entList.getTo())).toString()));
338
339       if (entList.hasNextBatch())
340         modelRoot.put("next", new SimpleScalar((new Integer(entList.getNextBatch())).toString()));
341       if (entList.hasPrevBatch())
342         modelRoot.put("prev", new SimpleScalar((new Integer(entList.getPrevBatch())).toString()));
343     }
344     return modelRoot;
345   }
346
347   /**
348    * Private methods to get template from a templateFilename
349    * @param templateFilename
350    * @return Template
351    * @exception HTMLParseException
352    */
353   private static Template getTemplateFor(String templateFilename) throws HTMLParseException
354   {
355     Template returnTemplate = null;
356     if (templateFilename!=null)
357       returnTemplate = (Template)templateCache.getItem(templateFilename,"template");
358
359
360     if (returnTemplate==null) {
361       theLog.printError("CACHE (ERR): Unknown template: " + templateFilename);
362       throw new HTMLParseException("Templatefile: "+ templateFilename + " not found.");
363     }
364
365     return returnTemplate;
366   }
367
368   public static void stopAutoUpdate(){
369     templateCache.stopAutoUpdate();
370     templateCache=null;
371   }
372
373 }