001: /*
002: * $Id: ActionForm.java 471754 2006-11-06 14:55:09Z husted $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts.action;
022:
023: import org.apache.struts.upload.MultipartRequestHandler;
024:
025: import javax.servlet.ServletRequest;
026: import javax.servlet.http.HttpServletRequest;
027:
028: import java.io.Serializable;
029:
030: /**
031: * <p>An <strong>ActionForm</strong> is a JavaBean optionally associated with
032: * one or more <code>ActionMappings</code>. Such a bean will have had its
033: * properties initialized from the corresponding request parameters before the
034: * corresponding <code>Action.execute</code> method is called.</p>
035: *
036: * <p>When the properties of this bean have been populated, but before the
037: * <code>execute</code> method of the <code>Action</code> is called, this
038: * bean's <code>validate</code> method will be called, which gives the bean a
039: * chance to verify that the properties submitted by the user are correct and
040: * valid. If this method finds problems, it returns an error messages object
041: * that encapsulates those problems, and the controller servlet will return
042: * control to the corresponding input form. Otherwise, the
043: * <code>validate</code> method returns <code>null</code>, indicating that
044: * everything is acceptable and the corresponding <code>Action.execute</code>
045: * method should be called.</p>
046: *
047: * <p>This class must be subclassed in order to be instantiated. Subclasses
048: * should provide property getter and setter methods for all of the bean
049: * properties they wish to expose, plus override any of the public or
050: * protected methods for which they wish to provide modified functionality.
051: * </p>
052: *
053: * <p>Because ActionForms are JavaBeans, subclasses should also implement
054: * <code>Serializable</code>, as required by the JavaBean specification. Some
055: * containers require that an object meet all JavaBean requirements in order
056: * to use the introspection API upon which ActionForms rely.</p>
057: *
058: * @version $Rev: 471754 $ $Date: 2005-11-12 08:14:24 -0500 (Sat, 12 Nov 2005)
059: * $
060: */
061: public abstract class ActionForm implements Serializable {
062: // ----------------------------------------------------- Instance Variables
063:
064: /**
065: * <p>The servlet instance to which we are attached.</p>
066: */
067: protected transient ActionServlet servlet = null;
068:
069: /**
070: * <p>The MultipartRequestHandler for this form, can be
071: * <code>null</code>.</p>
072: */
073: protected transient MultipartRequestHandler multipartRequestHandler;
074:
075: // ------------------------------------------------------------- Properties
076:
077: /**
078: * <p>Return the servlet instance to which we are attached.</p>
079: *
080: * @return The servlet instance to which we are attached.
081: */
082: protected ActionServlet getServlet() {
083: return (this .servlet);
084: }
085:
086: /**
087: * <p>Return the controller servlet instance to which we are attached. as
088: * an <code>ActionServletWrapper</code>.</p>
089: *
090: * @return An instance of {@link ActionServletWrapper}
091: * @see ActionServletWrapper
092: * @since Struts 1.0.1
093: */
094: public ActionServletWrapper getServletWrapper() {
095: return new ActionServletWrapper(getServlet());
096: }
097:
098: /**
099: * <p>Return the <code>MultipartRequestHandler</code> for this form The
100: * reasoning behind this is to give form bean developers control over the
101: * lifecycle of their multipart requests through the use of the
102: * <code>finish</code> and/or <code>rollback</code> methods of
103: * <code>MultipartRequestHandler</code>. This method will return
104: * <code>null</code> if this form's enctype is not "multipart/form-data".
105: * </p>
106: *
107: * @return The {@link org.apache.struts.upload.MultipartRequestHandler}
108: * for this form.
109: * @see org.apache.struts.upload.MultipartRequestHandler
110: */
111: public MultipartRequestHandler getMultipartRequestHandler() {
112: return multipartRequestHandler;
113: }
114:
115: /**
116: * <p>Set the servlet instance to which we are attached (if
117: * <code>servlet</code> is non-null).</p>
118: *
119: * @param servlet The new controller servlet, if any
120: */
121: public void setServlet(ActionServlet servlet) {
122: this .servlet = servlet;
123:
124: // :FIXME: Should this be releasing resources?
125: }
126:
127: /**
128: * <p>Set the Handler provided for use in dealing with file uploads.</p>
129: *
130: * @param multipartRequestHandler The Handler to use for fileuploads.
131: */
132: public void setMultipartRequestHandler(
133: MultipartRequestHandler multipartRequestHandler) {
134: this .multipartRequestHandler = multipartRequestHandler;
135: }
136:
137: // --------------------------------------------------------- Public Methods
138:
139: /**
140: * <p>>Can be used to reset all bean properties to their default state.
141: * This method is called before the properties are repopulated by the
142: * controller.</p>
143: *
144: * <p>The default implementation attempts to forward to the HTTP version
145: * of this method.</p>
146: *
147: * @param mapping The mapping used to select this instance
148: * @param request The servlet request we are processing
149: */
150: public void reset(ActionMapping mapping, ServletRequest request) {
151: try {
152: reset(mapping, (HttpServletRequest) request);
153: } catch (ClassCastException e) {
154: ; // FIXME: Why would this ever happen except a null
155: }
156: }
157:
158: /**
159: * <p>Can be used to reset bean properties to their default state, as
160: * needed. This method is called before the properties are repopulated by
161: * the controller.</p>
162: *
163: * <p>The default implementation does nothing. In practice, the only
164: * properties that need to be reset are those which represent checkboxes
165: * on a session-scoped form. Otherwise, properties can be given initial
166: * values where the field is declared. </p>
167: *
168: * <p>If the form is stored in session-scope so that values can be
169: * collected over multiple requests (a "wizard"), you must be very careful
170: * of which properties, if any, are reset. As mentioned, session-scope
171: * checkboxes must be reset to false for any page where this property is
172: * set. This is because the client does not submit a checkbox value when
173: * it is clear (false). If a session-scoped checkbox is not proactively
174: * reset, it can never be set to false.</p>
175: *
176: * <p>This method is <strong>not</strong> the appropriate place to
177: * initialize form value for an "update" type page (this should be done in
178: * a setup Action). You mainly need to worry about setting checkbox values
179: * to false; most of the time you can leave this method unimplemented.
180: * </p>
181: *
182: * @param mapping The mapping used to select this instance
183: * @param request The servlet request we are processing
184: */
185: public void reset(ActionMapping mapping, HttpServletRequest request) {
186: // Default implementation does nothing
187: }
188:
189: /**
190: * <p>Can be used to validate the properties that have been set for this
191: * non-HTTP request, and return an <code>ActionErrors</code> object that
192: * encapsulates any validation errors that have been found. If no errors
193: * are found, return <code>null</code> or an <code>ActionErrors</code>
194: * object with no recorded error messages.</p>
195: *
196: * <p>The default implementation attempts to forward to the HTTP version
197: * of this method.</p>
198: *
199: * @param mapping The mapping used to select this instance
200: * @param request The servlet request we are processing
201: * @return The set of validation errors, if validation failed; an empty
202: * set or <code>null</code> if validation succeeded.
203: */
204: public ActionErrors validate(ActionMapping mapping,
205: ServletRequest request) {
206: try {
207: return (validate(mapping, (HttpServletRequest) request));
208: } catch (ClassCastException e) {
209: return (null);
210: }
211: }
212:
213: /**
214: * <p>Can be used to validate the properties that have been set for this
215: * HTTP request, and return an <code>ActionErrors</code> object that
216: * encapsulates any validation errors that have been found. If no errors
217: * are found, return <code>null</code> or an <code>ActionErrors</code>
218: * object with no recorded error messages.</p>
219: *
220: * <p>The default implementation performs no validation and returns
221: * <code>null</code>. Subclasses must override this method to provide any
222: * validation they wish to perform.</p>
223: *
224: * @param mapping The mapping used to select this instance
225: * @param request The servlet request we are processing
226: * @return The set of validation errors, if validation failed; an empty
227: * set or <code>null</code> if validation succeeded.
228: * @see DynaActionForm
229: */
230: public ActionErrors validate(ActionMapping mapping,
231: HttpServletRequest request) {
232: return (null);
233: }
234: }
|