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 }