1 17 18 package org.apache.geronimo.gbean; 19 20 import java.beans.Introspector ; 21 import java.lang.reflect.InvocationTargetException ; 22 import java.lang.reflect.Method ; 23 import java.util.HashMap ; 24 import java.util.Map ; 25 import java.util.Set ; 26 import java.util.List ; 27 import java.util.ArrayList ; 28 import java.util.Iterator ; 29 30 import net.sf.cglib.reflect.FastClass; 31 import net.sf.cglib.reflect.FastMethod; 32 33 34 39 public class DynamicGBeanDelegate implements DynamicGBean { 40 protected final Map getters = new HashMap (); 41 protected final Map setters = new HashMap (); 42 protected final Map operations = new HashMap (); 43 private Class targetClass; 44 45 public void addAll(Object target) { 46 this.targetClass = target.getClass(); 47 Method [] methods = targetClass.getMethods(); 48 for (int i = 0; i < methods.length; i++) { 49 Method method = methods[i]; 50 if (isGetter(method)) { 51 addGetter(target, method); 52 } else if (isSetter(method)) { 53 addSetter(target, method); 54 } else { 55 addOperation(target, method); 56 } 57 } 58 } 59 60 public void addGetter(Object target, Method method) { 61 String name = method.getName(); 62 if (name.startsWith("get")) { 63 addGetter(name.substring(3), target, method); 64 } else if (name.startsWith("is")) { 65 addGetter(name.substring(2), target, method); 66 } else { 67 throw new IllegalArgumentException ("Method name must start with 'get' or 'is' " + method); 68 } 69 } 70 71 public void addGetter(String name, Object target, Method method) { 72 if (!(method.getParameterTypes().length == 0 && method.getReturnType() != Void.TYPE)) { 73 throw new IllegalArgumentException ("Method must take no parameters and return a value " + method); 74 } 75 getters.put(name, new Operation(target, method)); 76 getters.put(Introspector.decapitalize(name), new Operation(target, method)); 79 } 80 81 public void addSetter(Object target, Method method) { 82 if (!method.getName().startsWith("set")) { 83 throw new IllegalArgumentException ("Method name must start with 'set' " + method); 84 } 85 addSetter(method.getName().substring(3), target, method); 86 } 87 88 public void addSetter(String name, Object target, Method method) { 89 if (!(method.getParameterTypes().length == 1 && method.getReturnType() == Void.TYPE)) { 90 throw new IllegalArgumentException ("Method must take one parameter and not return anything " + method); 91 } 92 setters.put(name, new Operation(target, method)); 93 setters.put(Introspector.decapitalize(name), new Operation(target, method)); 96 } 97 98 public void addOperation(Object target, Method method) { 99 Class [] parameters = method.getParameterTypes(); 100 String [] types = new String [parameters.length]; 101 for (int i = 0; i < parameters.length; i++) { 102 types[i] = parameters[i].getName(); 103 } 104 GOperationSignature key = new GOperationSignature(method.getName(), types); 105 operations.put(key, new Operation(target, method)); 106 } 107 108 private boolean isGetter(Method method) { 109 String name = method.getName(); 110 return (name.startsWith("get") || name.startsWith("is")) && 111 method.getParameterTypes().length == 0 112 && method.getReturnType() != Void.TYPE; 113 } 114 115 private boolean isSetter(Method method) { 116 return method.getName().startsWith("set") && 117 method.getParameterTypes().length == 1 && 118 method.getReturnType() == Void.TYPE; 119 } 120 121 public Object getAttribute(String name) throws Exception { 122 Operation operation = (Operation) getters.get(name); 123 if (operation == null) { 124 throw new IllegalArgumentException (targetClass.getName() + ": no getter for " + name); 125 } 126 return operation.invoke(null); 127 } 128 129 public void setAttribute(String name, Object value) throws Exception { 130 Operation operation = (Operation) setters.get(name); 131 if (operation == null) { 132 throw new IllegalArgumentException (targetClass.getName() + ": no setter for " + name); 133 } 134 operation.invoke(new Object []{value}); 135 } 136 137 public Object invoke(String name, Object [] arguments, String [] types) throws Exception { 138 GOperationSignature signature = new GOperationSignature(name, types); 139 Operation operation = (Operation) operations.get(signature); 140 if (operation == null) { 141 throw new IllegalArgumentException (targetClass.getName() + ": no operation " + signature); 142 } 143 return operation.invoke(arguments); 144 } 145 146 150 public String [] getProperties() { 151 Set one = getters.keySet(); 152 Set two = setters.keySet(); 153 List out = new ArrayList (); 154 for (Iterator it = one.iterator(); it.hasNext();) { 155 String name = (String ) it.next(); 156 if(Character.isLowerCase(name.charAt(0)) && two.contains(name)) { 157 out.add(name); 158 } 159 } 160 return (String []) out.toArray(new String [out.size()]); 161 } 162 163 public Class getPropertyType(String name) { 164 Operation oper = (Operation) getters.get(name); 165 return oper.method.getReturnType(); 166 } 167 168 protected static class Operation { 169 private final Object target; 170 private final FastMethod method; 171 172 public Operation(Object target, Method method) { 173 assert target != null; 174 assert method != null; 175 this.target = target; 176 this.method = FastClass.create(target.getClass()).getMethod(method); 177 } 178 179 public Object invoke(Object [] arguments) throws Exception { 180 try { 181 return method.invoke(target, arguments); 182 } catch (InvocationTargetException e) { 183 Throwable targetException = e.getTargetException(); 184 if (targetException instanceof Exception ) { 185 throw (Exception ) targetException; 186 } else if (targetException instanceof Error ) { 187 throw (Error ) targetException; 188 } 189 throw e; 190 } 191 } 192 } 193 } 194 | Popular Tags |