1 /*
2 * $Id$
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21 package org.apache.struts.action;
22
23 import org.apache.struts.upload.MultipartRequestHandler;
24
25 import jakarta.servlet.ServletRequest;
26 import jakarta.servlet.http.HttpServletRequest;
27
28 import java.io.Serializable;
29
30 /**
31 * <p>An <strong>ActionForm</strong> is a JavaBean optionally associated with
32 * one or more <code>ActionMappings</code>. Such a bean will have had its
33 * properties initialized from the corresponding request parameters before the
34 * corresponding <code>Action.execute</code> method is called.</p>
35 *
36 * <p>When the properties of this bean have been populated, but before the
37 * <code>execute</code> method of the <code>Action</code> is called, this
38 * bean's <code>validate</code> method will be called, which gives the bean a
39 * chance to verify that the properties submitted by the user are correct and
40 * valid. If this method finds problems, it returns an error messages object
41 * that encapsulates those problems, and the controller servlet will return
42 * control to the corresponding input form. Otherwise, the
43 * <code>validate</code> method returns <code>null</code>, indicating that
44 * everything is acceptable and the corresponding <code>Action.execute</code>
45 * method should be called.</p>
46 *
47 * <p>This class must be subclassed in order to be instantiated. Subclasses
48 * should provide property getter and setter methods for all of the bean
49 * properties they wish to expose, plus override any of the public or
50 * protected methods for which they wish to provide modified functionality.
51 * </p>
52 *
53 * <p>Because ActionForms are JavaBeans, subclasses should also implement
54 * <code>Serializable</code>, as required by the JavaBean specification. Some
55 * containers require that an object meet all JavaBean requirements in order
56 * to use the introspection API upon which ActionForms rely.</p>
57 *
58 * @version $Rev$ $Date: 2005-11-12 08:14:24 -0500 (Sat, 12 Nov 2005)
59 * $
60 */
61 public abstract class ActionForm implements Serializable {
62 private static final long serialVersionUID = -7986260744524429895L;
63
64 // ----------------------------------------------------- Instance Variables
65
66 /**
67 * <p>The servlet instance to which we are attached.</p>
68 */
69 protected transient ActionServlet servlet = null;
70
71 /**
72 * <p>The MultipartRequestHandler for this form, can be
73 * <code>null</code>.</p>
74 */
75 protected transient MultipartRequestHandler multipartRequestHandler;
76
77 // ------------------------------------------------------------- Properties
78
79 /**
80 * <p>Return the servlet instance to which we are attached.</p>
81 *
82 * @return The servlet instance to which we are attached.
83 */
84 protected ActionServlet getServlet() {
85 return (this.servlet);
86 }
87
88 /**
89 * <p>Return the controller servlet instance to which we are attached. as
90 * an <code>ActionServletWrapper</code>.</p>
91 *
92 * @return An instance of {@link ActionServletWrapper}
93 * @see ActionServletWrapper
94 * @since Struts 1.0.1
95 */
96 public ActionServletWrapper getServletWrapper() {
97 return new ActionServletWrapper(getServlet());
98 }
99
100 /**
101 * <p>Return the <code>MultipartRequestHandler</code> for this form The
102 * reasoning behind this is to give form bean developers control over the
103 * lifecycle of their multipart requests through the use of the
104 * <code>finish</code> and/or <code>rollback</code> methods of
105 * <code>MultipartRequestHandler</code>. This method will return
106 * <code>null</code> if this form's enctype is not "multipart/form-data".
107 * </p>
108 *
109 * @return The {@link org.apache.struts.upload.MultipartRequestHandler}
110 * for this form.
111 * @see org.apache.struts.upload.MultipartRequestHandler
112 */
113 public MultipartRequestHandler getMultipartRequestHandler() {
114 return multipartRequestHandler;
115 }
116
117 /**
118 * <p>Set the servlet instance to which we are attached (if
119 * <code>servlet</code> is non-null).</p>
120 *
121 * @param servlet The new controller servlet, if any
122 */
123 public void setServlet(ActionServlet servlet) {
124 this.servlet = servlet;
125
126 // :FIXME: Should this be releasing resources?
127 }
128
129 /**
130 * <p>Set the Handler provided for use in dealing with file uploads.</p>
131 *
132 * @param multipartRequestHandler The Handler to use for fileuploads.
133 */
134 public void setMultipartRequestHandler(
135 MultipartRequestHandler multipartRequestHandler) {
136 this.multipartRequestHandler = multipartRequestHandler;
137 }
138
139 // --------------------------------------------------------- Public Methods
140
141 /**
142 * <p>Can be used to reset all bean properties to their default state.
143 * This method is called before the properties are repopulated by the
144 * controller.</p>
145 *
146 * <p>The default implementation attempts to forward to the HTTP version
147 * of this method.</p>
148 *
149 * @param mapping The mapping used to select this instance
150 * @param request The servlet request we are processing
151 */
152 public void reset(ActionMapping mapping, ServletRequest request) {
153 try {
154 reset(mapping, (HttpServletRequest) request);
155 } catch (ClassCastException e) {
156 ; // FIXME: Why would this ever happen except a null
157 }
158 }
159
160 /**
161 * <p>Can be used to reset bean properties to their default state, as
162 * needed. This method is called before the properties are repopulated by
163 * the controller.</p>
164 *
165 * <p>The default implementation does nothing. In practice, the only
166 * properties that need to be reset are those which represent checkboxes
167 * on a session-scoped form. Otherwise, properties can be given initial
168 * values where the field is declared. </p>
169 *
170 * <p>If the form is stored in session-scope so that values can be
171 * collected over multiple requests (a "wizard"), you must be very careful
172 * of which properties, if any, are reset. As mentioned, session-scope
173 * checkboxes must be reset to false for any page where this property is
174 * set. This is because the client does not submit a checkbox value when
175 * it is clear (false). If a session-scoped checkbox is not proactively
176 * reset, it can never be set to false.</p>
177 *
178 * <p>This method is <strong>not</strong> the appropriate place to
179 * initialize form value for an "update" type page (this should be done in
180 * a setup Action). You mainly need to worry about setting checkbox values
181 * to false; most of the time you can leave this method unimplemented.
182 * </p>
183 *
184 * @param mapping The mapping used to select this instance
185 * @param request The servlet request we are processing
186 */
187 public void reset(ActionMapping mapping, HttpServletRequest request) {
188 // Default implementation does nothing
189 }
190
191 /**
192 * <p>Can be used to validate the properties that have been set for this
193 * non-HTTP request, and return an <code>ActionErrors</code> object that
194 * encapsulates any validation errors that have been found. If no errors
195 * are found, return <code>null</code> or an <code>ActionErrors</code>
196 * object with no recorded error messages.</p>
197 *
198 * <p>The default implementation attempts to forward to the HTTP version
199 * of this method.</p>
200 *
201 * @param mapping The mapping used to select this instance
202 * @param request The servlet request we are processing
203 * @return The set of validation errors, if validation failed; an empty
204 * set or <code>null</code> if validation succeeded.
205 */
206 public ActionErrors validate(ActionMapping mapping, ServletRequest request) {
207 try {
208 return (validate(mapping, (HttpServletRequest) request));
209 } catch (ClassCastException e) {
210 return (null);
211 }
212 }
213
214 /**
215 * <p>Can be used to validate the properties that have been set for this
216 * HTTP request, and return an <code>ActionErrors</code> object that
217 * encapsulates any validation errors that have been found. If no errors
218 * are found, return <code>null</code> or an <code>ActionErrors</code>
219 * object with no recorded error messages.</p>
220 *
221 * <p>The default implementation performs no validation and returns
222 * <code>null</code>. Subclasses must override this method to provide any
223 * validation they wish to perform.</p>
224 *
225 * @param mapping The mapping used to select this instance
226 * @param request The servlet request we are processing
227 * @return The set of validation errors, if validation failed; an empty
228 * set or <code>null</code> if validation succeeded.
229 * @see DynaActionForm
230 */
231 public ActionErrors validate(ActionMapping mapping,
232 HttpServletRequest request) {
233 return (null);
234 }
235 }