data. ... got lost
[mir.git] / source / mir / servlet / ServletModule.java
1 package mir.servlet;
2
3 import freemarker.template.SimpleHash;
4 import freemarker.template.TemplateModelRoot;
5 import freemarker.template.TemplateModel;
6
7 import mir.entity.EntityList;
8 import mir.misc.*;
9 import mir.module.AbstractModule;
10 import mir.module.ModuleException;
11 import mir.storage.StorageObject;
12 import mir.storage.StorageObjectException;
13
14 import javax.servlet.http.HttpServletRequest;
15 import javax.servlet.http.HttpServletResponse;
16 import javax.servlet.http.HttpSession;
17 import java.io.IOException;
18 import java.io.PrintWriter;
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.Locale;
22
23
24 /**
25  * Abstract class ServletModule provides the base functionality for servlets.
26  * Deriving a class from ServletModule enables class to insert/edit/update/delete
27  * and list Entity from a Database via mainModule.
28  *
29  *
30  *  Abstrakte Klasse ServletModule stellt die Basisfunktionalitaet der
31  *  abgeleiteten ServletModule zur Verfügung.
32  *
33  * @version 28.6.1999
34  * @author RK
35  */
36
37 public abstract class ServletModule {
38
39     public String defaultAction;
40     protected Logfile theLog;
41     protected AbstractModule mainModule;
42     protected String templateListString;
43     protected String templateObjektString;
44     protected String templateConfirmString;
45
46     /**
47      * Singelton - Methode muss in den abgeleiteten Klassen ueberschrieben werden.
48      * @return ServletModule
49      */
50     public static ServletModule getInstance() {
51         return null;
52     }
53
54     /**
55      * get the session binded language
56      */
57     public String getLanguage(HttpServletRequest req) {
58         HttpSession session = req.getSession(false);
59         String language = (String) session.getAttribute("Language");
60         if (language == null) {
61             language = MirConfig.getProp("StandardLanguage");
62         }
63         return language;
64     }
65
66     /**
67      * get the locale either from the session or the accept-language header ot the request
68      * this supersedes getLanguage for the new i18n
69      */
70     public Locale getLocale(HttpServletRequest req) {
71         Locale loc = null;
72         HttpSession session = req.getSession(false);
73         if (session != null) {
74             // session can be null in case of logout
75             loc = (Locale) session.getAttribute("Locale");
76         }
77         // if there is nothing in the session get it fron the accept-language
78         if (loc == null) {
79             loc = req.getLocale();
80         }
81         return loc;
82     }
83
84     // ACHTUNG DEPRECATED::::
85     public void process(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException {
86     }
87
88
89     /**
90      *  list(req,res) - generische Listmethode. Wennn die Funktionalitaet
91      *  nicht reicht, muss sie in der abgeleiteten ServletModule-Klasse
92      *  ueberschreiben werden.
93      *
94      * @param req Http-Request, das vom Dispatcher durchgereicht wird
95      * @param res Http-Response, die vom Dispatcher durchgereicht wird
96      */
97     public void list(HttpServletRequest req, HttpServletResponse res)
98             throws ServletModuleException {
99         try {
100             EntityList theList;
101             String offsetParam = req.getParameter("offset");
102             int offset = 0;
103             PrintWriter out = res.getWriter();
104
105             // hier offsetcode bearbeiten
106             if (offsetParam != null && !offsetParam.equals("")) {
107                 offset = Integer.parseInt(offsetParam);
108             }
109             if (req.getParameter("next") != null) {
110                 offset = Integer.parseInt(req.getParameter("nextoffset"));
111             }
112             else {
113                 if (req.getParameter("prev") != null) {
114                     offset = Integer.parseInt(req.getParameter("prevoffset"));
115                 }
116             }
117             theList = mainModule.getByWhereClause(null, offset);
118             //theList = mainModule.getByWhereClause((String)null, offset);
119             if (theList == null || theList.getCount() == 0 || theList.getCount() > 1) {
120                 HTMLTemplateProcessor.process(res, templateListString, theList, out, getLocale(req));
121             }
122             else {
123                 deliver(req, res, theList.elementAt(0), templateObjektString);
124             }
125         }
126         catch (Exception e) {
127             throw new ServletModuleException(e.toString());
128         }
129     }
130
131     /**
132      *  add(req,res) - generische Addmethode. Wennn die Funktionalitaet
133      *  nicht reicht, muss sie in der abgeleiteten ServletModule-Klasse
134      *  ueberschreiben werden.
135      * @param req Http-Request, das vom Dispatcher durchgereicht wird
136      * @param res Http-Response, die vom Dispatcher durchgereicht wird
137      */
138     public void add(HttpServletRequest req, HttpServletResponse res)
139             throws ServletModuleException {
140
141         try {
142             SimpleHash mergeData = new SimpleHash();
143             mergeData.put("new", "1");
144             deliver(req, res, mergeData, templateObjektString);
145         }
146         catch (Exception e) {
147             throw new ServletModuleException(e.toString());
148         }
149     }
150
151     /**
152      *  insert(req,res) - generische Insertmethode, folgt auf add.
153      *  Wennn die Funktionalitaet
154      *  nicht reicht, muss sie in der abgeleiteten ServletModule-Klasse
155      *  ueberschreiben werden.
156      *
157      * @param req Http-Request, das vom Dispatcher durchgereicht wird
158      * @param res Http-Response, die vom Dispatcher durchgereicht wird
159      */
160     public void insert(HttpServletRequest req, HttpServletResponse res)
161             throws ServletModuleException, ServletModuleUserException {
162         try {
163             HashMap withValues = getIntersectingValues(req, mainModule.getStorageObject());
164             theLog.printDebugInfo("--trying to add...");
165             String id = mainModule.add(withValues);
166             theLog.printDebugInfo("--trying to deliver..." + id);
167             list(req, res);
168         }
169         catch (Exception e) {
170             throw new ServletModuleException(e.toString());
171         }
172     }
173
174     /**
175      *  delete(req,res) - generische Deletemethode. Wennn die Funktionalitaet
176      *  nicht reicht, muss sie in der abgeleiteten ServletModule-Klasse
177      *  ueberschreiben werden.
178      *
179      * @param req Http-Request, das vom Dispatcher durchgereicht wird
180      * @param res Http-Response, die vom Dispatcher durchgereicht wird
181      */
182
183     public void delete(HttpServletRequest req, HttpServletResponse res)
184             throws ServletModuleException {
185         try {
186             String idParam = req.getParameter("id");
187             if (idParam == null) throw new ServletModuleException("Falscher Aufruf: (id) nicht angegeben");
188             // Hier code zum Loeschen
189             String confirmParam = req.getParameter("confirm");
190             String cancelParam = req.getParameter("cancel");
191             if (confirmParam == null && cancelParam == null) {
192                 // HTML Ausgabe zum Confirmen!
193                 SimpleHash mergeData = new SimpleHash();
194                 String moduleClassName = mainModule.getClass().getName();
195                 int i = moduleClassName.indexOf(".Module");
196                 String moduleName = moduleClassName.substring(i + 7);
197                 mergeData.put("module", moduleName);
198                 mergeData.put("infoString", moduleName + ": " + idParam);
199                 mergeData.put("id", idParam);
200                 mergeData.put("where", req.getParameter("where"));
201                 mergeData.put("order", req.getParameter("order"));
202                 mergeData.put("offset", req.getParameter("offset"));
203                 deliver(req, res, mergeData, templateConfirmString);
204             }
205             else {
206                 if (confirmParam != null && !confirmParam.equals("")) {
207                     //theLog.printInfo("delete confirmed!");
208                     mainModule.deleteById(idParam);
209                     list(req, res); // back to list
210                 }
211                 else {
212                     if (req.getParameter("where") != null)
213                         list(req, res);
214                     else
215                         edit(req, res);
216                 }
217             }
218         }
219         catch (Exception e) {
220             throw new ServletModuleException(e.toString());
221         }
222     }
223
224     /**
225      *  edit(req,res) - generische Editmethode. Wennn die Funktionalitaet
226      *  nicht reicht, muss sie in der abgeleiteten ServletModule-Klasse
227      *  ueberschreiben werden.
228      *
229      * @param req Http-Request, das vom Dispatcher durchgereicht wird
230      * @param res Http-Response, die vom Dispatcher durchgereicht wird
231      */
232     public void edit(HttpServletRequest req, HttpServletResponse res)
233             throws ServletModuleException {
234         try {
235             String idParam = req.getParameter("id");
236             deliver(req, res, mainModule.getById(idParam), templateObjektString);
237         }
238         catch (ModuleException e) {
239             throw new ServletModuleException(e.toString());
240         }
241     }
242
243     /**
244      *  update(req,res) - generische Updatemethode. Wennn die Funktionalitaet
245      *  nicht reicht, muss sie in der abgeleiteten ServletModule-Klasse
246      *  ueberschreiben werden.
247      *
248      * @param req Http-Request, das vom Dispatcher durchgereicht wird
249      * @param res Http-Response, die vom Dispatcher durchgereicht wird
250      */
251
252     public void update(HttpServletRequest req, HttpServletResponse res)
253             throws ServletModuleException {
254         try {
255             String idParam = req.getParameter("id");
256             HashMap withValues = getIntersectingValues(req, mainModule.getStorageObject());
257             String id = mainModule.set(withValues);
258             //theLog.printInfo("Showing Entity with id: " + id);
259             //edit(req,res);
260             String whereParam = req.getParameter("where");
261             String orderParam = req.getParameter("order");
262             if ((whereParam != null && !whereParam.equals("")) || (orderParam != null && !orderParam.equals(""))) {
263                 //theLog.printDebugInfo("update to list");
264                 list(req, res);
265             }
266             else {
267                 edit(req, res);
268             }
269             //list(req,res);
270         }
271         catch (Exception e) {
272             throw new ServletModuleException(e.toString());
273         }
274     }
275
276     /**
277      * deliver liefert das Template mit dem Filenamen templateFilename
278      * an den HttpServletResponse res aus, nachdem es mit den Daten aus
279      * TemplateModelRoot rtm gemischt wurde
280      *
281      * @param res Http-Response, die vom Dispatcher durchgereicht wird
282      * @param rtm beinahalten das freemarker.template.TempalteModelRoot mit den
283      *   Daten, die ins Template gemerged werden sollen.
284      * @param tmpl Name des Templates
285      * @exception ServletModuleException
286      */
287         public void deliver(HttpServletRequest req, HttpServletResponse res,
288                                                                                         TemplateModelRoot rtm, TemplateModelRoot popups,
289                                                                                         String templateFilename)
290         throws ServletModuleException {
291                 if (rtm == null) rtm = new SimpleHash();
292                 try {
293                         PrintWriter out = res.getWriter();
294                         HTMLTemplateProcessor.process(res, templateFilename, rtm, popups, out,
295                                                                                                                                                 getLocale(req));
296                         out.close();
297                 }       catch (HTMLParseException e) {
298                         throw new ServletModuleException(e.toString());
299                 } catch (IOException e) {
300                         throw new ServletModuleException(e.toString());
301                 }
302         }
303
304         
305         /**
306          * deliver liefert das Template mit dem Filenamen templateFilename
307          * an den HttpServletResponse res aus, nachdem es mit den Daten aus
308          * TemplateModelRoot rtm gemischt wurde
309          *
310          * @param res Http-Response, die vom Dispatcher durchgereicht wird
311          * @param rtm beinahalten das freemarker.template.TempalteModelRoot mit den
312          *   Daten, die ins Template gemerged werden sollen.
313          * @param tmpl Name des Templates
314          * @exception ServletModuleException
315          */
316         public void deliver(HttpServletRequest req, HttpServletResponse res,
317                                                                                         TemplateModelRoot rtm, String templateFilename)
318         throws ServletModuleException {
319                 deliver(req, res, rtm, null, templateFilename);
320         }
321         
322     /**
323      * deliver liefert das Template mit dem Filenamen templateFilename
324      * an den HttpServletResponse res aus, nachdem es mit den Daten aus
325      * TemplateModelRoot rtm gemischt wurde
326      *
327      * @param res Http-Response, die vom Dispatcher durchgereicht wird
328      * @param rtm beinahalten das freemarker.template.TempalteModelRoot mit den
329      *   Daten, die ins Template gemerged werden sollen.
330      * @param tmpl Name des Templates
331      * @exception ServletModuleException
332      */
333     public void deliver_compressed(HttpServletRequest req, HttpServletResponse res, TemplateModelRoot rtm, String templateFilename)
334             throws ServletModuleException {
335         if (rtm == null) rtm = new SimpleHash();
336         try {
337             PrintWriter out = new LineFilterWriter(res.getWriter());
338             //PrintWriter out =  res.getWriter();
339             HTMLTemplateProcessor.process(res, templateFilename, rtm, out, getLocale(req));
340             out.close();
341         }
342         catch (HTMLParseException e) {
343             throw new ServletModuleException(e.toString());
344         }
345         catch (IOException e) {
346             throw new ServletModuleException(e.toString());
347         }
348     }
349
350     /**
351      * deliver liefert das Template mit dem Filenamen templateFilename
352      * an den HttpServletResponse res aus, nachdem es mit den Daten aus
353      * TemplateModelRoot rtm gemischt wurde
354      *
355      * @param out ist der OutputStream, in den die gergten Daten geschickt werden sollen.
356      * @param rtm beinahalten das freemarker.template.TempalteModelRoot mit den
357      *   Daten, die ins Template gemerged werden sollen.
358      * @param tmpl Name des Templates
359      * @exception ServletModuleException
360      */
361     private void deliver(HttpServletResponse res, HttpServletRequest req, PrintWriter out, TemplateModelRoot rtm, String templateFilename)
362             throws HTMLParseException {
363         HTMLTemplateProcessor.process(res, templateFilename, rtm, out, getLocale(req));
364     }
365
366     /**
367      *  Wenn die abgeleitete Klasse diese Methode ueberschreibt und einen String mit einem
368      *  Methodennamen zurueckliefert, dann wird diese Methode bei fehlender Angabe des
369      *  doParameters ausgefuehrt.
370      *
371      * @return Name der Default-Action
372      */
373     public String defaultAction() {
374         return defaultAction;
375     }
376
377     /**
378      *  Hier kann vor der Datenaufbereitung schon mal ein response geschickt
379      *  werden (um das subjektive Antwortverhalten bei langsamen Verbindungen
380      *  zu verbessern).
381      */
382     public void predeliver(HttpServletRequest req, HttpServletResponse res) {
383         ;
384     }
385
386     /**
387      * Holt die Felder aus der Metadatenfelderliste des StorageObjects, die
388      * im HttpRequest vorkommen und liefert sie als HashMap zurueck
389      *
390      * @return HashMap mit den Werten
391      */
392     public HashMap getIntersectingValues(HttpServletRequest req, StorageObject theStorage)
393             throws ServletModuleException {
394         ArrayList theFieldList;
395         try {
396             theFieldList = theStorage.getFields();
397         }
398         catch (StorageObjectException e) {
399             throw new ServletModuleException("ServletModule.getIntersectingValues: " + e.toString());
400         }
401
402         HashMap withValues = new HashMap();
403         String aField, aValue;
404
405         for (int i = 0; i < theFieldList.size(); i++) {
406             aField = (String) theFieldList.get(i);
407             aValue = req.getParameter(aField);
408             if (aValue != null) withValues.put(aField, aValue);
409         }
410         return withValues;
411     }
412
413 }