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 any library licensed under the Apache Software License,
\r
22 * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
\r
23 * (or with modified versions of the above that use the same license as the above),
\r
24 * and distribute linked combinations including the two. You must obey the
\r
25 * GNU General Public License in all respects for all of the code used other than
\r
26 * the above mentioned libraries. If you modify this file, you may extend this
\r
27 * exception to your version of the file, but you are not obligated to do so.
\r
28 * If you do not wish to do so, delete this exception statement from your version.
\r
30 package mir.servlet;
\r
32 import java.util.HashMap;
\r
33 import java.util.Iterator;
\r
34 import java.util.List;
\r
35 import java.util.Locale;
\r
36 import java.util.Map;
\r
37 import javax.servlet.http.HttpServletRequest;
\r
38 import javax.servlet.http.HttpServletResponse;
\r
39 import javax.servlet.http.HttpSession;
\r
41 import mir.config.MirPropertiesConfiguration;
\r
42 import mir.config.MirPropertiesConfiguration.PropertiesConfigExc;
\r
43 import mir.entity.adapter.EntityAdapterDefinition;
\r
44 import mir.entity.adapter.EntityAdapterEngine;
\r
45 import mir.entity.adapter.EntityAdapterModel;
\r
46 import mir.log.LoggerWrapper;
\r
47 import mir.module.AbstractModule;
\r
48 import mir.storage.StorageObject;
\r
49 import mir.util.HTTPRequestParser;
\r
50 import mir.util.URLBuilder;
\r
51 import mircoders.servlet.ServletHelper;
\r
56 * <p>Description: </p>
\r
57 * <p>Copyright: Copyright (c) 2003</p>
\r
59 * @author not attributable
\r
63 public abstract class ServletModule {
\r
64 public String defaultAction;
\r
65 protected LoggerWrapper logger;
\r
66 protected MirPropertiesConfiguration configuration;
\r
67 protected Locale fallbackLocale;
\r
69 protected AbstractModule mainModule;
\r
70 protected String definition;
\r
71 protected EntityAdapterModel model;
\r
73 protected String listGenerator;
\r
74 protected String editGenerator;
\r
75 protected String deleteConfirmationGenerator;
\r
76 protected int nrEntitiesPerListPage;
\r
79 public ServletModule(){
\r
84 configuration = MirPropertiesConfiguration.instance();
\r
86 catch (PropertiesConfigExc e) {
\r
87 throw new RuntimeException("Can't get configuration: " + e.getMessage());
\r
90 listGenerator = configuration.getString("ServletModule."+getOperationModuleName()+".ListTemplate");
\r
91 editGenerator = configuration.getString("ServletModule."+getOperationModuleName()+".EditTemplate");
\r
92 deleteConfirmationGenerator = configuration.getString("ServletModule."+getOperationModuleName()+".DeleteConfirmationTemplate");
\r
93 nrEntitiesPerListPage =
\r
94 configuration.getInt("ServletModule."+getOperationModuleName()+".ListSize",
\r
95 configuration.getInt("ServletModule.Default.ListSize", 20));
\r
97 fallbackLocale = new Locale(configuration.getString("Mir.Admin.FallbackLanguage", "en"), "");
\r
102 * Singleton instance retrievel method. MUST be overridden in subclasses.
\r
104 * @return ServletModule the single instance of the servletmodule class
\r
106 public static ServletModule getInstance() {
\r
111 * Get the module name
\r
115 protected String getOperationModuleName() {
\r
116 return getClass().getName().substring((new String("mircoders.servlet.ServletModule")).length());
\r
120 * get the locale either from the session or the accept-language header ot the request
\r
121 * this supersedes getLanguage for the new i18n
\r
123 public Locale getLocale(HttpServletRequest aRequest) {
\r
125 HttpSession session = aRequest.getSession(false);
\r
126 if (session != null) {
\r
127 // session can be null in case of logout
\r
128 loc = (Locale) session.getAttribute("locale");
\r
130 // if there is nothing in the session get it fron the accept-language
\r
132 loc = aRequest.getLocale();
\r
138 * get the locale either from the session or the accept-language header ot the request
\r
139 * this supersedes getLanguage for the new i18n
\r
141 public Locale getFallbackLocale(HttpServletRequest aRequest) {
\r
142 return fallbackLocale;
\r
146 * Function to specify the default ordering for lists. May be overridden.
\r
151 public String getDefaultListOrdering() {
\r
153 if (mainModule!=null && mainModule.getStorageObject()!=null){
\r
154 if (mainModule.getStorageObject().getFields().contains("webdb_create"))
\r
155 return "webdb_create desc";
\r
165 * @throws ServletModuleExc
\r
166 * @throws ServletModuleFailure
\r
168 public void redirect(HttpServletResponse aResponse, String aQuery) throws ServletModuleExc, ServletModuleFailure {
\r
170 aResponse.sendRedirect(aResponse.encodeRedirectURL(MirPropertiesConfiguration.instance().getString("RootUri") + "/Mir?"+aQuery));
\r
172 catch (Throwable t) {
\r
173 throw new ServletModuleFailure("ServletModule.redirect: " +t.getMessage(), t);
\r
178 * Generic list method
\r
182 * @throws ServletModuleExc
\r
183 * @throws ServletModuleUserExc
\r
184 * @throws ServletModuleFailure
\r
187 public void list(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
\r
189 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
\r
191 String where = requestParser.getParameter("where");
\r
192 String order = requestParser.getParameterWithDefault("order", getDefaultListOrdering());
\r
193 int offset = requestParser.getIntegerWithDefault("offset", 0);
\r
195 returnList(aRequest, aResponse, where, order, offset);
\r
199 public void returnList(HttpServletRequest aRequest, HttpServletResponse aResponse,
\r
200 String aWhereClause, String anOrderByClause, int anOffset) throws ServletModuleExc {
\r
202 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
\r
203 URLBuilder urlBuilder = new URLBuilder();
\r
207 Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
\r
210 EntityAdapterEngine.retrieveAdapterList(model, definition, aWhereClause, anOrderByClause, nrEntitiesPerListPage, anOffset);
\r
212 responseData.put("nexturl", null);
\r
213 responseData.put("prevurl", null);
\r
214 responseData.put("module", getOperationModuleName());
\r
216 count=mainModule.getSize(aWhereClause);
\r
218 urlBuilder.setValue("module", getOperationModuleName());
\r
219 urlBuilder.setValue("do", "list");
\r
220 urlBuilder.setValue("where", aWhereClause);
\r
221 urlBuilder.setValue("order", anOrderByClause);
\r
223 urlBuilder.setValue("searchfield", requestParser.getParameter("searchfield"));
\r
224 urlBuilder.setValue("searchtext", requestParser.getParameter("searchtext"));
\r
225 urlBuilder.setValue("searchispublished", requestParser.getParameter("searchispublished"));
\r
226 urlBuilder.setValue("searchstatus", requestParser.getParameter("searchstatus"));
\r
227 urlBuilder.setValue("searchorder", requestParser.getParameter("searchorder"));
\r
229 responseData.put("searchfield", requestParser.getParameter("searchfield"));
\r
230 responseData.put("searchtext", requestParser.getParameter("searchtext"));
\r
231 responseData.put("searchispublished", requestParser.getParameter("searchispublished"));
\r
232 responseData.put("searchstatus", requestParser.getParameter("searchstatus"));
\r
233 responseData.put("searchorder", requestParser.getParameter("searchorder"));
\r
235 urlBuilder.setValue("offset", anOffset);
\r
236 responseData.put("offset" , new Integer(anOffset).toString());
\r
237 responseData.put("thisurl" , urlBuilder.getQuery());
\r
239 if (count>anOffset+nrEntitiesPerListPage) {
\r
240 urlBuilder.setValue("offset", anOffset + nrEntitiesPerListPage);
\r
241 responseData.put("nexturl" , urlBuilder.getQuery());
\r
245 urlBuilder.setValue("offset", Math.max(anOffset - nrEntitiesPerListPage, 0));
\r
246 responseData.put("prevurl" , urlBuilder.getQuery());
\r
249 responseData.put("entities", list);
\r
250 responseData.put("from" , Integer.toString(anOffset+1));
\r
251 responseData.put("count", Integer.toString(count));
\r
252 responseData.put("to", Integer.toString(Math.min(anOffset+nrEntitiesPerListPage, count)));
\r
254 ServletHelper.generateResponse(aResponse.getWriter(), responseData, listGenerator);
\r
256 catch (Throwable e) {
\r
257 throw new ServletModuleFailure(e);
\r
261 public void editObject(HttpServletRequest aRequest, HttpServletResponse aResponse, Object anObject, boolean anIsNew, String anId) throws ServletModuleExc {
\r
262 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
\r
263 URLBuilder urlBuilder = new URLBuilder();
\r
264 EntityAdapterModel model;
\r
267 Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
\r
269 responseData.put("module", getOperationModuleName());
\r
270 responseData.put("entity", anObject);
\r
271 responseData.put("new", new Boolean(anIsNew));
\r
274 urlBuilder.setValue("module", getOperationModuleName());
\r
275 urlBuilder.setValue("returnurl", requestParser.getParameter("returnurl"));
\r
277 urlBuilder.setValue("do", "add");
\r
279 urlBuilder.setValue("id", anId);
\r
280 urlBuilder.setValue("do", "edit");
\r
282 responseData.put("returnurl", requestParser.getParameter("returnurl"));
\r
283 responseData.put("thisurl", urlBuilder.getQuery());
\r
285 ServletHelper.generateResponse(aResponse.getWriter(), responseData, editGenerator);
\r
287 catch (Throwable e) {
\r
288 throw new ServletModuleFailure(e);
\r
294 * Generic add method
\r
298 * @throws ServletModuleExc
\r
299 * @throws ServletModuleUserExc
\r
300 * @throws ServletModuleFailure
\r
302 public void add(HttpServletRequest aRequest, HttpServletResponse aResponse)
\r
303 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
\r
305 Map object = new HashMap();
\r
307 Iterator i = mainModule.getStorageObject().getFields().iterator();
\r
309 while (i.hasNext())
\r
310 object.put(i.next(), "");
\r
312 initializeNewObject(object, aRequest, aResponse);
\r
314 editObject(aRequest, aResponse, object, true, null);
\r
317 protected void initializeNewObject(Map aNewObject, HttpServletRequest aRequest, HttpServletResponse aResponse) {
\r
321 * Method called when the user edits an object.
\r
325 * @throws ServletModuleExc
\r
326 * @throws ServletModuleUserExc
\r
327 * @throws ServletModuleFailure
\r
329 public void edit(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
\r
330 edit(aRequest, aResponse, aRequest.getParameter("id"));
\r
334 * Generic edit method
\r
338 * @param anIdentifier
\r
339 * @throws ServletModuleExc
\r
340 * @throws ServletModuleUserExc
\r
341 * @throws ServletModuleFailure
\r
343 public void edit(HttpServletRequest aRequest, HttpServletResponse aResponse, String anIdentifier)
\r
344 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
\r
346 editObject(aRequest, aResponse, model.makeEntityAdapter(definition, mainModule.getById(anIdentifier)), false, anIdentifier);
\r
348 catch (Throwable e) {
\r
349 throw new ServletModuleFailure(e);
\r
354 * Generic update method
\r
358 * @throws ServletModuleExc
\r
359 * @throws ServletModuleUserExc
\r
360 * @throws ServletModuleFailure
\r
362 public void update(HttpServletRequest aRequest, HttpServletResponse aResponse)
\r
363 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
\r
365 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
\r
367 String id = aRequest.getParameter("id");
\r
368 Map withValues = getIntersectingValues(aRequest, mainModule.getStorageObject());
\r
369 mainModule.set(withValues);
\r
371 String returnUrl = requestParser.getParameter("returnurl");
\r
373 if (returnUrl!=null) {
\r
374 redirect(aResponse, returnUrl);
\r
377 edit(aRequest, aResponse, id);
\r
380 catch (Throwable e) {
\r
381 throw new ServletModuleFailure(e);
\r
386 * Generic insert method
\r
390 * @throws ServletModuleExc
\r
391 * @throws ServletModuleUserExc
\r
392 * @throws ServletModuleFailure
\r
394 public void insert(HttpServletRequest aRequest, HttpServletResponse aResponse)
\r
395 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
\r
397 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
\r
399 Map object = getIntersectingValues(aRequest, mainModule.getStorageObject());
\r
401 String id = processInstertedObject(object, aRequest, aResponse);
\r
403 String returnUrl = requestParser.getParameter("returnurl");
\r
405 if (returnUrl!=null) {
\r
406 redirect(aResponse, returnUrl);
\r
409 edit(aRequest, aResponse, id);
\r
412 catch (Throwable e) {
\r
413 throw new ServletModuleFailure(e);
\r
417 public String processInstertedObject(Map anObject, HttpServletRequest aRequest, HttpServletResponse aResponse) {
\r
419 return mainModule.add(anObject);
\r
421 catch (Throwable t) {
\r
422 throw new ServletModuleFailure(t);
\r
431 public void confirmdelete(HttpServletRequest aRequest, HttpServletResponse aResponse) {
\r
433 String idParam = aRequest.getParameter("id");
\r
434 String confirmParam = aRequest.getParameter("confirm");
\r
435 String cancelParam = aRequest.getParameter("cancel");
\r
437 if (confirmParam != null && !confirmParam.equals("")) {
\r
438 mainModule.deleteById(idParam);
\r
439 redirect(aResponse, aRequest.getParameter("okurl"));
\r
442 redirect(aResponse, aRequest.getParameter("cancelurl"));
\r
444 catch (Throwable t) {
\r
445 throw new ServletModuleFailure(t);
\r
453 * @throws ServletModuleExc
\r
454 * @throws ServletModuleUserExc
\r
455 * @throws ServletModuleFailure
\r
457 public void delete(HttpServletRequest aRequest, HttpServletResponse aResponse)
\r
458 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
\r
460 String idParam = aRequest.getParameter("id");
\r
462 if (idParam == null)
\r
463 throw new ServletModuleExc("Invalid call to delete: no id supplied");
\r
465 Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
\r
467 responseData.put("module", getOperationModuleName());
\r
468 responseData.put("id", idParam);
\r
469 responseData.put("cancelurl", aRequest.getParameter("cancelurl"));
\r
470 responseData.put("okurl", aRequest.getParameter("okurl"));
\r
472 ServletHelper.generateResponse(aResponse.getWriter(), responseData, deleteConfirmationGenerator);
\r
474 catch (Throwable e) {
\r
475 throw new ServletModuleFailure(e);
\r
480 * Wenn die abgeleitete Klasse diese Methode ueberschreibt und einen String mit einem
\r
481 * Methodennamen zurueckliefert, dann wird diese Methode bei fehlender Angabe des
\r
482 * doParameters ausgefuehrt.
\r
484 * @return Name der Default-Action
\r
486 public String defaultAction() {
\r
487 return defaultAction;
\r
491 * Gets the fields from a httprequest and matches them with the metadata from
\r
492 * the storage object. Returns the keys that match, with their values.
\r
494 * @return Map with the values
\r
496 public Map getIntersectingValues(HttpServletRequest aRequest, StorageObject theStorage)
\r
497 throws ServletModuleExc, ServletModuleFailure {
\r
500 HTTPRequestParser parser;
\r
503 parser = new HTTPRequestParser(aRequest);
\r
505 theFieldList = theStorage.getFields();
\r
507 Map withValues = new HashMap();
\r
508 String aField, aValue;
\r
510 for (int i = 0; i < theFieldList.size(); i++) {
\r
511 aField = (String) theFieldList.get(i);
\r
513 aValue = parser.getParameter(aField);
\r
514 if (aValue != null)
\r
515 withValues.put(aField, aValue);
\r
519 catch (Throwable e) {
\r
520 e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
\r
522 throw new ServletModuleFailure( "ServletModule.getIntersectingValues: " + e.getMessage(), e);
\r