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