001: /*
002: * $Id: BeanValidatorForm.java 472728 2006-11-09 01:10:58Z niallp $
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.validator;
022:
023: import org.apache.commons.beanutils.ConvertUtils;
024: import org.apache.commons.beanutils.DynaBean;
025: import org.apache.commons.beanutils.DynaClass;
026: import org.apache.commons.beanutils.WrapDynaBean;
027: import org.apache.commons.logging.Log;
028: import org.apache.commons.logging.LogFactory;
029: import org.apache.struts.action.ActionMapping;
030: import org.apache.struts.config.FormBeanConfig;
031:
032: import javax.servlet.http.HttpServletRequest;
033:
034: import java.io.Serializable;
035:
036: import java.lang.reflect.Array;
037:
038: import java.util.List;
039: import java.util.Map;
040:
041: /**
042: * <p>Struts <i>validator</i> <code>ActionForm</code> backed by either a
043: * <code>DynaBean</code> or POJO JavaBean.</p>
044: *
045: * <p>Passing a POJO JavaBean to the constructor will automatically create an
046: * associated <code>WrapDynaBean</code>. One use for this would be to migrate
047: * <i>view</i> objects from an existing system which, for the usual reasons,
048: * can't be changed to extend <ActionForm</code>.</p>
049: *
050: * <p>This form is based on the standard struts <code>ValidatorForm</code> for
051: * use with the <i>Validator</i> framework and validates either using the
052: * <i>name</i> from the Struts <code>ActionMapping</code> or the
053: * <code>ActionMapping</code>'s path depending on whether
054: * <code>pathValidation</code> is <code>true</code> or
055: * <code>false</code>.</p>
056: *
057: * <p><b>Note</b>: WrapDynaBean is NOT serializable. If you use this class
058: * with a WrapDynaBean (as described above), you should not store your form in
059: * session scope.</p>
060: */
061: public class BeanValidatorForm extends ValidatorForm implements
062: DynaBean, Serializable {
063: /**
064: * Commons Logging
065: */
066: protected static Log logger = LogFactory
067: .getLog(BeanValidatorForm.class);
068:
069: /**
070: * The <code>DynaBean</code> that this ActionForm is backed by.
071: */
072: protected DynaBean dynaBean;
073:
074: /**
075: * Indicates whether the ActionMapping's path should be used for the
076: * validation key.
077: */
078: protected boolean pathValidation = false;
079:
080: /**
081: * The name used to identify the ActionForm in the struts-config.xml
082: */
083: private String strutsConfigFormName;
084:
085: // ------------------- Constructor ----------------------------------
086:
087: /**
088: * Construct a new <code>BeanValidatorForm</code> with the specified
089: * bean.
090: */
091: public BeanValidatorForm(Object bean) {
092: if (bean instanceof DynaBean) {
093: dynaBean = (DynaBean) bean;
094: } else {
095: dynaBean = new WrapDynaBean(bean);
096: }
097: }
098:
099: // ------------------- Protected Methods ----------------------------------
100:
101: /**
102: * <p>Set whether this form should validate based on the
103: * <code>ActionMapping</code>'s path.</p>
104: */
105: protected void setPathValidation(boolean pathValidation) {
106: this .pathValidation = pathValidation;
107: }
108:
109: /**
110: * <p>Indicates whether this form should validate based on the
111: * <code>ActionMapping</code>'s path.</p>
112: */
113: protected boolean isPathValidation() {
114: return pathValidation;
115: }
116:
117: // ------------------- Public Methods ----------------------------------
118:
119: /**
120: * <p>Perform intialization of the ActionForm.</p>
121: * <p>This method is called when the form is created.</p>
122: *
123: * @since Struts 1.3.6
124: */
125: public void initialize(FormBeanConfig formBeanConfig) {
126: strutsConfigFormName = formBeanConfig.getName();
127: }
128:
129: /**
130: * Return name used to identify the ActionForm in the
131: * struts-config.xml.
132: *
133: * @since Struts 1.3.6
134: */
135: public String getStrutsConfigFormName() {
136: return strutsConfigFormName;
137: }
138:
139: /**
140: * <p>Return the <code>DynaBean</code> that this <code>ActionForm</code>
141: * is backed by.</p>
142: */
143: public DynaBean getDynaBean() {
144: return dynaBean;
145: }
146:
147: /**
148: * <p>Return the <code>Bean</code> that this <code>ActionForm</code> is
149: * backed by.</p>
150: *
151: * <p>If the <code>DynaBean</code> is a <code>WrapDynaBean</code> type
152: * then this method returns the 'Wrapped' POJO bean associated with it. If
153: * you require the actual <code>WrapDynaBean</code> then use the
154: * <code>getDynaBean()</code> method.</p>
155: */
156: public Object getInstance() {
157: if (dynaBean instanceof WrapDynaBean) {
158: return ((WrapDynaBean) dynaBean).getInstance();
159: }
160:
161: return dynaBean;
162: }
163:
164: /**
165: * <p>Return the size of an indexed or mapped property.</p>
166: */
167: public int size(String name) {
168: Object value = dynaBean.get(name);
169:
170: if (value == null) {
171: return 0;
172: }
173:
174: if (value instanceof Map) {
175: return ((Map) value).size();
176: }
177:
178: if (value instanceof List) {
179: return ((List) value).size();
180: }
181:
182: if ((value.getClass().isArray())) {
183: return Array.getLength(value);
184: }
185:
186: return 0;
187: }
188:
189: // ------------------- ValidatorForm Methods ----------------------------------
190:
191: /**
192: * Returns the Validation key
193: *
194: * @param mapping The mapping used to select this instance
195: * @param request The servlet request we are processing
196: * @return validation key to use
197: */
198: public String getValidationKey(ActionMapping mapping,
199: HttpServletRequest request) {
200: String validationKey = null;
201:
202: if (isPathValidation()) {
203: // Get the path replacing any slashes by underscore
204: validationKey = mapping.getPath();
205:
206: // Remove any leading slash
207: if (validationKey.charAt(0) == '/') {
208: validationKey = validationKey.substring(1);
209: }
210:
211: // Replace any slashes by underscore
212: if (validationKey.indexOf("/") > 0) {
213: validationKey = validationKey.replace('/', '_');
214: }
215: } else {
216: validationKey = mapping.getAttribute();
217: }
218:
219: if (logger.isDebugEnabled()) {
220: logger.debug("Validating ActionForm '" + mapping.getName()
221: + "' using key '" + validationKey
222: + "' for mapping '" + mapping.getPath() + "'");
223: }
224:
225: return validationKey;
226: }
227:
228: // ------------------- DynaBean Methods ----------------------------------
229:
230: /**
231: * Return the <code>DynaClass</code> instance that describes the set of
232: * properties available for this DynaBean.
233: */
234: public DynaClass getDynaClass() {
235: return dynaBean.getDynaClass();
236: }
237:
238: /**
239: * Return the value of a simple property with the specified name.
240: *
241: * @param name Name of the property whose value is to be retrieved
242: */
243: public Object get(String name) {
244: return dynaBean.get(name);
245: }
246:
247: /**
248: * Return the value of an indexed property with the specified name.
249: *
250: * @param name Name of the property whose value is to be retrieved
251: * @param index Index of the value to be retrieved
252: */
253: public Object get(String name, int index) {
254: return dynaBean.get(name, index);
255: }
256:
257: /**
258: * Return the value of a mapped property with the specified name, or
259: * <code>null</code> if there is no value for the specified key.
260: *
261: * @param name Name of the property whose value is to be retrieved
262: * @param key Key of the value to be retrieved
263: */
264: public Object get(String name, String key) {
265: return dynaBean.get(name, key);
266: }
267:
268: /**
269: * Set the value of a simple property with the specified name.
270: *
271: * @param name Name of the property whose value is to be set
272: * @param value Value to which this property is to be set
273: */
274: public void set(String name, Object value) {
275: // Set the page number (for validator)
276: if ("page".equals(name)) {
277: if (value == null) {
278: page = 0;
279: } else if (value instanceof Integer) {
280: page = ((Integer) value).intValue();
281: } else {
282: try {
283: page = ((Integer) ConvertUtils.convert(value
284: .toString(), Integer.class)).intValue();
285: } catch (Exception ignore) {
286: page = 0;
287: }
288: }
289: }
290:
291: dynaBean.set(name, value);
292: }
293:
294: /**
295: * Set the value of an indexed property with the specified name.
296: *
297: * @param name Name of the property whose value is to be set
298: * @param index Index of the property to be set
299: * @param value Value to which this property is to be set
300: */
301: public void set(String name, int index, Object value) {
302: dynaBean.set(name, index, value);
303: }
304:
305: /**
306: * Set the value of a mapped property with the specified name.
307: *
308: * @param name Name of the property whose value is to be set
309: * @param key Key of the property to be set
310: * @param value Value to which this property is to be set
311: */
312: public void set(String name, String key, Object value) {
313: dynaBean.set(name, key, value);
314: }
315:
316: /**
317: * Does the specified mapped property contain a value for the specified
318: * key value?
319: *
320: * @param name Name of the property to check
321: * @param key Name of the key to check
322: */
323: public boolean contains(String name, String key) {
324: return dynaBean.contains(name, key);
325: }
326:
327: /**
328: * Remove any existing value for the specified key on the specified mapped
329: * property.
330: *
331: * @param name Name of the property for which a value is to be removed
332: * @param key Key of the value to be removed
333: */
334: public void remove(String name, String key) {
335: dynaBean.remove(name, key);
336: }
337: }
|