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