001: /*
002: * Copyright 2005-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005: * in compliance with the License. You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software distributed under the License
010: * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011: * or implied. See the License for the specific language governing permissions and limitations under
012: * the License.
013: */
014:
015: package org.strecks.form.controller;
016:
017: import java.util.HashMap;
018: import java.util.Map;
019: import java.util.Set;
020:
021: import javax.servlet.http.HttpServletRequest;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.apache.struts.action.ActionErrors;
026: import org.apache.struts.action.ActionForm;
027: import org.apache.struts.action.ActionMapping;
028: import org.strecks.bind.handler.BindHandler;
029: import org.strecks.bind.internal.BindConvertInfo;
030: import org.strecks.converter.ConversionState;
031: import org.strecks.converter.Converter;
032: import org.strecks.converter.handler.ConversionHandler;
033: import org.strecks.exceptions.ApplicationConfigurationException;
034: import org.strecks.exceptions.ConversionRuntimeException;
035: import org.strecks.util.Assert;
036: import org.strecks.validator.internal.MethodValidators;
037: import org.strecks.validator.internal.OrderedProperty;
038: import org.strecks.validator.internal.ValidationInfo;
039:
040: /**
041: * Action form which handles annotation based validation, conversion and data binding
042: * @author Phil Zoio
043: */
044: public class DelegatingForm extends ActionForm implements ValidForm,
045: BindingForm, WrappingForm, Deferable {
046:
047: private static Log log = LogFactory.getLog(DelegatingForm.class);
048:
049: private static final long serialVersionUID = 1L;
050:
051: public static final Object CONVERSION_FAILED = new Object();
052:
053: private boolean bindOutwards;
054:
055: private ValidationInfo validationInfo;
056:
057: private BindConvertInfo bindConvertInfo;
058:
059: private Map<String, Object> convertedValues;
060:
061: private ActionForm form;
062:
063: public DelegatingForm(ActionForm form) {
064: super ();
065: Assert.notNull(form);
066: this .form = form;
067: }
068:
069: /* **************************** validation related methods **************************** */
070:
071: public void setValidationInfo(ValidationInfo validationInfo) {
072: this .validationInfo = validationInfo;
073: }
074:
075: public void setBindConvertInfo(BindConvertInfo bindConvertInfo) {
076: this .bindConvertInfo = bindConvertInfo;
077: }
078:
079: @Override
080: public ActionErrors validate(ActionMapping mapping,
081: HttpServletRequest request) {
082:
083: //if validation is deferred, do not validate now
084: if (isDeferred())
085: return null;
086:
087: Assert.notNull(validationInfo);
088: Assert.notNull(form);
089:
090: ConversionHandler conversionHandler = validationInfo
091: .getConversionHandler();
092:
093: Map<OrderedProperty, MethodValidators> validators = validationInfo
094: .getValidators();
095: Set<OrderedProperty> keySet = validators.keySet();
096: for (OrderedProperty property : keySet) {
097: MethodValidators methodValidators = validators
098: .get(property);
099: if (methodValidators.getRequiresConversion()) {
100: if (convertedValues == null)
101: convertedValues = new HashMap<String, Object>();
102: Converter converter = methodValidators.getConverter();
103:
104: Object converted = null;
105:
106: // catch the conversion exception, and throw
107: String propertyName = property.getPropertyName();
108:
109: try {
110: converted = conversionHandler.getAndConvertInwards(
111: form, propertyName, converter);
112:
113: if (converted != null) {
114:
115: // check that converted is actually of correct type
116: Class<?> converterType = methodValidators
117: .getConverterType();
118:
119: if (!converterType.isAssignableFrom(converted
120: .getClass())) {
121: String message = "Supplied value of "
122: + propertyName
123: + " in "
124: + form.getClass()
125: + " converted to "
126: + converted.getClass()
127: + " and not the "
128: + converterType
129: + " expected by one or more validators. "
130: + "Check that the property contains an appropriate converter in its getter method";
131:
132: log.info(message);
133: throw new ApplicationConfigurationException(
134: message);
135: }
136:
137: } else {
138: converted = ConversionState.NULL;
139: }
140:
141: } catch (ConversionRuntimeException e) {
142: converted = ConversionState.FAILURE;
143: }
144:
145: convertedValues.put(propertyName, converted);
146:
147: }
148: }
149:
150: return validationInfo.getValidationHandler()
151: .validate(validationInfo, form, mapping, request,
152: convertedValues);
153:
154: }
155:
156: @Override
157: public void reset(ActionMapping mapping, HttpServletRequest request) {
158: form.reset(mapping, request);
159: bindOutwards = false;
160: }
161:
162: /* **************************** bind related methods **************************** */
163:
164: /**
165: * Bind from the to the String form bean properties to the target object(s)
166: */
167: public void bindInwards(Object actionBean) {
168:
169: Assert.notNull(bindConvertInfo);
170: Assert.notNull(form);
171:
172: Map<String, BindHandler> bindMap = bindConvertInfo.getBindMap();
173:
174: Set<String> keySet = bindMap.keySet();
175: for (String propertyName : keySet) {
176: BindHandler bindHandler = bindMap.get(propertyName);
177: Object convertedValue = null;
178:
179: if (convertedValues != null) {
180: convertedValue = convertedValues.get(propertyName);
181: }
182: bindHandler.bindInwards(form, actionBean, convertedValue);
183: }
184: }
185:
186: /**
187: * Bind from the target object(s) to the String form bean properties
188: */
189: public void bindOutwards(Object actionBean) {
190:
191: Assert.notNull(bindConvertInfo);
192: Assert.notNull(form);
193:
194: Map<String, BindHandler> bindMap = bindConvertInfo.getBindMap();
195:
196: Set<String> keySet = bindMap.keySet();
197: for (String propertyName : keySet) {
198: BindHandler bindHandler = bindMap.get(propertyName);
199: bindHandler.bindOutwards(form, actionBean);
200: }
201: }
202:
203: public void setBindOutwards(boolean bindOutwards) {
204: this .bindOutwards = true;
205: }
206:
207: public boolean getBindOutwards() {
208: return bindOutwards;
209: }
210:
211: public ActionForm getWrappedForm() {
212: return form;
213: }
214:
215: public BindConvertInfo getBindConvertInfo() {
216: return bindConvertInfo;
217: }
218:
219: public ValidationInfo getValidationInfo() {
220: return validationInfo;
221: }
222:
223: public boolean isDeferred() {
224: return false;
225: }
226: }
|