update of the open session system: articles can now also be posted
[mir.git] / source / mircoders / localizer / basic / MirBasicPostingSessionHandler.java
1 /*
2  * Copyright (C) 2001, 2002 The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with  any library licensed under the Apache Software License,
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23  * (or with modified versions of the above that use the same license as the above),
24  * and distribute linked combinations including the two.  You must obey the
25  * GNU General Public License in all respects for all of the code used other than
26  * the above mentioned libraries.  If you modify this file, you may extend this
27  * exception to your version of the file, but you are not obligated to do so.
28  * If you do not wish to do so, delete this exception statement from your version.
29  */
30 package mircoders.localizer.basic;
31
32 import java.util.Arrays;
33 import java.util.HashMap;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Random;
38 import java.util.*;
39
40 import mir.config.MirPropertiesConfiguration;
41 import mir.entity.Entity;
42 import mir.log.LoggerWrapper;
43 import mir.session.Request;
44 import mir.session.Response;
45 import mir.session.Session;
46 import mir.session.SessionExc;
47 import mir.session.SessionFailure;
48 import mir.session.SessionHandler;
49 import mir.session.UploadedFile;
50 import mir.storage.StorageObject;
51 import mir.util.ExceptionFunctions;
52 import mircoders.entity.EntityComment;
53 import mircoders.global.MirGlobal;
54 import mircoders.media.MediaUploadProcessor;
55 import mircoders.module.ModuleComment;
56 import mircoders.storage.DatabaseComment;
57 import mircoders.storage.DatabaseCommentToMedia;
58 import mircoders.storage.DatabaseContent;
59
60 /**
61  *
62  * <p>Title: Experimental session handler for comment postings </p>
63  * <p>Description: </p>
64  * <p>Copyright: Copyright (c) 2003</p>
65  * <p>Company: </p>
66  * @author not attributable
67  * @version 1.0
68  */
69
70 public abstract class MirBasicPostingSessionHandler implements SessionHandler {
71   protected LoggerWrapper logger;
72   protected MirPropertiesConfiguration configuration;
73
74   public MirBasicPostingSessionHandler() {
75     logger = new LoggerWrapper("Localizer.OpenPosting");
76     try {
77       configuration = MirPropertiesConfiguration.instance();
78     }
79     catch (Throwable t) {
80       logger.fatal("Cannot load configuration: " + t.toString());
81
82       throw new RuntimeException("Cannot load configuration: " + t.toString());
83     }
84   }
85
86   public void processRequest(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
87     if (aSession.getAttribute("initialRequest")==null) {
88       initialRequest(aRequest, aSession, aResponse);
89       aSession.setAttribute("initialRequest", "no");
90     }
91     else {
92       subsequentRequest(aRequest, aSession, aResponse);
93     }
94   };
95
96   protected void initialRequest(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
97     initializeSession(aRequest, aSession);
98     initializeResponseData(aRequest, aSession, aResponse);
99     makeInitialResponse(aRequest, aSession, aResponse);
100   }
101
102   public void subsequentRequest(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
103     try {
104
105       try {
106         List validationErrors = new Vector();
107
108         if (!shouldProcessRequest(aRequest, aSession, validationErrors)) {
109           initializeResponseData(aRequest, aSession, aResponse);
110           makeResponse(aRequest, aSession, aResponse, validationErrors);
111         }
112         else {
113           preProcessRequest(aRequest, aSession);
114           Iterator i = aRequest.getUploadedFiles().iterator();
115           while (i.hasNext()) {
116             processUploadedFile(aRequest, aSession, (UploadedFile) i.next());
117           }
118           postProcessRequest(aRequest, aSession);
119           initializeResponseData(aRequest, aSession, aResponse);
120           makeFinalResponse(aRequest, aSession, aResponse);
121           aSession.terminate();
122         }
123       }
124       catch (Throwable t) {
125         initializeResponseData(aRequest, aSession, aResponse);
126         makeErrorResponse(aRequest, aSession, aResponse, t);
127         aSession.terminate();
128       }
129     }
130     catch (Throwable t) {
131       aSession.terminate();
132
133       throw new SessionFailure(t);
134     }
135   }
136
137   protected void initializeSession(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
138     if (MirGlobal.abuse().getOpenPostingPassword()) {
139       String password = (String) aSession.getAttribute("password");
140       if (password==null) {
141         password = generateOnetimePassword();
142         aSession.setAttribute("password", password);
143       }
144     }
145     else {
146       aSession.deleteAttribute("password");
147     }
148
149     logger.debug("referrer = " + aRequest.getHeader("Referer"));
150
151     aSession.setAttribute("referer", aRequest.getHeader("Referer"));
152     aSession.setAttribute("nrmediaitems",
153         new Integer(configuration.getInt("ServletModule.OpenIndy.DefaultMediaUploadItems")));
154   }
155
156   protected void initializeResponseData(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
157     int nrMediaItems = ((Integer) aSession.getAttribute("nrmediaitems")).intValue();
158     List mediaItems = new Vector();
159     int i=0;
160
161     while (i<nrMediaItems) {
162       i++;
163       mediaItems.add(new Integer(i));
164     }
165
166     aResponse.setResponseValue("nrmediaitems", new Integer(nrMediaItems));
167     aResponse.setResponseValue("mediaitems", mediaItems);
168     aResponse.setResponseValue("password", aSession.getAttribute("password"));
169     aResponse.setResponseValue("referer", aSession.getAttribute("referer"));
170     aResponse.setResponseValue("errors", null);
171   }
172
173   protected abstract void makeInitialResponse(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure;
174   protected abstract void makeResponse(Request aRequest, Session aSession, Response aResponse, List anErrors) throws SessionExc, SessionFailure;
175   protected abstract void makeFinalResponse(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure;
176
177   protected void preProcessRequest(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
178   };
179   public void processUploadedFile(Request aRequest, Session aSession, UploadedFile aFile) throws SessionExc, SessionFailure {
180   };
181   protected void postProcessRequest(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
182   };
183
184   protected boolean shouldProcessRequest(Request aRequest, Session aSession, List aValidationErrors) throws SessionExc, SessionFailure {
185     int nrMediaItems = ((Integer) aSession.getAttribute("nrmediaitems")).intValue();
186     try {
187       nrMediaItems = Math.min(configuration.getInt("ServletModule.OpenIndy.MaxMediaUploadItems"), Integer.parseInt(aRequest.getParameter("nrmediaitems")));
188     }
189     catch (Throwable t) {
190     }
191
192     aSession.setAttribute("nrmediaitems", new Integer(nrMediaItems));
193
194     if (aRequest.getParameter("post")==null)
195       return false;
196     else {
197       validate(aValidationErrors, aRequest, aSession);
198       return (aValidationErrors == null || aValidationErrors.size() == 0);
199     }
200   }
201
202   protected void validate(List aResults, Request aRequest, Session aSession) throws SessionExc, SessionFailure {
203   }
204
205   protected void makeErrorResponse(Request aRequest, Session aSession, Response aResponse, Throwable anError) throws SessionExc, SessionFailure {
206     aResponse.setResponseGenerator(configuration.getString("Localizer.OpenSession.ErrorTemplate"));
207   };
208
209   /**
210    * Class that represents a validation error
211    *
212    * <p>Title: </p>
213    * <p>Description: </p>
214    * <p>Copyright: Copyright (c) 2003</p>
215    * <p>Company: </p>
216    * @author not attributable
217    * @version 1.0
218    */
219
220   public class ValidationError {
221     private String field;
222     private String message;
223     private List parameters;
224
225     public ValidationError(String aField, String aMessage) {
226       this (aField, aMessage, new String[] {});
227     }
228
229     public ValidationError(String aField, String aMessage, Object aParameter) {
230       this (aField, aMessage, new Object[] {aParameter});
231     }
232
233     public ValidationError(String aField, String aMessage, Object[] aParameters) {
234       field = aField;
235       message = aMessage;
236       parameters = Arrays.asList(aParameters);
237     }
238
239     public String getMessage() {
240       return message;
241     }
242
243     public String getField() {
244       return field;
245     }
246
247     public List getParameters() {
248       return parameters;
249     }
250   }
251
252   /**
253    * Convenience validation method to test wether a field has been filled in
254    *
255    * @param aRequest
256    * @param aFieldName
257    * @param anErrorMessageResource
258    * @param aValidationResults
259    * @return
260    */
261
262   protected boolean testFieldEntered(Request aRequest, String aFieldName, String anErrorMessageResource, List aValidationResults) {
263     Object value = aRequest.getParameter(aFieldName);
264     if (value==null || !(value instanceof String) || ((String) value).trim().length()==0) {
265       aValidationResults.add(new ValidationError(aFieldName, anErrorMessageResource));
266       return false;
267     }
268     else
269       return true;
270   }
271
272   /**
273    * Convenience validation method to test wether a field is numeric
274
275    * @param aRequest
276    * @param aFieldName
277    * @param anErrorMessageResource
278    * @param aValidationResults
279    * @return
280    */
281
282   protected boolean testFieldIsNumeric(Request aRequest, String aFieldName, String anErrorMessageResource, List aValidationResults) {
283     Object value = aRequest.getParameter(aFieldName);
284     if (value!=null) {
285       try {
286         Integer.parseInt((String) value);
287         return true;
288       }
289       catch (Throwable t) {
290         aValidationResults.add(new ValidationError(aFieldName, anErrorMessageResource));
291         return false;
292       }
293     }
294     return true;
295   }
296
297   /**
298    * Method to generate a one-time password
299    *
300    * @return a password, to be used once
301    */
302   protected String generateOnetimePassword() {
303     Random r = new Random();
304     int random = r.nextInt();
305
306     long l = System.currentTimeMillis();
307
308     l = (l*l*l*l)/random;
309     if (l<0)
310       l = l * -1;
311
312     String returnString = ""+l;
313
314     return returnString.substring(5);
315   }
316
317
318   /**
319    *
320    * @param aRequest
321    * @param aStorage
322    * @return
323    * @throws SessionExc
324    * @throws SessionFailure
325    */
326
327   protected static final Map getIntersectingValues(Request aRequest, StorageObject aStorage) throws SessionExc, SessionFailure {
328     Map result = new HashMap();
329
330     Iterator i = aStorage.getFields().iterator();
331
332     while (i.hasNext()) {
333       String fieldName = (String) i.next();
334       Object value = aRequest.getParameter(fieldName);
335       if (value != null)
336         result.put(fieldName, value);
337     }
338
339     return result;
340   }
341
342 }