1 /*
2 * Scope: a generic MVC framework.
3 * Copyright (c) 2000-2002, The Scope team
4 * All rights reserved.
5 *
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * Neither the name "Scope" nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 *
36 * $Id: JSPPage.java,v 1.8 2002/09/05 15:41:48 ludovicc Exp $
37 */
38 package org.scopemvc.view.servlet.jsp;
39
40
41 import java.util.HashMap;
42 import java.util.Iterator;
43 import java.util.LinkedList;
44 import java.util.List;
45 import org.apache.commons.logging.Log;
46 import org.apache.commons.logging.LogFactory;
47 import org.scopemvc.core.PropertyManager;
48 import org.scopemvc.core.Selector;
49 import org.scopemvc.util.Debug;
50 import org.scopemvc.util.ScopeConfig;
51 import org.scopemvc.util.convertor.StringConvertor;
52 import org.scopemvc.util.convertor.StringConvertors;
53 import org.scopemvc.view.servlet.Page;
54 import org.scopemvc.view.servlet.ValidationFailure;
55
56 /***
57 * <P>
58 *
59 * A concrete {@link org.scopemvc.view.servlet.Page}. ***** Doesn't do the
60 * populateModel stuff yet </P>
61 *
62 * @author <A HREF="mailto:smeyfroi@users.sourceforge.net">Steve Meyfroidt</A>
63 * @created 05 September 2002
64 * @version $Revision: 1.8 $ $Date: 2002/09/05 15:41:48 $
65 */
66 public class JSPPage extends Page {
67
68 /***
69 * The prefix on form parameters to identify a property/value pair used to
70 * repopulate the View's bound model. A property/value pair looks like:
71 * <CODE>
72 * <PROPERTY_ID_PREFIX>ViewID<VIEW_ID_SUFFIX>SelectorDescription
73 * </CODE>
74 *
75 * @see #populateModel
76 */
77 static char PROPERTY_ID_PREFIX;
78
79 private final static Log LOG = LogFactory.getLog(JSPPage.class);
80
81 private String path;
82
83
84 /***
85 * @param inViewID unique View ID for routing incoming Controls
86 * @param inJSPPath the path to the JSP this View uses
87 */
88 public JSPPage(String inViewID, String inJSPPath) {
89 super(inViewID);
90 path = inJSPPath;
91 init();
92 }
93
94
95 /***
96 * Gets the path
97 *
98 * @return The path value
99 */
100 public final String getPath() {
101 return path;
102 }
103
104
105 /***
106 * <P>
107 *
108 * Interprets any form parameters like <CODE>
109 * <PROPERTY_ID_PREFIX>SelectorDescription
110 * </CODE> as [property_description, property_value] pairs </P> <P>
111 *
112 * Extracts the property_description from the form parameter key, then
113 * populates its model object using the String value. Any parameters treated
114 * this way are removed from the HashMap. </P>
115 *
116 * @param ioParameters form parameters to parse for [property_description,
117 * property_value] pairs, removing any processed pairs from the
118 * parameters before return
119 * @return PopulateModelFailedException that will be handled as a validation
120 * failure.
121 */
122 public List populateModel(HashMap ioParameters) {
123 if (LOG.isDebugEnabled()) {
124 LOG.debug("populateModel: " + ioParameters);
125 }
126
127 List errors = new LinkedList();
128 // collect ValidationFailures in here
129 List toRemove = new LinkedList();
130 for (Iterator i = ioParameters.keySet().iterator(); i.hasNext(); ) {
131 Object o = i.next();
132 if (Debug.ON) {
133 Debug.assertTrue(o instanceof String);
134 }
135 String parameterKey = (String) o;
136 if (LOG.isDebugEnabled()) {
137 LOG.debug("populateModel: " + parameterKey);
138 }
139
140 // Recognise prefixed form parameters for model population
141 if (parameterKey.charAt(0) == PROPERTY_ID_PREFIX) {
142
143 // get the form parameter value and remove from the parameter list
144 o = ioParameters.get(parameterKey);
145 // ... if multiple values take the first
146 if (o instanceof Object[]) {
147 if (Debug.ON) {
148 Debug.assertTrue(((Object[]) o).length > 0);
149 }
150 o = ((Object[]) o)[0];
151 }
152 if (Debug.ON) {
153 Debug.assertTrue(o instanceof String);
154 }
155 String stringValue = (String) o;
156
157 // Mark it for removal (avoid concurrency problem with Iterator)
158 toRemove.add(o);
159
160 // find the property description
161 String propertyDescription = parameterKey.substring(1);
162 try {
163 populateBoundModelProperty(propertyDescription, stringValue);
164 } catch (Exception e) {
165 if (LOG.isDebugEnabled()) {
166 LOG.debug("populateModel: got an exception: " + e);
167 }
168 errors.add(new ValidationFailure(propertyDescription, stringValue, e));
169 }
170 }
171 }
172
173 for (Iterator i = toRemove.iterator(); i.hasNext(); ) {
174 ioParameters.remove(i.next());
175 }
176
177 if (errors.size() == 0) {
178 errors = null;
179 }
180 return errors;
181 }
182
183
184 /***
185 * Do it like this so that we can pick up application-specific
186 * ScopeConfig... static initializers would happen before user got a chance
187 * to setup the custom config properties.
188 */
189 protected void init() {
190 PROPERTY_ID_PREFIX = ScopeConfig.getChar("ServletFormParameter.propertyIDPrefix");
191 if (PROPERTY_ID_PREFIX == 0) {
192 LOG.fatal("No propertyIDPrefix in config.");
193 }
194 }
195
196
197 /***
198 * Use the property_description, property_value pair passed to set a
199 * property in the bound model to a new value. Use StringConvertor if
200 * available to convert from String to the property's native datatype.
201 *
202 * @param inPropertyDescription TODO: Describe the Parameter
203 * @param inValue TODO: Describe the Parameter
204 * @throws Exception on any failure
205 */
206 protected void populateBoundModelProperty(String inPropertyDescription, String inValue)
207 throws Exception {
208 if (LOG.isDebugEnabled()) {
209 LOG.debug("populateBoundModelProperty: " + inPropertyDescription + ", " + inValue);
210 }
211
212 if (getBoundModel() == null) {
213 LOG.error("No bound model for: " + this);
214 return;
215 }
216
217 // Get the PropertyManager for the bound model
218 Object model = getBoundModel();
219 PropertyManager manager = PropertyManager.getInstance(model);
220 if (Debug.ON) {
221 Debug.assertTrue(manager != null, "null manager");
222 }
223
224 // Get the Selector from the property description
225 Selector selector = Selector.fromString(inPropertyDescription);
226
227 // Use StringConvertors if available, else just set(Selector, String)
228 StringConvertor convertor = StringConvertors.forClass(manager.getPropertyClass(model, selector));
229 if (convertor != null) {
230 if (LOG.isDebugEnabled()) {
231 LOG.debug("populateProperty: got " + convertor.getClass());
232 }
233 Object value = convertor.stringAsValue(inValue);
234 manager.set(model, selector, value);
235 } else {
236 if (LOG.isDebugEnabled()) {
237 LOG.debug("populateProperty: no StringConvertor ");
238 }
239 manager.set(model, selector, inValue);
240 }
241 }
242 }
This page was automatically generated by Maven