1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.betwixt.expression;
18
19 import java.lang.reflect.Array;
20 import java.util.Collection;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24
25 /***
26 * Abstracts common features for strongly typed <code>Updater</code>'s.
27 * Strongly type <code>Updater</code>'s perform conversions based on this
28 * the expected type before the bean update is invoked.
29 * @since 0.7
30 * @author <a href='http://commons.apache.org'>Apache Commons Team</a>, <a href='http://www.apache.org'>Apache Software Foundation</a>
31 */
32 public abstract class TypedUpdater implements Updater {
33
34 /*** Logger */
35 private static final Log log = LogFactory.getLog( TypedUpdater.class );
36
37
38 /*** The type of the first parameter of the method */
39 private Class valueType;
40
41 /***
42 * Updates the current bean context with the given String value
43 * @param context the Context to be updated
44 * @param newValue the update to this new value
45 */
46 public void update(Context context, Object newValue) {
47 Object bean = context.getBean();
48 if ( bean != null ) {
49 if ( newValue instanceof String ) {
50
51 if ( log.isTraceEnabled() ) {
52 log.trace("Converting primitive to " + valueType);
53 }
54 newValue = context.getObjectStringConverter()
55 .stringToObject( (String) newValue, valueType, context );
56 }
57 if ( newValue != null ) {
58
59
60
61
62
63
64
65
66
67
68
69
70 }
71
72 if (newValue instanceof Collection && valueType.isArray()) {
73 Collection valuesAsCollection = (Collection) newValue;
74 Class componentType = valueType.getComponentType();
75 if (componentType != null) {
76 Object[] valuesAsArray =
77 (Object[]) Array.newInstance(componentType, valuesAsCollection.size());
78 newValue = valuesAsCollection.toArray(valuesAsArray);
79 }
80 }
81
82 ;
83 try {
84 executeUpdate( context, bean, newValue );
85
86 } catch (Exception e) {
87 String valueTypeName = (newValue != null) ? newValue.getClass().getName() : "null";
88 log.warn(
89 "Cannot evaluate: " + this.toString() + " on bean: " + bean
90 + " of type: " + bean.getClass().getName() + " with value: " + newValue
91 + " of type: " + valueTypeName
92 );
93 handleException(context, e);
94 }
95 }
96 }
97
98
99
100 /***
101 * Gets the type expected.
102 * The value passed into {@link #update}
103 * will be converted on the basis of this type
104 * before being passed to {@link #executeUpdate}.
105 * @return <code>Class</code> giving expected type, not null
106 */
107 public Class getValueType() {
108 return valueType;
109 }
110
111 /***
112 * Sets the type expected.
113 * The value passed into {@link #update}
114 * will be converted on the basis of this type
115 * before being passed to {@link #executeUpdate}.
116 * @param valueType <code>Class</code> giving expected type, not null
117 */
118 public void setValueType(Class valueType) {
119 this.valueType = valueType;
120 }
121
122 /***
123 * Updates the bean with the given value.
124 * @param bean
125 * @param value value after type conversion
126 */
127 protected abstract void executeUpdate(Context context, Object bean, Object value) throws Exception;
128
129 /***
130 * Strategy method to allow derivations to handle exceptions differently.
131 * @param context the Context being updated when this exception occured
132 * @param e the Exception that occured during the update
133 */
134 protected void handleException(Context context, Exception e) {
135 log.info( "Caught exception: " + e, e );
136 }
137
138 }