001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.betwixt.expression; 018 019 020 import java.lang.reflect.Method; 021 022 import org.apache.commons.logging.Log; 023 import org.apache.commons.logging.LogFactory; 024 025 /** <p><code>MethodUpdater</code> updates the current bean context 026 * by calling a WriteMethod with the String value from the XML attribute 027 * or element.</p> 028 * 029 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a> 030 * @version $Revision: 438373 $ 031 */ 032 public class MethodUpdater extends TypedUpdater { 033 034 /** Logger */ 035 private static Log log = LogFactory.getLog( MethodUpdater.class ); 036 037 /** 038 * Programmatically set log 039 * @param aLog the implementation to which this class should log 040 */ 041 public static void setLog( Log aLog ) { 042 log = aLog; 043 } 044 045 /** The method to call on the bean */ 046 private Method method; 047 /** Base constructor */ 048 public MethodUpdater() { 049 } 050 051 /** 052 * Convenience constructor sets method property 053 * @param method the Method to be invoked on the context's bean in the update 054 */ 055 public MethodUpdater(Method method) { 056 setMethod( method ); 057 } 058 059 /** 060 * Gets the method which will be invoked by the update 061 * 062 * @return the Method to be invoked by the update 063 */ 064 public Method getMethod() { 065 return method; 066 } 067 068 /** 069 * Sets the constant value of this expression 070 * @param method the Method to be invoked by the update 071 */ 072 public void setMethod(Method method) { 073 this.method = method; 074 Class[] types = method.getParameterTypes(); 075 if ( types == null || types.length <= 0 ) { 076 throw new IllegalArgumentException( "The Method must have at least one parameter" ); 077 } 078 setValueType(types[0]); 079 } 080 081 // Implementation methods 082 //------------------------------------------------------------------------- 083 084 085 086 /** 087 * Returns something useful for logging. 088 * @return something useful for logging 089 */ 090 public String toString() { 091 return "MethodUpdater [method=" + method + "]"; 092 } 093 094 /** 095 * Updates the bean by method invocation. 096 * @since 0.7 097 */ 098 protected void executeUpdate(Context context, Object bean, Object newValue) throws Exception { 099 if ( log.isDebugEnabled() ) { 100 log.debug( 101 "Calling setter method: " + method.getName() + " on bean: " + bean 102 + " with new value: " + newValue 103 ); 104 } 105 Object[] arguments = { newValue }; 106 try 107 { 108 method.invoke( bean, arguments ); 109 } 110 catch (IllegalAccessException e) 111 { 112 method.setAccessible(true); 113 method.invoke( bean, arguments ); 114 } 115 } 116 }