KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > core > controller > DefaultForm


1 /* ====================================================================
2  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3  *
4  * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by Jcorporate Ltd.
21  * (http://www.jcorporate.com/)."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. "Jcorporate" and product names such as "Expresso" must
26  * not be used to endorse or promote products derived from this
27  * software without prior written permission. For written permission,
28  * please contact info@jcorporate.com.
29  *
30  * 5. Products derived from this software may not be called "Expresso",
31  * or other Jcorporate product names; nor may "Expresso" or other
32  * Jcorporate product names appear in their name, without prior
33  * written permission of Jcorporate Ltd.
34  *
35  * 6. No product derived from this software may compete in the same
36  * market space, i.e. framework, without prior written permission
37  * of Jcorporate Ltd. For written permission, please contact
38  * partners@jcorporate.com.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Jcorporate Ltd. Contributions back
56  * to the project(s) are encouraged when you make modifications.
57  * Please send them to support@jcorporate.com. For more information
58  * on Jcorporate Ltd. and its products, please see
59  * <http://www.jcorporate.com/>.
60  *
61  * Portions of this software are based upon other open source
62  * products and are subject to their respective licenses.
63  */

64
65 package com.jcorporate.expresso.core.controller;
66
67 import com.jcorporate.expresso.core.misc.StringUtil;
68 import com.jcorporate.expresso.core.misc.URLUTF8Encoder;
69 import org.apache.commons.logging.Log;
70 import org.apache.commons.logging.LogFactory;
71 import org.apache.commons.validator.Validator;
72 import org.apache.commons.validator.ValidatorException;
73 import org.apache.commons.validator.ValidatorResources;
74 import org.apache.commons.validator.ValidatorResults;
75 import org.apache.struts.action.ActionErrors;
76 import org.apache.struts.action.ActionForm;
77 import org.apache.struts.action.ActionMapping;
78 import org.apache.struts.validator.Resources;
79
80 import javax.servlet.ServletContext JavaDoc;
81 import javax.servlet.ServletRequest JavaDoc;
82 import javax.servlet.http.HttpServletRequest JavaDoc;
83 import java.io.Serializable JavaDoc;
84 import java.util.Enumeration JavaDoc;
85 import java.util.Hashtable JavaDoc;
86 import java.util.Iterator JavaDoc;
87 import java.util.Locale JavaDoc;
88 import java.util.StringTokenizer JavaDoc;
89
90
91 /**
92  * * <p> This class is a bridge between Expresso's Controller system and the Struts
93  * Action Form. It is automatically utilized by Expresso and you don't have
94  * to directly deal with it. </p>
95  *
96  * @author Michael Nash
97  * @since Expresso 4.0
98  */

99 public class DefaultForm
100         extends ActionForm
101         implements Serializable JavaDoc, StateForm {
102     private Hashtable JavaDoc formData = new Hashtable JavaDoc();
103     private Hashtable JavaDoc formAttributes = null;
104
105     public DefaultForm() {
106     }
107
108     public ActionErrors validate(ActionMapping mapping, ServletRequest JavaDoc request) {
109         return null;
110     }
111
112     public void saveForm(ControllerRequest req)
113             throws ControllerException {
114         formData.clear();
115         formData.putAll(req.getParameters());
116     }
117
118     public void restoreForm(ControllerRequest req)
119             throws ControllerException {
120         String JavaDoc oneKey = null;
121
122         for (Enumeration JavaDoc e = formData.elements(); e.hasMoreElements();) {
123             oneKey = (String JavaDoc) e.nextElement();
124             req.setParameter(oneKey, (String JavaDoc) formData.get(oneKey));
125         }
126     }
127
128     public Hashtable JavaDoc getFields() {
129         return formData;
130     }
131
132     public void clear() {
133         formData.clear();
134     }
135
136     public synchronized void setAttribute(String JavaDoc fieldName, Object JavaDoc newValue) {
137         if (formAttributes == null) {
138             formAttributes = new Hashtable JavaDoc();
139         }
140
141         formAttributes.put(fieldName, newValue);
142     }
143
144     public synchronized void setField(String JavaDoc fieldName, String JavaDoc fieldValue)
145             throws ControllerException {
146
147         if (fieldName == null || fieldName.length() == 0) {
148             throw new ControllerException("Field name cannot be null here");
149         }
150         formData.put(fieldName, fieldValue);
151     }
152
153     /**
154      *
155      */

156     public synchronized void setUsingHashtableParameters(Hashtable JavaDoc parameters) throws ControllerException {
157         for (Iterator JavaDoc i = parameters.keySet().iterator(); i.hasNext();) {
158             String JavaDoc key = (String JavaDoc) i.next();
159             setField(key, (String JavaDoc) parameters.get(key));
160         }
161     }
162
163     /**
164      * Returns the attribute that has been set for a particular field OR
165      * null if it doesn't exist.
166      *
167      * @throws ControllerException if fieldName is blank.
168      */

169     public Object JavaDoc getAttribute(String JavaDoc fieldName) throws ControllerException {
170         if (formAttributes == null) {
171             return null;
172         }
173
174         if (fieldName == null || fieldName.length() == 0) {
175             throw new ControllerException("Field name cannot be null here");
176         }
177
178         return formAttributes.get(fieldName);
179
180     }
181
182     /**
183      * Returns the attributes Hashtable.
184      */

185     public Hashtable JavaDoc getAttributes() {
186
187         return formAttributes;
188
189     }
190
191     public String JavaDoc getField(String JavaDoc fieldName)
192             throws ControllerException {
193         if (StringUtil.notNull(fieldName).equals("")) {
194             throw new ControllerException("Field name cannot be null here");
195         }
196
197         return (String JavaDoc) formData.get(fieldName);
198     }
199
200     /**
201      * Validate the properties that have been set from this HTTP request,
202      * and return an <code>ActionErrors</code> object that encapsulates any
203      * validation errors that have been found. If no errors are found, return
204      * <code>null</code> or an <code>ActionErrors</code> object with no
205      * recorded error messages.
206      *
207      * @param mapping The mapping used to select this instance.
208      * @param request The servlet request we are processing.
209      * @return ActionErrors containing validation errors.
210      */

211     /**
212      * @todo add this method so validation can be called from an external State *RD* Mon Jul 27 2004
213      */

214     public ActionErrors validate(ActionMapping mapping,
215                                  HttpServletRequest JavaDoc request) {
216
217         ServletContext JavaDoc application = getServlet().getServletContext();
218         ActionErrors errors = new ErrorCollection();
219
220         try {
221             Validator validator =
222                     initValidator(getState(request), this,
223                             application, request,
224                             errors, page);
225
226             validatorResults = validator.validate();
227         } catch (ControllerException ex) {
228         } catch (ValidatorException e) {
229             log.error(e.getMessage(), e);
230         }
231
232         return errors;
233     }
234
235     /**
236      * Validate the properties that have been set from this HTTP request,
237      * and return an <code>ActionErrors</code> object that encapsulates any
238      * validation errors that have been found. If no errors are found, return
239      * <code>null</code> or an <code>ActionErrors</code> object with no
240      * recorded error messages.
241      *
242      * @param mapping The mapping used to select this instance.
243      * @param request The servlet request we are processing.
244      * @return ActionErrors containing validation errors.
245      */

246     /**
247      * @todo add this method so the form can be validated with Struts Validator *RD* Mon Jul 27 2004
248      */

249     public ErrorCollection validate(ControllerRequest request) {
250         if (request instanceof ServletControllerRequest) {
251             ServletControllerRequest scr = (ServletControllerRequest) request;
252             return (ErrorCollection) this.validate(scr.getMapping(), (HttpServletRequest JavaDoc) scr.getServletRequest());
253         } else {
254             return new ErrorCollection();
255         }
256     }
257
258
259     /**
260      * Get the state requested by the transition button in the form
261      * @param params the hashtable of parameters to parse
262      * @return String
263      * @throws ControllerException
264      */

265     /** @todo add this method so Struts Validator can find the formset containing the rules *RD* Mon Jul 27 2004 */
266     /**
267      * @todo I'm sure there must be a more elegant way for doing this *RD* Mon Jul 27 2004
268      */

269     private static String JavaDoc getState(HttpServletRequest JavaDoc request) throws
270             ControllerException {
271
272         log.debug("Adding button parameters");
273
274         String JavaDoc oneParamName = null;
275         Object JavaDoc oneParamValue = null;
276         boolean gotControllerFromButton = false;
277
278         for (Enumeration JavaDoc e = request.getParameterNames(); e.hasMoreElements();) {
279             oneParamName = (String JavaDoc) e.nextElement();
280             oneParamValue = StringUtil.notNull(request.getParameter(oneParamName));
281
282             if (oneParamName.startsWith("button_")) {
283
284                 //We add a special parameter to the collection, which
285
//is simply "button"="name_ofButton"
286
String JavaDoc buttonName = oneParamName.substring(oneParamName.indexOf("_") + 1);
287
288                 /**
289                  * button names come in from the browser like
290
291                  button_promptLogin.y
292                  button_promptLogin.x
293
294                  cut off those .x, .y trailers
295                  */

296                 if (buttonName.endsWith(".x")) {
297                     buttonName = buttonName.substring(0, buttonName.length() - 2);
298                 }
299                 if (buttonName.endsWith(".y")) {
300                     buttonName = buttonName.substring(0, buttonName.length() - 2);
301                 }
302
303                 if (log.isDebugEnabled()) {
304                     log.debug("There is a button parameter called '" +
305                             buttonName + "'");
306                 }
307
308                 /* pick up the corresponding parameter string, if any */
309                 String JavaDoc paramString = (String JavaDoc) request.getParameter(buttonName +
310                         "_params");
311
312                 if (paramString != null) {
313                     log.debug("Button parameters:");
314
315                     //We first check to see if the button parameters string is encoded. If it is, we decode it
316
//before parsing it.
317
String JavaDoc encodeType = (String JavaDoc) request.getParameter(buttonName +
318                             "_encoding");
319
320                     if ("u".equals(encodeType)) {
321
322                         //this param string has been URL encoded
323
try {
324                             paramString = URLUTF8Encoder.decode(paramString);
325                         } catch (Exception JavaDoc ex) {
326                             log.error("Could not URLDecode: " + paramString,
327                                     ex);
328                         }
329                     }
330                     /* if the param string for the button was encoded */
331
332                     /* parse it into a hashtable */
333                     StringTokenizer JavaDoc stkpm = null;
334                     stkpm = new StringTokenizer JavaDoc(paramString, "&");
335
336                     while (stkpm.hasMoreTokens()) {
337                         String JavaDoc pairValue = stkpm.nextToken();
338
339                         //This decode is paired up with the getParamString() method's encode() in
340
//the Transition class.
341
try {
342                             pairValue = URLUTF8Encoder.decode(pairValue);
343                         } catch (Exception JavaDoc ex) {
344                             log.error("Could not URLDecode: " + pairValue, ex);
345                         }
346
347                         String JavaDoc paramName = pairValue;
348                         String JavaDoc paramValue = "";
349                         int position = pairValue.indexOf("=");
350                         if (position != -1) {
351                             paramName = pairValue.substring(0, position);
352                             position++; //ignore the '='
353
if (position < pairValue.length()) {
354                                 paramValue = pairValue.substring(position);
355                             }
356                         }
357
358                         if (paramName.equals(Controller.CONTROLLER_PARAM_KEY)) {
359                             gotControllerFromButton = true;
360                         }
361                         if (log.isDebugEnabled()) {
362                             log.debug("Parameter '" + paramName + "', value '"
363                                     + paramValue + "'");
364                         }
365                         if (paramName.equals(Controller.STATE_PARAM_KEY)) {
366                             return paramValue;
367                         }
368
369                     }
370                     /* while more parameters in the button param string */
371
372                     log.debug("End button parameters");
373                 } else { /* if the button param string exists */
374                     throw new ControllerException("Button '" + buttonName +
375                             "' was clicked, but no " +
376                             "button parameters field called '" +
377                             buttonName +
378                             "_params' was found.");
379                 }
380             }
381             /* if this param is a buitton */
382
383         }
384         /* for each of the parameters */
385
386         return "";
387     }
388
389     /**
390      * Initialize the <code>Validator</code> to perform validation.
391      *
392      * @param key The key that the validation rules are under (the form elements
393      * name attribute).
394      * @param bean The bean validation is being performed on.
395      * @param application servlet context
396      * @param request The current request object.
397      * @param errors The object any errors will be stored in.
398      * @param page This in conjunction with the page property of a
399      * <code>Field<code> can control the processing of fields. If the field's
400      * page is less than or equal to this page value, it will be processed.
401      */

402     /**
403      * @todo add this method for Struts Validator to work *RD* Mon Jul 27 2004
404      */

405     public Validator initValidator(String JavaDoc key,
406                                    Object JavaDoc bean,
407                                    ServletContext JavaDoc application,
408                                    HttpServletRequest JavaDoc request,
409                                    ActionErrors errors,
410                                    int page) {
411
412         ValidatorResources resources = Resources.getValidatorResources(application,
413                 request);
414
415         Locale JavaDoc locale = Resources.getLocale(request);
416
417         Validator validator = new Validator(resources, key);
418         validator.setUseContextClassLoader(true);
419
420         validator.setPage(page);
421
422         validator.addResource(Resources.
423                 SERVLET_CONTEXT_KEY, application);
424         validator.addResource(Resources.
425                 HTTP_SERVLET_REQUEST_KEY, request);
426         validator.addResource(Validator.LOCALE_KEY, locale);
427         validator.addResource(Resources.
428                 ACTION_ERRORS_KEY, errors);
429         validator.addResource(Validator.BEAN_KEY, bean);
430
431         return validator;
432     }
433
434     /**
435      * Used to indicate the current page of a multi-page form.
436      */

437     /**
438      * @todo Struts Validator requires this variable to exist *RD* Mon Jul 27 2004
439      */

440     protected int page = 0;
441
442     /**
443      * The results returned from the validation performed
444      * by the <code>Validator</code>.
445      */

446     /**
447      * @todo Struts Validator requires this variable to exist *RD* Mon Jul 27 2004
448      */

449     protected ValidatorResults validatorResults = null;
450
451     /**
452      * Commons Logging instance.
453      */

454     /**
455      * @todo Struts Validator requires this variable to exist *RD* Mon Jul 27 2004
456      */

457     private static Log log = LogFactory.getLog(DefaultForm.class);
458
459 }
460
Popular Tags