package org.robobinding.function; import java.lang.reflect.Method; import java.text.MessageFormat; import java.util.Map; import java.util.Set; import org.robobinding.Bug; import org.robobinding.util.Maps; import org.robobinding.util.MethodUtils; /** * @since 1.0 * @author Cheng Wei * */ public class LazyFunctions implements Functions { private final Class<?> beanClass; private final Map<MethodDescriptor, Function> functions; private final FunctionSupply supply; public LazyFunctions(Class<?> beanClass, Set<MethodDescriptor> methods, FunctionSupply supply) { this.beanClass = beanClass; this.functions = Maps.newHashMap(); this.supply = supply; initializeFunctions(methods); } private void initializeFunctions(Set<MethodDescriptor> methods) { for(MethodDescriptor method : methods) { functions.put(method, null); } } @Override public Function find(String functionName, Class<?>... parameterTypes) { Method method = MethodUtils.getMatchingAccessibleMethod(beanClass, functionName, parameterTypes); if(method == null) { return null; } MethodDescriptor methodDescriptor = new MethodDescriptor(method.getName(), method.getParameterTypes()); if(!functions.containsKey(methodDescriptor)) { throw new RuntimeException("No such method '"+new MethodDescription(beanClass, method)+"'"); } Function function = functions.get(methodDescriptor); if (function == null) { function = supply.tryToCreateFunction(methodDescriptor); if(function == null) { throw new Bug(MessageFormat.format("The method '{0}' is not generated", new MethodDescription(beanClass, method))); } functions.put(methodDescriptor, function); } return function; } }