001 /*
002 * Copyright 2002-2005 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.springframework.binding.value.support;
017
018 import java.lang.reflect.Method;
019
020 import org.springframework.binding.value.ValueModel;
021 import org.springframework.util.Assert;
022
023 /**
024 * A value model that derives it's value from the result of invoking a method.
025 * The parameters for the method invocation are generated from a list of
026 * "source" value models. Should any of the "source" values change the method
027 * will be invoked and if the return value has changed the value held by
028 * this class will be updated.
029 *
030 * @author Oliver Hutchison
031 */
032 public final class MethodInvokingDerivedValueModel extends AbstractDerivedValueModel {
033
034 private final Object target;
035
036 private final Method method;
037
038 private Object value;
039
040 public MethodInvokingDerivedValueModel(Object target, String methodName, ValueModel[] paramSourceValueModels) {
041 super(paramSourceValueModels);
042 this.target = target;
043 this.method = getPropertyMethod(target, methodName, paramSourceValueModels.length);
044 Assert.notNull(method, "No method with name [" + methodName + "] and " + paramSourceValueModels.length
045 + " parameters found on class.");
046 sourceValuesChanged();
047 }
048
049 protected void sourceValuesChanged() {
050 Object oldValue = value;
051 try {
052 value = method.invoke(target, getSourceValues());
053 fireValueChange(oldValue, value);
054 }
055 catch (Exception e) {
056 e.printStackTrace();
057 }
058 }
059
060 public Object getValue() {
061 return value;
062 }
063
064 private Method getPropertyMethod(Object target, String methodName, int numberOfParams) {
065 Method propertyMethod = null;
066 Method[] methods = target.getClass().getMethods();
067 for (int i = 0; i < methods.length; i++) {
068 Method method = methods[i];
069 if (method.getName().equals(methodName) && method.getParameterTypes().length == numberOfParams) {
070 if (propertyMethod != null) {
071 throw new UnsupportedOperationException("Found than one method with name '" + methodName + "' and "
072 + numberOfParams + " parameters on class '" + target.getClass().getName() + "'.");
073 }
074 propertyMethod = method;
075 }
076 }
077 return propertyMethod;
078 }
079 }