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.Method;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22
23 /*** <p><code>MethodUpdater</code> updates the current bean context
24 * by calling a WriteMethod with the String value from the XML attribute
25 * or element.</p>
26 *
27 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
28 * @version $Revision: 1.12 $
29 */
30 public class MethodUpdater implements Updater {
31
32 /*** Logger */
33 private static Log log = LogFactory.getLog( MethodUpdater.class );
34
35 /***
36 * Programmatically set log
37 * @param aLog the implementation to which this class should log
38 */
39 public static void setLog( Log aLog ) {
40 log = aLog;
41 }
42
43 /*** The method to call on the bean */
44 private Method method;
45 /*** The type of the first parameter of the method */
46 private Class valueType;
47
48 /*** Base constructor */
49 public MethodUpdater() {
50 }
51
52 /***
53 * Convenience constructor sets method property
54 * @param method the Method to be invoked on the context's bean in the update
55 */
56 public MethodUpdater(Method method) {
57 setMethod( method );
58 }
59
60 /***
61 * Updates the current bean context with the given String value
62 * @param context the Context to be updated
63 * @param newValue the update to this new value
64 */
65 public void update(Context context, Object newValue) {
66 Object bean = context.getBean();
67 if ( bean != null ) {
68 if ( newValue instanceof String ) {
69
70 if ( log.isTraceEnabled() ) {
71 log.trace("Converting primitive to " + valueType);
72 }
73 newValue = context.getObjectStringConverter()
74 .stringToObject( (String) newValue, valueType, null, context );
75 }
76 if ( newValue != null ) {
77
78
79
80
81
82
83
84
85
86
87
88
89 }
90 Object[] arguments = { newValue };
91 try {
92 if ( log.isDebugEnabled() ) {
93 log.debug(
94 "Calling setter method: " + method.getName() + " on bean: " + bean
95 + " with new value: " + newValue
96 );
97 }
98 method.invoke( bean, arguments );
99
100 } catch (Exception e) {
101 String valueTypeName = (newValue != null) ? newValue.getClass().getName() : "null";
102 log.warn(
103 "Cannot evaluate method: " + method.getName() + " on bean: " + bean
104 + " of type: " + bean.getClass().getName() + " with value: " + newValue
105 + " of type: " + valueTypeName
106 );
107 handleException(context, e);
108 }
109 }
110 }
111
112 /***
113 * Gets the method which will be invoked by the update
114 *
115 * @return the Method to be invoked by the update
116 */
117 public Method getMethod() {
118 return method;
119 }
120
121 /***
122 * Sets the constant value of this expression
123 * @param method the Method to be invoked by the update
124 */
125 public void setMethod(Method method) {
126 this.method = method;
127 Class[] types = method.getParameterTypes();
128 if ( types == null || types.length <= 0 ) {
129 throw new IllegalArgumentException( "The Method must have at least one parameter" );
130 }
131 this.valueType = types[0];
132 }
133
134
135
136
137 /***
138 * Strategy method to allow derivations to handle exceptions differently.
139 * @param context the Context being updated when this exception occured
140 * @param e the Exception that occured during the update
141 */
142 protected void handleException(Context context, Exception e) {
143 log.info( "Caught exception: " + e, e );
144 }
145
146 /***
147 * Returns something useful for logging.
148 * @return something useful for logging
149 */
150 public String toString() {
151 return "MethodUpdater [method=" + method + "]";
152 }
153 }