001: ///////////////////////////////////////////////////////////////////////////////
002: //
003: // Copyright (C) 2003-@year@ by Thomas M. Hazel, MyOODB (www.myoodb.org)
004: //
005: // All Rights Reserved
006: //
007: // This program is free software; you can redistribute it and/or modify
008: // it under the terms of the GNU General Public License and GNU Library
009: // General Public License as published by the Free Software Foundation;
010: // either version 2, or (at your option) any later version.
011: //
012: // This program is distributed in the hope that it will be useful,
013: // but WITHOUT ANY WARRANTY; without even the implied warranty of
014: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: // GNU General Public License and GNU Library General Public License
016: // for more details.
017: //
018: // You should have received a copy of the GNU General Public License
019: // and GNU Library General Public License along with this program; if
020: // not, write to the Free Software Foundation, 675 Mass Ave, Cambridge,
021: // MA 02139, USA.
022: //
023: ///////////////////////////////////////////////////////////////////////////////
024: package org.myoodb.core;
025:
026: import java.util.*;
027: import java.lang.reflect.*;
028:
029: import org.myoodb.*;
030:
031: public final class MethodHelper {
032: protected static final HashMap CLASS_TABLE = new HashMap(128);
033: protected static final HashMap METHOD_TABLE = new HashMap(128);
034:
035: public final static String SIGNATURE_DELIMITER = ",";
036:
037: public static String getSignature(Class[] args) {
038: StringBuilder result = new StringBuilder();
039: result.append("\"");
040: for (int i = 0; i < args.length; i++) {
041: if (i > 0) {
042: result.append(SIGNATURE_DELIMITER);
043: }
044: result.append(args[i].getName());
045: }
046: result.append("\"");
047: return result.toString();
048: }
049:
050: public static String getSignature(String[] args) {
051: StringBuilder result = new StringBuilder();
052: result.append("\"");
053: for (int i = 0; i < args.length; i++) {
054: if (i > 0) {
055: result.append(SIGNATURE_DELIMITER);
056: }
057: result.append(args[i]);
058: }
059: result.append("\"");
060: return result.toString();
061: }
062:
063: public static int getMethodIndex(Method[] methods, Method method) {
064: for (int i = 0; i < methods.length; i++) {
065: if (method.equals(methods[i]) == true) {
066: return i;
067: }
068: }
069:
070: throw new org.myoodb.exception.InternalException(
071: "MethodHelper.getMethodIndex (unable to find method: "
072: + method + " )");
073: }
074:
075: public static Method[] getMethods(Class classType,
076: Class interfaceType) {
077: Method[] implMethods = classType.getMethods();
078: Method[] interfaceMethods = interfaceType.getMethods();
079:
080: TreeSet initSet = new TreeSet();
081: for (int i = 0; i < implMethods.length; i++) {
082: String implName = implMethods[i].getName();
083: String implSig = MethodHelper.getSignature(implMethods[i]
084: .getParameterTypes());
085: MethodSignature implMethodSig = new MethodSignature(
086: interfaceType.getName(), implName, implSig,
087: implMethods[i]);
088: initSet.add(implMethodSig);
089: }
090:
091: TreeMap indexMap = new TreeMap();
092: for (int j = 0; j < interfaceMethods.length; j++) {
093: String interfaceName = interfaceMethods[j].getName();
094: String interfaceSig = MethodHelper
095: .getSignature(interfaceMethods[j]
096: .getParameterTypes());
097: MethodSignature interfaceMethodSig = new MethodSignature(
098: interfaceType.getName(), interfaceName,
099: interfaceSig, null);
100:
101: org.myoodb.MyOodbIndex index = null;
102: MethodSignature foundMethodSig = null;
103:
104: for (int k = 0; k < implMethods.length; k++) {
105: String implName = implMethods[k].getName();
106: String implSig = MethodHelper
107: .getSignature(implMethods[k]
108: .getParameterTypes());
109: MethodSignature implMethodSig = new MethodSignature(
110: interfaceType.getName(), implName, implSig,
111: implMethods[k]);
112:
113: if (interfaceMethodSig.equals(implMethodSig) == true) {
114: foundMethodSig = implMethodSig;
115: index = interfaceMethods[j]
116: .getAnnotation(org.myoodb.MyOodbIndex.class);
117: break;
118: }
119: }
120:
121: if (index != null) {
122: indexMap
123: .put(new Integer(index.value()), foundMethodSig);
124: initSet.remove(foundMethodSig);
125: }
126: }
127:
128: int index = 0;
129: Iterator iter = indexMap.values().iterator();
130: while (iter.hasNext()) {
131: MethodSignature methodSig = (MethodSignature) iter.next();
132: implMethods[index++] = methodSig.getMethod();
133: }
134:
135: iter = initSet.iterator();
136: while (iter.hasNext()) {
137: MethodSignature methodSig = (MethodSignature) iter.next();
138: implMethods[index++] = methodSig.getMethod();
139: }
140:
141: return implMethods;
142: }
143:
144: public static Method[] getMethods(Class classType) {
145: synchronized (CLASS_TABLE) {
146: Method[] methods = (Method[]) CLASS_TABLE.get(classType);
147:
148: if (methods == null) {
149: Class interfaceType = null;
150:
151: try {
152: String className = classType.getName();
153: className = className.substring(0, className
154: .length()
155: - AbstractObjectContainer.IMPL_NAME_SUFFIX
156: .length());
157: interfaceType = Class.forName(className);
158: } catch (java.lang.ClassNotFoundException e) {
159: // XXX: this should never happen
160: e.printStackTrace();
161: }
162:
163: methods = MethodHelper.getMethods(classType,
164: interfaceType);
165: CLASS_TABLE.put(classType, methods);
166: }
167:
168: return methods;
169: }
170: }
171:
172: public static Constructor getConstructor(Class classType, String sig)
173: throws ClassNotFoundException, NoSuchMethodException {
174: synchronized (METHOD_TABLE) {
175: MethodSignature def = new MethodSignature(classType
176: .getName(), "CONSTRUCTOR", sig);
177: Constructor constructor = (Constructor) METHOD_TABLE
178: .get(def);
179:
180: if (constructor == null) {
181: Class[] classes;
182: if (sig == null) {
183: classes = new Class[0];
184: } else {
185: StringTokenizer st = new StringTokenizer(sig,
186: MethodHelper.SIGNATURE_DELIMITER);
187: classes = new Class[st.countTokens()];
188: for (int i = 0; st.hasMoreTokens(); i++) {
189: classes[i] = MyOodbManager.getTheManager()
190: .getClassManager().getClass(
191: st.nextToken());
192: }
193: }
194:
195: constructor = classType.getConstructor(classes);
196: METHOD_TABLE.put(def, constructor);
197: }
198:
199: return constructor;
200: }
201: }
202:
203: public static final Method getMethod(MyOodbLocal[] targets,
204: Object obj, String methodName, String sig, Object[] args)
205: throws Exception {
206: Method method = null;
207:
208: for (int i = 0; i < targets.length; i++) {
209: synchronized (METHOD_TABLE) {
210: MethodSignature def = new MethodSignature(targets[i]
211: .getClass().getName(), methodName, sig);
212: method = (Method) METHOD_TABLE.get(def);
213:
214: if (method == null) {
215: Class[] classes = new Class[args.length];
216: StringTokenizer st = new StringTokenizer(sig,
217: MethodHelper.SIGNATURE_DELIMITER);
218: for (int j = 0; st.hasMoreTokens(); ++j) {
219: classes[j] = MyOodbManager.getTheManager()
220: .getClassManager().getClass(
221: st.nextToken());
222: }
223:
224: try {
225: method = obj.getClass().getMethod(methodName,
226: classes);
227: METHOD_TABLE.put(def, method);
228: } catch (java.lang.NoSuchMethodException e) {
229: // nothing to do
230: }
231: }
232: }
233:
234: if (method != null) {
235: break;
236: }
237: }
238:
239: return method;
240: }
241:
242: public static Method getAssociatedBeanGetMethod(Method method,
243: Method[] methods) {
244: String name = method.getName();
245:
246: if ((name.length() <= 3) || (name.equals("setXML") == true)
247: || (name.equals("getXML") == true)
248: || (name.equals("setBean") == true)
249: || (name.equals("getBean") == true)) {
250: return null;
251: }
252:
253: String suffix = name.substring(0, 3);
254:
255: if ((suffix.equals("set") == true)
256: && (method.getParameterTypes().length == 1)) {
257: String getMethod = "get" + name.substring(3);
258:
259: for (int methodIndex = 0; methodIndex < methods.length; methodIndex++) {
260: method = methods[methodIndex];
261:
262: if ((method.getName().equals(getMethod) == true)
263: && (method.getParameterTypes().length == 0)) {
264: return method;
265: }
266: }
267: }
268:
269: return null;
270: }
271:
272: public static Method getAssociatedBeanRemoveMethod(Method method,
273: Method[] methods) {
274: String name = method.getName();
275:
276: if (name.length() <= 3) {
277: return null;
278: }
279:
280: String suffix = name.substring(0, 3);
281:
282: if ((suffix.equals("add") == true)
283: && (method.getParameterTypes().length == 1)) {
284: String removeMethod = "remove" + name.substring(3);
285:
286: for (int methodIndex = 0; methodIndex < methods.length; methodIndex++) {
287: method = methods[methodIndex];
288:
289: if ((method.getName().equals(removeMethod) == true)
290: && (method.getParameterTypes().length == 1)) {
291: return method;
292: }
293: }
294: }
295:
296: return null;
297: }
298:
299: public static Method getAssociatedBeanGetsMethod(Method method,
300: Method[] methods) {
301: String name = method.getName();
302:
303: if (name.length() <= 3) {
304: return null;
305: }
306:
307: String suffix = name.substring(0, 3);
308:
309: if ((suffix.equals("add") == true)
310: && (method.getParameterTypes().length == 1)) {
311: String getsMethod = "get" + name.substring(3) + "s";
312:
313: for (int methodIndex = 0; methodIndex < methods.length; methodIndex++) {
314: method = methods[methodIndex];
315:
316: if ((method.getName().equals(getsMethod) == true)
317: && (method.getParameterTypes().length == 0)) {
318: return method;
319: }
320: }
321: }
322:
323: return null;
324: }
325: }
|