1 10 package org.mmbase.util.functions; 11 12 import org.mmbase.cache.Cache; 13 14 import java.lang.reflect.*; 15 import java.util.*; 16 import org.mmbase.util.logging.*; 17 18 35 public class BeanFunction extends AbstractFunction { 36 private static final Logger log = Logging.getLoggerInstance(BeanFunction.class); 37 44 public static Class getClass(Class claz, String name) { 45 Class [] classes = claz.getDeclaredClasses(); 46 for (int j=0; j < classes.length; j++) { 47 Class c = classes[j]; 48 if (c.getName().endsWith("$" + name)) { 49 return c; 50 } 51 } 52 throw new IllegalArgumentException ("There is no inner class with name '" + name + "' in " + claz); 53 } 54 55 58 private static Cache beanFunctionCache = new Cache(50) { 59 public String getName() { 60 return "BeanFunctionCache"; 61 } 62 public String getDescription() { 63 return "ClassName.FunctionName -> BeanFunction object"; 64 } 65 }; 66 67 71 public static Function getFunction(Class claz, String name) throws IllegalAccessException , InstantiationException , InvocationTargetException { 72 String key = claz.getName() + '.' + name; 73 BeanFunction result = (BeanFunction) beanFunctionCache.get(key); 74 if (result == null) { 75 result = new BeanFunction(claz, name); 76 beanFunctionCache.put(key, result); 77 } 78 return result; 79 } 80 81 85 86 89 private Class claz = null; 90 91 94 private Method method = null; 95 96 99 private List setMethods = new ArrayList(); 100 101 102 103 106 private BeanFunction(Class claz, String name) throws IllegalAccessException , InstantiationException , InvocationTargetException { 107 super(name, null, null); 108 this.claz = claz; 109 110 Method[] methods = claz.getMethods(); 112 for (int i = 0 ; i < methods.length; i++) { 113 Method m = methods[i]; 114 String methodName = m.getName(); 115 if (methodName.equals(name) && m.getParameterTypes().length == 0) { 116 method = m; 117 break; 118 } 119 } 120 121 if (method == null) { 122 throw new IllegalArgumentException ("The class " + claz + " does not have method " + name + " (with no argument)"); 123 } 124 125 127 128 Object sampleInstance = claz.newInstance(); 130 131 List parameters = new ArrayList(); 132 for (int i = 0 ; i < methods.length; i++) { 133 Method method = methods[i]; 134 String methodName = method.getName(); 135 Class [] parameterTypes = method.getParameterTypes(); 136 if (parameterTypes.length == 1 && methodName.startsWith("set")) { 137 String parameterName = methodName.substring(3); 138 Object defaultValue; 140 try { 141 Method getter = claz.getMethod("get" + parameterName, new Class [] {}); 142 defaultValue = getter.invoke(sampleInstance, new Object [] {}); 143 } catch (NoSuchMethodException nsme) { 144 defaultValue = null; 145 } 146 if (Character.isUpperCase(parameterName.charAt(0))) { 147 if (parameterName.length() > 1) { 148 if (! Character.isUpperCase(parameterName.charAt(1))) { 149 parameterName = "" + Character.toLowerCase(parameterName.charAt(0)) + parameterName.substring(1); 150 } 151 } else { 152 parameterName = parameterName.toLowerCase(); 153 } 154 } 155 if (parameterName.equals("node") && org.mmbase.bridge.Node.class.isAssignableFrom(parameterTypes[0])) { 156 parameters.add(Parameter.NODE); 157 } else { 158 parameters.add(new Parameter(parameterName, parameterTypes[0], defaultValue)); 159 } 160 setMethods.add(method); 161 } 162 } 163 setParameterDefinition((Parameter[]) parameters.toArray(new Parameter[0])); 164 ReturnType returnType = new ReturnType(method.getReturnType(), ""); 165 setReturnType(returnType); 166 167 } 168 169 170 174 public Object getFunctionValue(Parameters parameters) { 175 try { 176 Object bean = claz.newInstance(); 177 Iterator i = parameters.iterator(); 178 Iterator j = setMethods.iterator(); 179 while(i.hasNext() && j.hasNext()) { 180 Object value = i.next(); 181 Method method = (Method) j.next(); 182 method.invoke(bean, new Object [] {value}); 183 } 184 Object ret = method.invoke(bean, new Object [] {}); 185 return ret; 186 } catch (Exception e) { 187 throw new RuntimeException (e); 188 } 189 } 190 191 } 192 | Popular Tags |