View Javadoc

1   package org.cateproject.view.flow;
2   
3   import java.beans.PropertyEditorSupport;
4   
5   import org.springframework.beans.BeanWrapperImpl;
6   import org.springframework.beans.BeansException;
7   import org.springframework.beans.NotReadablePropertyException;
8   import org.springframework.beans.NotWritablePropertyException;
9   import org.springframework.beans.TypeMismatchException;
10  import org.springframework.binding.convert.ConversionException;
11  import org.springframework.binding.convert.ConversionExecutor;
12  import org.springframework.binding.convert.service.GenericConversionService;
13  import org.springframework.binding.expression.EvaluationException;
14  import org.springframework.binding.expression.Expression;
15  import org.springframework.binding.expression.PropertyNotFoundException;
16  import org.springframework.binding.expression.ValueCoercionException;
17  import org.springframework.core.convert.ConversionService;
18  
19  public class BeanWrapperExpression implements Expression {
20  
21  	private String expression;
22  
23  	private GenericConversionService conversionService;
24  
25  	/**
26  	 * Creates a new bean wrapper expression.
27  	 * @param expression the property expression string
28  	 * @param conversionService the conversion service containing converters to use as PropertyEditors for type
29  	 * conversion
30  	 */
31  	public BeanWrapperExpression(String expression, GenericConversionService conversionService) {
32  		this.expression = expression;
33  		this.conversionService = conversionService;
34  	}
35  
36  	public boolean equals(Object o) {
37  		if (!(o instanceof BeanWrapperExpression)) {
38  			return false;
39  		}
40  		BeanWrapperExpression other = (BeanWrapperExpression) o;
41  		return expression.equals(other.expression);
42  	}
43  
44  	public int hashCode() {
45  		return expression.hashCode();
46  	}
47  
48  	public Object getValue(Object context) throws EvaluationException {
49  		try {
50  			BeanWrapperImpl beanWrapper = new BeanWrapperImpl(context);
51  			beanWrapper.setConversionService(conversionService.getDelegateConversionService());
52  			return beanWrapper.getPropertyValue(expression);
53  		} catch (NotReadablePropertyException e) {
54  			throw new PropertyNotFoundException(context.getClass(), expression, e);
55  		} catch (BeansException e) {
56  			throw new EvaluationException(context.getClass(), getExpressionString(),
57  					"A BeansException occurred getting the value for expression '" + getExpressionString()
58  							+ "' on context [" + context.getClass() + "]", e);
59  		}
60  	}
61  
62  	public void setValue(Object context, Object value) {
63  		try {
64  			BeanWrapperImpl beanWrapper = new BeanWrapperImpl(context);
65  			beanWrapper.setConversionService(conversionService.getDelegateConversionService());
66  			
67  			beanWrapper.setPropertyValue(expression, value);
68  		} catch (NotWritablePropertyException e) {
69  			throw new PropertyNotFoundException(context.getClass(), expression, e);
70  		} catch (TypeMismatchException e) {
71  			throw new ValueCoercionException(context.getClass(), expression, value, e.getRequiredType(), e);
72  		} catch (BeansException e) {
73  			throw new EvaluationException(context.getClass(), getExpressionString(),
74  					"A BeansException occurred setting the value of expression '" + getExpressionString()
75  							+ "' on context [" + context.getClass() + "] to [" + value + "]", e);
76  		}
77  	}
78  
79  	public Class getValueType(Object context) {
80  		try {
81  			BeanWrapperImpl beanWrapper = new BeanWrapperImpl(context);
82  			return beanWrapper.getPropertyType(expression);
83  		} catch (NotReadablePropertyException e) {
84  			throw new PropertyNotFoundException(context.getClass(), expression, e);
85  		} catch (BeansException e) {
86  			throw new EvaluationException(context.getClass(), getExpressionString(),
87  					"An BeansException occurred getting the value type for expression '" + getExpressionString()
88  							+ "' on context [" + context.getClass() + "]", e);
89  		}
90  	}
91  
92  	public String getExpressionString() {
93  		return expression;
94  	}
95  
96  	public String toString() {
97  		return expression;
98  	}
99  
100 	/**
101 	 * Adapts the String->Object converters to PropertyEditors for use during a setValue attempt. Excludes any
102 	 * String->Enum converter, since BeanWrapper has built in support for Enum conversion.
103 	 * @param registry the registry to register converter-to-editor adapters with
104 	 */
105 //	protected void registerConvertersAsPropertyEditors(PropertyEditorRegistry registry) {
106 //		registry.registerCustomEditor(String.class,new StringTrimmerEditor(true));
107 //
108 //		Set converters = conversionService.getConversionExecutors(String.class);
109 //		for (Iterator it = converters.iterator(); it.hasNext();) {
110 //			ConversionExecutor converter = (ConversionExecutor) it.next();
111 //			if (!converter.getTargetClass().getName().equals("java.lang.Enum")) {
112 //				registry.registerCustomEditor(converter.getTargetClass(), new PropertyEditorConverter(converter));
113 //			}
114 //		}
115 //	}
116 
117 	private static class PropertyEditorConverter extends PropertyEditorSupport {
118 
119 		private ConversionExecutor converter;
120 
121 		public PropertyEditorConverter(ConversionExecutor converter) {
122 			this.converter = converter;
123 		}
124 
125 		public void setAsText(String text) throws IllegalArgumentException {
126 			try {
127 				Object convertedValue = converter.execute(text);
128 				setValue(convertedValue);
129 			} catch (ConversionException e) {
130 				IllegalArgumentException iae = new IllegalArgumentException("Unable to convert text '" + text + "'");
131 				iae.initCause(e);
132 				throw iae;
133 			}
134 		}
135 	}
136 
137 }
138