KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > snipsnap > config > ConfigurationProxy


1 /*
2  * This file is part of "SnipSnap Wiki/Weblog".
3  *
4  * Copyright (c) 2002 Stephan J. Schmidt, Matthias L. Jugel
5  * All Rights Reserved.
6  *
7  * Please visit http://snipsnap.org/ for updates and contact.
8  *
9  * --LICENSE NOTICE--
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  * --LICENSE NOTICE--
24  */

25 package org.snipsnap.config;
26
27 import java.lang.reflect.Field JavaDoc;
28 import java.lang.reflect.InvocationHandler JavaDoc;
29 import java.lang.reflect.Method JavaDoc;
30 import java.lang.reflect.Proxy JavaDoc;
31 import java.lang.reflect.InvocationTargetException JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.Map JavaDoc;
34 import java.util.StringTokenizer JavaDoc;
35 import java.util.Arrays JavaDoc;
36
37 public class ConfigurationProxy implements InvocationHandler JavaDoc {
38   private Map JavaDoc methodCache = new HashMap JavaDoc();
39   private Map JavaDoc propertyMethodCache = new HashMap JavaDoc();
40
41   private ConfigurationMap config = null;
42   private Method JavaDoc getMethod, setMethod;
43   private Method JavaDoc staticGetMethod, staticSetMethod;
44   private Map JavaDoc propertyMethodMap;
45
46   public ConfigurationProxy(ConfigurationMap config) {
47     this.config = config;
48     try {
49       // static get/set methods for globals
50
staticGetMethod = config.getClass().getMethod("getGlobal", new Class JavaDoc[]{String JavaDoc.class});
51       staticSetMethod = config.getClass().getMethod("setGlobal", new Class JavaDoc[]{String JavaDoc.class, String JavaDoc.class});
52       methodCache.put(staticGetMethod.toString(), staticGetMethod);
53       methodCache.put(staticGetMethod.toString(), staticSetMethod);
54
55       // simple get/set methods
56
getMethod = config.getClass().getMethod("get", new Class JavaDoc[]{String JavaDoc.class});
57       setMethod = config.getClass().getMethod("set", new Class JavaDoc[]{String JavaDoc.class, String JavaDoc.class});
58       methodCache.put(getMethod.toString(), getMethod);
59       methodCache.put(setMethod.toString(), setMethod);
60     } catch (Exception JavaDoc 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 JavaDoc();
67     Field JavaDoc[] fields = Configuration.class.getFields();
68     for (int fieldCount = 0; fieldCount < fields.length; fieldCount++) {
69       try {
70         String JavaDoc value = (String JavaDoc) 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 JavaDoc 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 JavaDoc value = (String JavaDoc) 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 JavaDoc e) {
90         System.err.println("ERROR unable to load global property names: " + e);
91         e.printStackTrace();
92       }
93     }
94   }
95
96   /**
97    * Transforms a property name into a CamlCase method name for reflection.
98    *
99    * @param name the name of the property
100    * @param prefix the prefix that should be removed before transforming
101    * @return a java method name usable for reflection
102    */

103   private String JavaDoc getCamlCase(String JavaDoc name, String JavaDoc prefix) {
104     if (name.startsWith(prefix)) {
105       name = name.substring(prefix.length());
106     }
107     StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(name, ".", false);
108     StringBuffer JavaDoc result = new StringBuffer JavaDoc();
109     while (tokenizer.hasMoreTokens()) {
110       String JavaDoc 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   // DYNAMIC PROXY METHODS
120
public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args) throws Throwable JavaDoc {
121     Object JavaDoc result = null;
122     Object JavaDoc[] invokeArgs = args;
123
124 // System.out.println(method.getName() + "(" + (args != null ? "" + Arrays.asList(args) : "") + ") ");
125

126     Method JavaDoc targetMethod = getTargetMethod(method);
127
128     // if we cannot find a method this must be a get/set method
129
if (targetMethod == null) {
130       String JavaDoc methodName = method.getName();
131       targetMethod = (Method JavaDoc)propertyMethodCache.get(methodName);
132       // extend arguments by one and insert property name in front (works for
133
// set(property, value) and get(property), TODO may be optimized
134
if(args != null) {
135         invokeArgs = new Object JavaDoc[args.length + 1];
136         System.arraycopy(args, 0, invokeArgs, 1, args.length);
137       } else {
138         invokeArgs = new Object JavaDoc[1];
139       }
140       invokeArgs[0] = propertyMethodMap.get(methodName);
141     }
142
143     try {
144 // System.out.print(targetMethod.getName() + "(" +
145
// (invokeArgs != null ? "" + Arrays.asList(invokeArgs) : "") +
146
// ") => ");
147
result = targetMethod.invoke(config, invokeArgs);
148     } catch (IllegalAccessException JavaDoc e) {
149       System.err.println("ConfigurationProxy: illegal access to method: "+targetMethod);
150     } catch (IllegalArgumentException JavaDoc e) {
151       System.err.println("ConfigurationProxy: illegal arguments: "+Arrays.asList(invokeArgs));
152       e.printStackTrace();
153     } catch (InvocationTargetException JavaDoc e) {
154       e.getTargetException().printStackTrace();
155
156     }
157 // System.out.println(result);
158
return result;
159   }
160
161   private Method JavaDoc getTargetMethod(Method JavaDoc method) {
162     String JavaDoc methodKey = method.toString();
163     if (methodCache.containsKey(methodKey)) {
164       return (Method JavaDoc) methodCache.get(methodKey);
165     } else {
166       try {
167         Method JavaDoc targetMethod = config.getClass().getMethod(method.getName(), method.getParameterTypes());
168         methodCache.put(targetMethod.toString(), targetMethod);
169         return targetMethod;
170       } catch (NoSuchMethodException JavaDoc e) {
171         // ignore non-existing methods
172
} catch (SecurityException JavaDoc e) {
173         e.printStackTrace();
174       }
175     }
176     return null;
177   }
178
179   // PROXY FACTORY HANDLING
180
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 JavaDoc[]{Configuration.class, Globals.class},
200                                                    new ConfigurationProxy(config));
201     return proxy;
202   }
203
204 }
205
Popular Tags