whoops^2
[mir.git] / source / mircoders / localizer / basic / MirBasicPostingSessionHandler.java
1 /*\r
2  * Copyright (C) 2001, 2002 The Mir-coders group\r
3  *\r
4  * This file is part of Mir.\r
5  *\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
10  *\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
15  *\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
19  *\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
29  */\r
30 package mircoders.localizer.basic;\r
31 \r
32 import java.util.HashMap;\r
33 import java.util.Iterator;\r
34 import java.util.List;\r
35 import java.util.Map;\r
36 import java.util.Random;\r
37 import java.util.Vector;\r
38 \r
39 import mir.config.MirPropertiesConfiguration;\r
40 import mir.log.LoggerWrapper;\r
41 import mir.session.Request;\r
42 import mir.session.Response;\r
43 import mir.session.Session;\r
44 import mir.session.SessionExc;\r
45 import mir.session.SessionFailure;\r
46 import mir.session.SessionHandler;\r
47 import mir.session.UploadedFile;\r
48 import mir.session.ValidationError;\r
49 import mir.session.ValidationHelper;\r
50 import mir.storage.StorageObject;\r
51 import mir.util.ExceptionFunctions;\r
52 import mircoders.global.MirGlobal;\r
53 import mircoders.module.ModuleMediaType;\r
54 \r
55 /**\r
56  *\r
57  * <p>Title: Experimental session handler for comment postings </p>\r
58  * <p>Description: </p>\r
59  * <p>Copyright: Copyright (c) 2003</p>\r
60  * <p>Company: </p>\r
61  * @author not attributable\r
62  * @version 1.0\r
63  */\r
64 \r
65 public abstract class MirBasicPostingSessionHandler implements SessionHandler {\r
66   protected LoggerWrapper logger;\r
67   protected MirPropertiesConfiguration configuration;\r
68 \r
69   private String normalResponseGenerator;\r
70   private String dupeResponseGenerator;\r
71   private String unsupportedMediaTypeResponseGenerator;\r
72   private String finalResponseGenerator;\r
73 \r
74 \r
75   public MirBasicPostingSessionHandler() {\r
76     logger = new LoggerWrapper("Localizer.OpenPosting");\r
77     try {\r
78       configuration = MirPropertiesConfiguration.instance();\r
79     }\r
80     catch (Throwable t) {\r
81       logger.fatal("Cannot load configuration: " + t.toString());\r
82 \r
83       throw new RuntimeException("Cannot load configuration: " + t.toString());\r
84     }\r
85   }\r
86 \r
87   protected void setNormalResponseGenerator(String aGenerator) {\r
88     normalResponseGenerator = aGenerator;\r
89   }\r
90 \r
91   protected void setResponseGenerators(String aNormalResponseGenerator, String aDupeResponseGenerator,\r
92         String anUnsupportedMediaTypeResponseGenerator, String aFinalResponseGenerator) {\r
93     setNormalResponseGenerator(aNormalResponseGenerator);\r
94     dupeResponseGenerator = aDupeResponseGenerator;\r
95     unsupportedMediaTypeResponseGenerator = anUnsupportedMediaTypeResponseGenerator;\r
96     finalResponseGenerator = aFinalResponseGenerator;\r
97   }\r
98 \r
99   public void processRequest(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {\r
100     if (MirGlobal.abuse().getOpenPostingDisabled()) {\r
101       makeOpenPostingDisabledResponse(aRequest, aSession, aResponse);\r
102       aSession.terminate();\r
103     }\r
104     else {\r
105       if (aSession.getAttribute("initialRequest") == null) {\r
106         initialRequest(aRequest, aSession, aResponse);\r
107         aSession.setAttribute("initialRequest", "no");\r
108       }\r
109       else {\r
110         subsequentRequest(aRequest, aSession, aResponse);\r
111       }\r
112     }\r
113   };\r
114 \r
115   protected void initialRequest(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {\r
116     initializeSession(aRequest, aSession);\r
117     initializeResponseData(aRequest, aSession, aResponse);\r
118     makeInitialResponse(aRequest, aSession, aResponse);\r
119   }\r
120 \r
121   public void subsequentRequest(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {\r
122     try {\r
123       try {\r
124         List validationErrors = new Vector();\r
125 \r
126         if (!shouldProcessRequest(aRequest, aSession, validationErrors)) {\r
127           initializeResponseData(aRequest, aSession, aResponse);\r
128           makeResponse(aRequest, aSession, aResponse, validationErrors);\r
129         }\r
130         else {\r
131           preProcessRequest(aRequest, aSession);\r
132           Iterator i = aRequest.getUploadedFiles().iterator();\r
133           while (i.hasNext()) {\r
134             processUploadedFile(aRequest, aSession, (UploadedFile) i.next());\r
135           }\r
136           postProcessRequest(aRequest, aSession);\r
137           initializeResponseData(aRequest, aSession, aResponse);\r
138           makeFinalResponse(aRequest, aSession, aResponse);\r
139           aSession.terminate();\r
140         }\r
141       }\r
142       catch (Throwable t) {\r
143         initializeResponseData(aRequest, aSession, aResponse);\r
144         makeErrorResponse(aRequest, aSession, aResponse, t);\r
145         aSession.terminate();\r
146       }\r
147     }\r
148     catch (Throwable t) {\r
149       aSession.terminate();\r
150 \r
151       throw new SessionFailure(t);\r
152     }\r
153   }\r
154 \r
155   protected void initializeSession(Request aRequest, Session aSession) throws SessionExc, SessionFailure {\r
156     if (MirGlobal.abuse().getOpenPostingPassword()) {\r
157       String password = (String) aSession.getAttribute("password");\r
158       if (password==null) {\r
159         password = generateOnetimePassword();\r
160         aSession.setAttribute("password", password);\r
161       }\r
162     }\r
163     else {\r
164       aSession.deleteAttribute("password");\r
165     }\r
166 \r
167     logger.debug("referrer = " + aRequest.getHeader("Referer"));\r
168 \r
169     aSession.setAttribute("referer", aRequest.getHeader("Referer"));\r
170   }\r
171 \r
172   protected void initializeResponseData(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {\r
173     int nrMediaItems = configuration.getInt("ServletModule.OpenIndy.DefaultMediaUploadItems", 5);\r
174 \r
175     if (aSession.getAttribute("nrmediaitems")!=null) {\r
176       nrMediaItems = ((Integer) aSession.getAttribute("nrmediaitems")).intValue();\r
177     }\r
178     try {\r
179       nrMediaItems = Math.min(configuration.getInt("ServletModule.OpenIndy.MaxMediaUploadItems"), Integer.parseInt(aRequest.getParameter("nrmediaitems")));\r
180     }\r
181     catch (Throwable t) {\r
182     }\r
183     aSession.setAttribute("nrmediaitems", new Integer(nrMediaItems));\r
184 \r
185     List mediaItems = new Vector();\r
186     int i=0;\r
187 \r
188     while (i<nrMediaItems) {\r
189       i++;\r
190       mediaItems.add(new Integer(i));\r
191     }\r
192 \r
193     aResponse.setResponseValue("nrmediaitems", new Integer(nrMediaItems));\r
194     aResponse.setResponseValue("mediaitems", mediaItems);\r
195     aResponse.setResponseValue("password", aSession.getAttribute("password"));\r
196     aResponse.setResponseValue("referer", aSession.getAttribute("referer"));\r
197     aResponse.setResponseValue("errors", null);\r
198   }\r
199 \r
200   protected void makeInitialResponse(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {\r
201     aResponse.setResponseGenerator(normalResponseGenerator);\r
202   };\r
203 \r
204   protected void makeResponse(Request aRequest, Session aSession, Response aResponse, List anErrors) throws SessionExc, SessionFailure {\r
205     aResponse.setResponseValue("errors", anErrors);\r
206     aResponse.setResponseGenerator(normalResponseGenerator);\r
207   };\r
208 \r
209   protected void makeFinalResponse(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {\r
210     aResponse.setResponseGenerator(finalResponseGenerator);\r
211   };\r
212 \r
213   protected void makeErrorResponse(Request aRequest, Session aSession, Response aResponse, Throwable anError) throws SessionExc, SessionFailure {\r
214     anError.printStackTrace();\r
215     Throwable rootCause = ExceptionFunctions.traceCauseException(anError);\r
216 \r
217     if (rootCause instanceof DuplicatePostingExc)\r
218       aResponse.setResponseGenerator(dupeResponseGenerator);\r
219     if (rootCause instanceof ModuleMediaType.UnsupportedMimeTypeExc) {\r
220       aResponse.setResponseValue("mimetype", ((ModuleMediaType.UnsupportedMimeTypeExc) rootCause).getMimeType());\r
221       aResponse.setResponseGenerator(unsupportedMediaTypeResponseGenerator);\r
222     }\r
223     else {\r
224       aResponse.setResponseValue("errorstring", anError.getMessage());\r
225       aResponse.setResponseGenerator(configuration.getString("Localizer.OpenSession.ErrorTemplate"));\r
226     }\r
227   };\r
228 \r
229   protected void makeOpenPostingDisabledResponse(Request aRequest, Session aSession, Response aResponse) {\r
230     aResponse.setResponseGenerator(configuration.getString("ServletModule.OpenIndy.PostingDisabledTemplate"));\r
231   }\r
232 \r
233   protected void preProcessRequest(Request aRequest, Session aSession) throws SessionExc, SessionFailure {\r
234   };\r
235   public void processUploadedFile(Request aRequest, Session aSession, UploadedFile aFile) throws SessionExc, SessionFailure {\r
236   };\r
237   protected void postProcessRequest(Request aRequest, Session aSession) throws SessionExc, SessionFailure {\r
238   };\r
239 \r
240   protected boolean shouldProcessRequest(Request aRequest, Session aSession, List aValidationErrors) throws SessionExc, SessionFailure {\r
241     if (aRequest.getParameter("post")==null)\r
242       return false;\r
243     else {\r
244       validate(aValidationErrors, aRequest, aSession);\r
245       return (aValidationErrors == null || aValidationErrors.size() == 0);\r
246     }\r
247   }\r
248 \r
249   protected void validate(List aResults, Request aRequest, Session aSession) throws SessionExc, SessionFailure {\r
250     String password = (String) aSession.getAttribute("password");\r
251 \r
252     if (password!=null) {\r
253       String submittedPassword= aRequest.getParameter("password").trim();\r
254 \r
255       if (!password.equals(submittedPassword)) {\r
256         aResults.add(new ValidationError("password", "passwordmismatch"));\r
257       }\r
258     }\r
259   }\r
260 \r
261 \r
262   /**\r
263    * Method to generate a one-time password\r
264    *\r
265    * @return a password, to be used once\r
266    */\r
267 \r
268   protected String generateOnetimePassword() {\r
269     Random r = new Random();\r
270     int random = r.nextInt();\r
271 \r
272     long l = System.currentTimeMillis();\r
273 \r
274     l = (l*l*l*l)/random;\r
275     if (l<0)\r
276       l = l * -1;\r
277 \r
278     String returnString = ""+l;\r
279 \r
280     return returnString.substring(5);\r
281   }\r
282 \r
283 \r
284   /**\r
285    *\r
286    * @param aRequest\r
287    * @param aStorage\r
288    * @return\r
289    * @throws SessionExc\r
290    * @throws SessionFailure\r
291    */\r
292 \r
293   protected static final Map getIntersectingValues(Request aRequest, StorageObject aStorage) throws SessionExc, SessionFailure {\r
294     Map result = new HashMap();\r
295 \r
296     Iterator i = aStorage.getFields().iterator();\r
297 \r
298     while (i.hasNext()) {\r
299       String fieldName = (String) i.next();\r
300       Object value = aRequest.getParameter(fieldName);\r
301       if (value != null)\r
302         result.put(fieldName, value);\r
303     }\r
304 \r
305     return result;\r
306   }\r
307 \r
308   protected static class DuplicatePostingExc extends SessionExc {\r
309     public DuplicatePostingExc(String aMessage) {\r
310       super(aMessage);\r
311     }\r
312   }\r
313 \r
314 }\r