KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > struts > validator > LazyValidatorForm


1 /*
2  * $Id: LazyValidatorForm.java 56698 2004-11-05 21:11:41Z niallp $
3  *
4  * Copyright 2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 package org.apache.struts.validator;
20
21 import java.util.Map JavaDoc;
22 import java.util.List JavaDoc;
23 import org.apache.commons.beanutils.DynaBean;
24 import org.apache.commons.beanutils.LazyDynaBean;
25 import org.apache.commons.beanutils.LazyDynaMap;
26
27 /**
28  * <p>Struts <i>Lazy</i> <code>ActionForm</code> which <i>wraps</i> a <code>LazyDynaBean</code>.</p>
29  *
30  * <p>There isn't really that much to this implementation as most of the <i>lazy</i> behaviour is in
31  * <code>LazyDynaBean</code> and <i>wrapping</i> the <code>LazyDynaBean<code> is handled in the parent
32  * <code>BeanValidatorForm</code>. The only thing it really does is populate <i>indexed</i> properties
33  * which are a <code>List<code> type with a <code>LazyDynaBean<code> in the <code>get(name, index)</code>
34  * method.</p>
35  *
36  * <p><i>Lazy</i> DynaBeans provide several types of <i>lazy</i> behaviour:</p>
37  * <ul>
38  * <li><b><i>lazy</i> property addition</b> - properties which do not exist
39  * are automatically added.</li>
40  * <li><b><i>lazy</i> List facilities</b> - automatically <i>grows</i> a <code>List</code> or
41  * <code>Array</code> to accomodate the index value being set.</li>
42  * <li><b><i>lazy</i> List creation</b> - automatic creation of a <code>List</code>
43  * or <code>Array</code> for <i>indexed</i> properties, if it doesn't exist.</li>
44  * <li><b><i>lazy</i> Map creation</b> - automatic creation of a <code>Map</code>
45  * for <i>mapped</i> properties, if it doesn't exist.</li>
46  * </ul>
47  *
48  * <p>Using this <i>lazy</i> <code>ActionForm</code> means that you don't have to define the ActionForm's
49  * properties in the <code>struts-config.xml</code>. However, a word of warning, everything in the
50  * Request gets populated into this <code>ActionForm</code> circumventing the normal <i>firewall</i>
51  * function of Struts forms. Therefore you should only <i>take out</i> of this form properties you expect
52  * to be there rather than blindly populating all the properties into the business tier.</p>
53  *
54  * <p>Having said that it is not necessary to pre-define properties in the <code>struts-config.xml</code>, it is
55  * useful to sometimes do so for <i>mapped</i> or <i>indexed</i> properties. For example, if you want to use
56  * a different <code>Map<code> implementation from the default <code>HashMap</code> or an array for indexed
57  * properties, rather than the default <code>List</code> type:</p>
58  *
59  * <pre><code>
60  * &lt;form-bean name="myForm" type="org.apache.struts.validator.LazyValidatorForm"&gt;
61  * &lt;form-property name="myMap" type="java.util.TreeMap" /&gt;
62  * &lt;form-property name="myBeans" type="org.apache.commons.beanutils.LazyDynaBean[]" /&gt;
63  * &lt;/form-bean&gt;
64  * </code></pre>
65  *
66  * <p>Another reason for defining <i>indexed</i> properties in the <code>struts-config.xml</code> is that
67  * if you are validating indexed properties using the Validator and none are submitted then the indexed
68  * property will be <code>null</code> which causes validator to fail. Pre-defining them in the
69  * <code>struts-config.xml</code> will result in a zero-length indexed property (array or List) being
70  * instantiated, avoiding an issue with validator in that circumstance.</p>
71  *
72  * <p>This implementation validates using the ActionForm <i>name</i>. If you require a version that
73  * validates according to the <i>path</i> then it can be easily created in the following manner:</p>
74  *
75  * <pre><code>
76  * public class MyLazyForm extends LazyValidatorForm {
77  *
78  * public MyLazyForm () {
79  * super();
80  * setPathValidation(true);
81  * }
82  *
83  * }
84  * </code></pre>
85  *
86  * <p>Rather than using this class, another alternative is to either use a <code>LazyDynaBean</code> or
87  * custom version of <code>LazyDynaBean</code> directly. Struts now automatically <i>wraps</i> objects
88  * which are not <code>ActionForms</code> in a <code>BeanValidatorForm</code>. For example:</p>
89  *
90  * <pre><code>
91  * &lt;form-bean name="myForm" type="org.apache.commons.beanutils.LazyDynaBean"&gt;
92  * &lt;form-property name="myBeans" type="org.apache.commons.beanutils.LazyDynaBean[]" /&gt;
93  * &lt;/form-bean&gt;
94  * </code></pre>
95  *
96  * @see <a HREF="http://jakarta.apache.org/commons/beanutils/apidocs/org/apache/commons/beanutils/package-summary.html#dynamic.lazy">Commons BeanUtils JavaDoc</a>
97  * @since Struts 1.2.6
98  * @version $Rev: 56698 $ $Date: 2004-11-05 21:11:41 +0000 (Fri, 05 Nov 2004) $
99  */

100 public class LazyValidatorForm extends BeanValidatorForm {
101
102     // ------------------- Constructors ----------------------------------
103

104     /**
105      * Default Constructor which creates a <code>LazyDynaBean</code> to <i>back</i>
106      * this form.
107      */

108     public LazyValidatorForm() {
109         super(new LazyDynaBean());
110     }
111
112     /**
113      */

114     public LazyValidatorForm(DynaBean bean) {
115         super(bean);
116     }
117
118     // ------------------- DynaBean methods ----------------------------------
119

120    /**
121     * <p>Return an indexed property value.</p>
122     *
123     * <p>If the "indexed" property is a <code>List</code> type then
124     * any missing values are populated with a bean (created in
125     * the <code>newIndexedBean(name)</code> method - in this
126     * implementation this is a <code>LazyDynaBean</code> type.</p>
127     */

128     public Object JavaDoc get(String JavaDoc name, int index) {
129
130         int size = size(name);
131
132
133         // Get the indexed property
134
Object JavaDoc value = dynaBean.get(name, index);
135
136         // Create missing beans for Lists
137
if (value == null) {
138             Object JavaDoc indexedValue = dynaBean.get(name);
139             if (List JavaDoc.class.isAssignableFrom(indexedValue.getClass())) {
140                 for (int i = size; i <= index; i++) {
141                     value = newIndexedBean(name);
142                     set(name, i, value);
143                 }
144             }
145         }
146
147         return value;
148
149     }
150
151     // ------------------- Public methods ----------------------------------
152

153    /**
154     * <p>Return the <code>Map</code> containing the property values.</p>
155     *
156     * <p>Provided so that properties can be access using JSTL.</p>
157     */

158     public Map JavaDoc getMap() {
159         return ((LazyDynaBean)dynaBean).getMap();
160     }
161
162     // ------------------- Protected methods ----------------------------------
163

164    /**
165     * <p>Creates new <code>DynaBean</code> instances to populate
166     * an 'indexed' property of beans - defaults to <code>LazyDynaBean</code>
167     * type.</p>
168     *
169     * <p>Override this method if you require a different type of
170     * <code>DynaBean</code>.</p>
171     */

172     protected DynaBean newIndexedBean(String JavaDoc name) {
173         return new LazyDynaBean();
174     }
175
176 }
Popular Tags