View Javadoc
1 /* 2 * $Header: /home/cvs/jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/expression/MethodExpression.java,v 1.4 2003/01/12 13:52:03 rdonkin Exp $ 3 * $Revision: 1.4 $ 4 * $Date: 2003/01/12 13:52:03 $ 5 * 6 * ==================================================================== 7 * 8 * The Apache Software License, Version 1.1 9 * 10 * Copyright (c) 1999-2002 The Apache Software Foundation. All rights 11 * reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in 22 * the documentation and/or other materials provided with the 23 * distribution. 24 * 25 * 3. The end-user documentation included with the redistribution, if 26 * any, must include the following acknowlegement: 27 * "This product includes software developed by the 28 * Apache Software Foundation (http://www.apache.org/)." 29 * Alternately, this acknowlegement may appear in the software itself, 30 * if and wherever such third-party acknowlegements normally appear. 31 * 32 * 4. The names "The Jakarta Project", "Commons", and "Apache Software 33 * Foundation" must not be used to endorse or promote products derived 34 * from this software without prior written permission. For written 35 * permission, please contact apache@apache.org. 36 * 37 * 5. Products derived from this software may not be called "Apache" 38 * nor may "Apache" appear in their names without prior written 39 * permission of the Apache Group. 40 * 41 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 44 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 47 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 48 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 49 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52 * SUCH DAMAGE. 53 * ==================================================================== 54 * 55 * This software consists of voluntary contributions made by many 56 * individuals on behalf of the Apache Software Foundation. For more 57 * information on the Apache Software Foundation, please see 58 * <http://www.apache.org/>;. 59 * 60 * $Id: MethodExpression.java,v 1.4 2003/01/12 13:52:03 rdonkin Exp $ 61 */ 62 package org.apache.commons.betwixt.expression; 63 64 import java.lang.reflect.Method; 65 66 /*** <p><code>MethodExpression</code> evaluates a method on the current bean context.</p> 67 * 68 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a> 69 * @version $Revision: 1.4 $ 70 */ 71 public class MethodExpression implements Expression { 72 73 /*** null arguments */ 74 protected static Object[] NULL_ARGUMENTS; 75 /*** null classes */ 76 protected static Class[] NULL_CLASSES; 77 78 /*** The method to call on the bean */ 79 private Method method; 80 81 /*** Base constructor */ 82 public MethodExpression() { 83 } 84 85 /*** 86 * Convenience constructor sets method property 87 * @param method the Method whose return value when invoked on the bean 88 * will the value of this expression 89 */ 90 public MethodExpression(Method method) { 91 this.method = method; 92 } 93 94 /*** 95 * Evaluate by calling the read method on the current bean 96 * 97 * @param context the context against which this expression will be evaluated 98 * @return the value returned by the method when it's invoked on the context's bean, 99 * so long as the method can be invoked. 100 * Otherwise, null. 101 */ 102 public Object evaluate(Context context) { 103 Object bean = context.getBean(); 104 if ( bean != null ) { 105 Object[] arguments = getArguments(); 106 try { 107 return method.invoke( bean, arguments ); 108 109 } catch (IllegalAccessException e) { 110 // lets try use another method with the same name 111 try { 112 Class type = bean.getClass(); 113 Method alternate = findAlternateMethod( type, method ); 114 if ( alternate != null ) { 115 return alternate.invoke( bean, arguments ); 116 } 117 } catch (Exception e2) { 118 handleException(context, e2); 119 } 120 } catch (Exception e) { 121 handleException(context, e); 122 } 123 } 124 return null; 125 } 126 127 /*** 128 * Do nothing. 129 * @see org.apache.commons.betwixt.expression.Expression 130 */ 131 public void update(Context context, String newValue) { 132 // do nothing 133 } 134 135 /*** 136 * Gets the method used to evaluate this expression. 137 * @return the method whose value (when invoked against the context's bean) will be used 138 * to evaluate this expression. 139 */ 140 public Method getMethod() { 141 return method; 142 } 143 144 /*** 145 * Sets the method used to evaluate this expression 146 * @param method method whose value (when invoked against the context's bean) will be used 147 * to evaluate this expression 148 */ 149 public void setMethod(Method method) { 150 this.method = method; 151 } 152 153 // Implementation methods 154 //------------------------------------------------------------------------- 155 156 /*** 157 * Allows derived objects to create arguments for the method call 158 * @return {@link #NULL_ARGUMENTS} 159 */ 160 protected Object[] getArguments() { 161 return NULL_ARGUMENTS; 162 } 163 164 /*** Tries to find an alternate method for the given type using interfaces 165 * which gets around the problem of inner classes, 166 * such as on Map.Entry implementations. 167 * 168 * @param type the Class whose methods are to be searched 169 * @param method the Method for which an alternative is to be search for 170 * @return the alternative Method, if one can be found. Otherwise null. 171 */ 172 protected Method findAlternateMethod( 173 Class type, 174 Method method ) { 175 // XXX 176 // Would it be better to use the standard reflection code in eg. lang 177 // since this code contains workarounds for common JVM bugs? 178 // 179 Class[] interfaces = type.getInterfaces(); 180 if ( interfaces != null ) { 181 String name = method.getName(); 182 for ( int i = 0, size = interfaces.length; i < size; i++ ) { 183 Class otherType = interfaces[i]; 184 // 185 // catch NoSuchMethodException so that all interfaces will be tried 186 try { 187 Method alternate = otherType.getMethod( name, NULL_CLASSES ); 188 if ( alternate != null && alternate != method ) { 189 return alternate; 190 } 191 } catch (NoSuchMethodException e) { 192 // swallow 193 } 194 } 195 } 196 return null; 197 } 198 199 /*** 200 * <p>Log error to context's logger.</p> 201 * 202 * <p>Allows derived objects to handle exceptions differently.</p> 203 * 204 * @param context the Context being evaluated when the exception occured 205 * @param e the exception to handle 206 */ 207 protected void handleException(Context context, Exception e) { 208 // use the context's logger to log the problem 209 context.getLog().error("[MethodExpression] Cannot evaluate expression", e); 210 } 211 212 /*** 213 * Returns something useful for logging. 214 * @return something useful for logging 215 */ 216 public String toString() { 217 return "MethodExpression [method=" + method + "]"; 218 } 219 }

This page was automatically generated by Maven