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 }