1 25 package org.snipsnap.config; 26 27 import java.lang.reflect.Field ; 28 import java.lang.reflect.InvocationHandler ; 29 import java.lang.reflect.Method ; 30 import java.lang.reflect.Proxy ; 31 import java.lang.reflect.InvocationTargetException ; 32 import java.util.HashMap ; 33 import java.util.Map ; 34 import java.util.StringTokenizer ; 35 import java.util.Arrays ; 36 37 public class ConfigurationProxy implements InvocationHandler { 38 private Map methodCache = new HashMap (); 39 private Map propertyMethodCache = new HashMap (); 40 41 private ConfigurationMap config = null; 42 private Method getMethod, setMethod; 43 private Method staticGetMethod, staticSetMethod; 44 private Map propertyMethodMap; 45 46 public ConfigurationProxy(ConfigurationMap config) { 47 this.config = config; 48 try { 49 staticGetMethod = config.getClass().getMethod("getGlobal", new Class []{String .class}); 51 staticSetMethod = config.getClass().getMethod("setGlobal", new Class []{String .class, String .class}); 52 methodCache.put(staticGetMethod.toString(), staticGetMethod); 53 methodCache.put(staticGetMethod.toString(), staticSetMethod); 54 55 getMethod = config.getClass().getMethod("get", new Class []{String .class}); 57 setMethod = config.getClass().getMethod("set", new Class []{String .class, String .class}); 58 methodCache.put(getMethod.toString(), getMethod); 59 methodCache.put(setMethod.toString(), setMethod); 60 } catch (Exception e) { 61 System.err.println("FATAL ERROR: unable to get get/set methods of configuration map"); 62 e.printStackTrace(); 63 getMethod = null; 64 } 65 66 propertyMethodMap = new HashMap (); 67 Field [] fields = Configuration.class.getFields(); 68 for (int fieldCount = 0; fieldCount < fields.length; fieldCount++) { 69 try { 70 String value = (String ) fields[fieldCount].get(Configuration.class); 71 propertyMethodMap.put("get" + getCamlCase(value, "app."), value); 72 propertyMethodMap.put("set" + getCamlCase(value, "app."), value); 73 propertyMethodCache.put("get" + getCamlCase(value, "app."), getMethod); 74 propertyMethodCache.put("set" + getCamlCase(value, "app."), setMethod); 75 } catch (Exception e) { 76 System.err.println("ERROR unable to load property names: " + e); 77 e.printStackTrace(); 78 } 79 } 80 81 fields = Globals.class.getFields(); 82 for(int fieldCount = 0; fieldCount < fields.length; fieldCount++) { 83 try { 84 String value = (String ) fields[fieldCount].get(Globals.class); 85 propertyMethodMap.put("get" + getCamlCase(value, "app."), value); 86 propertyMethodMap.put("set" + getCamlCase(value, "app."), value); 87 propertyMethodCache.put("get" + getCamlCase(value, "app."), staticGetMethod); 88 propertyMethodCache.put("set" + getCamlCase(value, "app."), staticSetMethod); 89 } catch (Exception e) { 90 System.err.println("ERROR unable to load global property names: " + e); 91 e.printStackTrace(); 92 } 93 } 94 } 95 96 103 private String getCamlCase(String name, String prefix) { 104 if (name.startsWith(prefix)) { 105 name = name.substring(prefix.length()); 106 } 107 StringTokenizer tokenizer = new StringTokenizer (name, ".", false); 108 StringBuffer result = new StringBuffer (); 109 while (tokenizer.hasMoreTokens()) { 110 String token = tokenizer.nextToken(); 111 result.append(token.substring(0, 1).toUpperCase()); 112 if (token.length() > 1) { 113 result.append(token.substring(1)); 114 } 115 } 116 return result.toString(); 117 } 118 119 public Object invoke(Object proxy, Method method, Object [] args) throws Throwable { 121 Object result = null; 122 Object [] invokeArgs = args; 123 124 126 Method targetMethod = getTargetMethod(method); 127 128 if (targetMethod == null) { 130 String methodName = method.getName(); 131 targetMethod = (Method )propertyMethodCache.get(methodName); 132 if(args != null) { 135 invokeArgs = new Object [args.length + 1]; 136 System.arraycopy(args, 0, invokeArgs, 1, args.length); 137 } else { 138 invokeArgs = new Object [1]; 139 } 140 invokeArgs[0] = propertyMethodMap.get(methodName); 141 } 142 143 try { 144 result = targetMethod.invoke(config, invokeArgs); 148 } catch (IllegalAccessException e) { 149 System.err.println("ConfigurationProxy: illegal access to method: "+targetMethod); 150 } catch (IllegalArgumentException e) { 151 System.err.println("ConfigurationProxy: illegal arguments: "+Arrays.asList(invokeArgs)); 152 e.printStackTrace(); 153 } catch (InvocationTargetException e) { 154 e.getTargetException().printStackTrace(); 155 156 } 157 return result; 159 } 160 161 private Method getTargetMethod(Method method) { 162 String methodKey = method.toString(); 163 if (methodCache.containsKey(methodKey)) { 164 return (Method ) methodCache.get(methodKey); 165 } else { 166 try { 167 Method targetMethod = config.getClass().getMethod(method.getName(), method.getParameterTypes()); 168 methodCache.put(targetMethod.toString(), targetMethod); 169 return targetMethod; 170 } catch (NoSuchMethodException e) { 171 } catch (SecurityException e) { 173 e.printStackTrace(); 174 } 175 } 176 return null; 177 } 178 179 public static Configuration proxy = null; 181 182 public static Configuration getInstance() { 183 if (proxy == null) { 184 newInstance(); 185 } 186 return proxy; 187 } 188 189 public static Configuration newInstance() { 190 return newProxyInstance(new ConfigurationMap()); 191 } 192 193 public static Configuration newInstance(Configuration config) { 194 return newProxyInstance(new ConfigurationMap(config)); 195 } 196 197 private static Configuration newProxyInstance(ConfigurationMap config) { 198 proxy = (Configuration) Proxy.newProxyInstance(config.getClass().getClassLoader(), 199 new Class []{Configuration.class, Globals.class}, 200 new ConfigurationProxy(config)); 201 return proxy; 202 } 203 204 } 205 | Popular Tags |