KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > betwixt > expression > MethodExpression


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.betwixt.expression;
17
18 import java.lang.reflect.Method JavaDoc;
19
20 /** <p><code>MethodExpression</code> evaluates a method on the current bean context.</p>
21   *
22   * @author <a HREF="mailto:jstrachan@apache.org">James Strachan</a>
23   * @version $Revision: 1.8 $
24   */

25 public class MethodExpression implements Expression {
26
27     /** null arguments */
28     protected static Object JavaDoc[] NULL_ARGUMENTS;
29     /** null classes */
30     protected static Class JavaDoc[] NULL_CLASSES;
31     
32     /** The method to call on the bean */
33     private Method JavaDoc method;
34     
35     /** Base constructor */
36     public MethodExpression() {
37     }
38     
39     /**
40      * Convenience constructor sets method property
41      * @param method the Method whose return value when invoked on the bean
42      * will the value of this expression
43      */

44     public MethodExpression(Method JavaDoc method) {
45         this.method = method;
46     }
47
48     /**
49      * Evaluate by calling the read method on the current bean
50      *
51      * @param context the context against which this expression will be evaluated
52      * @return the value returned by the method when it's invoked on the context's bean,
53      * so long as the method can be invoked.
54      * Otherwise, null.
55      */

56     public Object JavaDoc evaluate(Context context) {
57         Object JavaDoc bean = context.getBean();
58         if ( bean != null ) {
59             Object JavaDoc[] arguments = getArguments();
60             try {
61                 return method.invoke( bean, arguments );
62                 
63             } catch (IllegalAccessException JavaDoc e) {
64                 // lets try use another method with the same name
65
try {
66                     Class JavaDoc type = bean.getClass();
67                     Method JavaDoc alternate = findAlternateMethod( type, method );
68                     if ( alternate != null ) {
69                         return alternate.invoke( bean, arguments );
70                     }
71                 } catch (Exception JavaDoc e2) {
72                     handleException(context, e2);
73                 }
74             } catch (Exception JavaDoc e) {
75                 handleException(context, e);
76             }
77         }
78         return null;
79     }
80
81     /**
82      * Do nothing.
83      * @see org.apache.commons.betwixt.expression.Expression
84      */

85     public void update(Context context, String JavaDoc newValue) {
86         // do nothing
87
}
88
89     /**
90      * Gets the method used to evaluate this expression.
91      * @return the method whose value (when invoked against the context's bean) will be used
92      * to evaluate this expression.
93      */

94     public Method JavaDoc getMethod() {
95         return method;
96     }
97     
98     /**
99      * Sets the method used to evaluate this expression
100      * @param method method whose value (when invoked against the context's bean) will be used
101      * to evaluate this expression
102      */

103     public void setMethod(Method JavaDoc method) {
104         this.method = method;
105     }
106     
107     // Implementation methods
108
//-------------------------------------------------------------------------
109

110     /**
111      * Allows derived objects to create arguments for the method call
112      * @return {@link #NULL_ARGUMENTS}
113      */

114     protected Object JavaDoc[] getArguments() {
115         return NULL_ARGUMENTS;
116     }
117     
118     /** Tries to find an alternate method for the given type using interfaces
119       * which gets around the problem of inner classes,
120       * such as on Map.Entry implementations.
121       *
122       * @param type the Class whose methods are to be searched
123       * @param method the Method for which an alternative is to be search for
124       * @return the alternative Method, if one can be found. Otherwise null.
125       */

126     protected Method JavaDoc findAlternateMethod(
127                                             Class JavaDoc type,
128                                             Method JavaDoc method ) {
129         // XXX
130
// Would it be better to use the standard reflection code in eg. lang
131
// since this code contains workarounds for common JVM bugs?
132
//
133
Class JavaDoc[] interfaces = type.getInterfaces();
134         if ( interfaces != null ) {
135             String JavaDoc name = method.getName();
136             for ( int i = 0, size = interfaces.length; i < size; i++ ) {
137                 Class JavaDoc otherType = interfaces[i];
138                 //
139
// catch NoSuchMethodException so that all interfaces will be tried
140
try {
141                     Method JavaDoc alternate = otherType.getMethod( name, NULL_CLASSES );
142                     if ( alternate != null && alternate != method ) {
143                         return alternate;
144                     }
145                 } catch (NoSuchMethodException JavaDoc e) {
146                     // swallow
147
}
148             }
149         }
150         return null;
151     }
152     
153     /**
154       * <p>Log error to context's logger.</p>
155       *
156       * <p>Allows derived objects to handle exceptions differently.</p>
157       *
158       * @param context the Context being evaluated when the exception occured
159       * @param e the exception to handle
160       */

161     protected void handleException(Context context, Exception JavaDoc e) {
162         // use the context's logger to log the problem
163
context.getLog().error("[MethodExpression] Cannot evaluate expression ", e);
164     }
165     
166     /**
167      * Returns something useful for logging.
168      * @return something useful for logging
169      */

170     public String JavaDoc toString() {
171         return "MethodExpression [method=" + method + "]";
172     }
173 }
174
Popular Tags