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.bind.handler;
016:
017: import org.apache.commons.logging.Log;
018: import org.apache.commons.logging.LogFactory;
019: import org.strecks.converter.ConversionState;
020: import org.strecks.util.Assert;
021: import org.strecks.util.PropertyValueGetter;
022: import org.strecks.util.PropertyValueSetter;
023: import org.strecks.util.ReflectHelper;
024:
025: /**
026: * <p>
027: * Adds support for binding a form property (usually a String) to a typed domain object.
028: * </p>
029: * <p>
030: * For example suppose you have a form to create a Person object. One field is date of birth. The
031: * user enters a date, which is represented in the form as a String. Using this mechanism, this
032: * value can then be bound directly to the <code>java.util.Date</code> typed property
033: * <code>person.dateOfBirth</code>
034: * </p>
035: *
036: * @author Phil Zoio
037: */
038: public class BindSimpleHandler extends AbstractBindHandler implements
039: BindHandler {
040:
041: private static Log log = LogFactory.getLog(BindSimpleHandler.class);
042:
043: private String beanLocatingExpression;
044:
045: private String beanPropertyName;
046:
047: private Class beanPropertyClass;
048:
049: /* **** public interface implementations ****** */
050:
051: /**
052: * Bind to the target object(s) from the String properties
053: */
054: public void bindInwards(Object form, Object actionBean,
055: Object convertedValue) {
056:
057: checkState();
058:
059: Object targetBean = PropertyValueGetter.getTargetBean(form,
060: getBeanLocatingExpression());
061:
062: if (targetBean != null) {
063:
064: maybeInitConverter(targetBean);
065:
066: Object targetValue = null;
067:
068: if (convertedValue == null
069: || convertedValue == ConversionState.FAILURE) {
070: targetValue = getAndConvertInwards(form,
071: getPropertyDescriptor().getName(), this
072: .getConverter());
073: } else if (convertedValue == ConversionState.NULL) {
074: targetValue = null;
075: } else {
076: targetValue = convertedValue;
077: }
078: PropertyValueSetter.setPropertyValue(targetBean, this
079: .getBeanPropertyName(), getBeanPropertyClass(),
080: targetValue);
081:
082: } else {
083: log.warn("Unable to locate target for inward binding from "
084: + form.getClass().getName()
085: + " using bean locating expression: "
086: + getBeanLocatingExpression());
087: }
088:
089: }
090:
091: /**
092: * Bind from the target object(s) to the String properties
093: */
094: public void bindOutwards(Object form, Object actionBean) {
095:
096: checkState();
097:
098: Object targetBean = PropertyValueGetter.getTargetBean(form,
099: getBeanLocatingExpression());
100:
101: if (targetBean != null) {
102:
103: maybeInitConverter(targetBean);
104:
105: Object propertyValue = getAndConvertOutwards(targetBean,
106: this .getBeanPropertyName(), this .getConverter());
107:
108: PropertyValueSetter.setPropertyValue(form,
109: getPropertyDescriptor(), propertyValue);
110:
111: }
112:
113: }
114:
115: private void checkState() {
116: Assert.notNull(beanPropertyName);
117: Assert.notNull(getConverter());
118: Assert.notNull(getConversionHandler());
119: }
120:
121: /* **** helper methods ****** */
122:
123: protected void setBeanPropertyClass(Object containingBean) {
124: String beanPropertyName = getBeanPropertyName();
125: Class<?> propertyType = ReflectHelper.getBeanPropertyType(
126: containingBean, beanPropertyName);
127: setBeanPropertyClass(propertyType);
128: }
129:
130: protected void maybeInitConverter(Object targetBean) {
131: synchronized (this ) {
132: // need to figure out what the binding target class is and set converter appropriately
133: if (this .getBeanPropertyClass() == null) {
134: setBeanPropertyClass(targetBean);
135: }
136: getConverter().setTargetClass(getBeanPropertyClass());
137: }
138: }
139:
140: /* **** package level getter and setters ****** */
141:
142: public String getBeanLocatingExpression() {
143: return beanLocatingExpression;
144: }
145:
146: public void setBeanLocatingExpression(String beanLocatingExpression) {
147: this .beanLocatingExpression = beanLocatingExpression;
148: //FIXME set target source property
149: }
150:
151: public String getBeanPropertyName() {
152: return beanPropertyName;
153: }
154:
155: public void setBeanPropertyName(String beanPropertyName) {
156: this .beanPropertyName = beanPropertyName;
157: }
158:
159: public Class getBeanPropertyClass() {
160: return beanPropertyClass;
161: }
162:
163: public void setBeanPropertyClass(Class propertyClass) {
164: this.beanPropertyClass = propertyClass;
165: }
166:
167: }
|