001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.commons.modeler.util;
019:
020: import java.io.File;
021: import java.io.FilenameFilter;
022: import java.io.IOException;
023: import java.lang.reflect.InvocationTargetException;
024: import java.lang.reflect.Method;
025: import java.net.InetAddress;
026: import java.net.MalformedURLException;
027: import java.net.URL;
028: import java.net.UnknownHostException;
029: import java.util.Hashtable;
030: import java.util.StringTokenizer;
031: import java.util.Vector;
032:
033: // Depends:
034: // JDK1.1
035:
036: /**
037: * Utils for introspection and reflection
038: *
039: * Source: jakarta-tomcat-connector/util
040: */
041: public final class IntrospectionUtils {
042: static final Class NO_PARAMS[] = new Class[0];
043: static final Class STRING_OBJ_PARAM[] = new Class[] { String.class,
044: Object.class };
045: static final Class STRING_PARAM[] = new Class[] { String.class };
046:
047: /** Execute a no-param method.
048: */
049: public static void execute(Object proxy, String method)
050: throws Exception {
051: Method executeM = null;
052: Class c = proxy.getClass();
053: executeM = findMethod(c, method, NO_PARAMS);
054: if (executeM == null) {
055: throw new RuntimeException("No method " + method + " in "
056: + proxy.getClass());
057: }
058: executeM.invoke(proxy, (Object[]) null);
059: }
060:
061: /**
062: * Call void setAttribute( String ,Object )
063: */
064: public static void setAttribute(Object proxy, String n, Object v)
065: throws Exception {
066: if (proxy instanceof AttributeHolder) {
067: ((AttributeHolder) proxy).setAttribute(n, v);
068: return;
069: }
070:
071: Method executeM = null;
072: Class c = proxy.getClass();
073: executeM = findMethod(c, "setAttribute", STRING_OBJ_PARAM);
074:
075: if (executeM == null) {
076: System.out
077: .println("No setAttribute in " + proxy.getClass());
078: return;
079: }
080: executeM.invoke(proxy, new Object[] { n, v });
081: return;
082: }
083:
084: /**
085: * Call void getAttribute( String )
086: */
087: public static Object getAttribute(Object proxy, String n)
088: throws Exception {
089: Method executeM = null;
090: Class c = proxy.getClass();
091: executeM = findMethod(c, "getAttribute", STRING_PARAM);
092: if (executeM == null) {
093: System.out
094: .println("No getAttribute in " + proxy.getClass());
095: return null;
096: }
097: return executeM.invoke(proxy, new Object[] { n });
098: }
099:
100: /** Construct a URLClassLoader. Will compile and work in JDK1.1 too.
101: */
102: public static ClassLoader getURLClassLoader(URL urls[],
103: ClassLoader parent) {
104: try {
105: Class urlCL = Class.forName("java.net.URLClassLoader");
106: Class paramT[] = new Class[2];
107: paramT[0] = urls.getClass();
108: paramT[1] = ClassLoader.class;
109: Method m = findMethod(urlCL, "newInstance", paramT);
110: if (m == null)
111: return null;
112:
113: ClassLoader cl = (ClassLoader) m.invoke(urlCL,
114: new Object[] { urls, parent });
115: return cl;
116: } catch (ClassNotFoundException ex) {
117: // jdk1.1
118: return null;
119: } catch (Exception ex) {
120: ex.printStackTrace();
121: return null;
122: }
123: }
124:
125: public static String guessInstall(String installSysProp,
126: String homeSysProp, String jarName) {
127: return guessInstall(installSysProp, homeSysProp, jarName, null);
128: }
129:
130: /** Guess a product install/home by analyzing the class path.
131: * It works for product using the pattern: lib/executable.jar
132: * or if executable.jar is included in classpath by a shell
133: * script. ( java -jar also works )
134: *
135: * Insures both "install" and "home" System properties are set.
136: * If either or both System properties are unset, "install" and
137: * "home" will be set to the same value. This value will be
138: * the other System property that is set, or the guessed value
139: * if neither is set.
140: */
141: public static String guessInstall(String installSysProp,
142: String homeSysProp, String jarName, String classFile) {
143: String install = null;
144: String home = null;
145:
146: if (installSysProp != null)
147: install = System.getProperty(installSysProp);
148:
149: if (homeSysProp != null)
150: home = System.getProperty(homeSysProp);
151:
152: if (install != null) {
153: if (home == null)
154: System.getProperties().put(homeSysProp, install);
155: return install;
156: }
157:
158: // Find the directory where jarName.jar is located
159:
160: String cpath = System.getProperty("java.class.path");
161: String pathSep = System.getProperty("path.separator");
162: StringTokenizer st = new StringTokenizer(cpath, pathSep);
163: while (st.hasMoreTokens()) {
164: String path = st.nextToken();
165: // log( "path " + path );
166: if (path.endsWith(jarName)) {
167: home = path.substring(0, path.length()
168: - jarName.length());
169: try {
170: if ("".equals(home)) {
171: home = new File("./").getCanonicalPath();
172: } else if (home.endsWith(File.separator)) {
173: home = home.substring(0, home.length() - 1);
174: }
175: File f = new File(home);
176: String parentDir = f.getParent();
177: if (parentDir == null)
178: parentDir = home; // unix style
179: File f1 = new File(parentDir);
180: install = f1.getCanonicalPath();
181: if (installSysProp != null)
182: System.getProperties().put(installSysProp,
183: install);
184: if (home == null && homeSysProp != null)
185: System.getProperties()
186: .put(homeSysProp, install);
187: return install;
188: } catch (Exception ex) {
189: ex.printStackTrace();
190: }
191: } else {
192: String fname = path + (path.endsWith("/") ? "" : "/")
193: + classFile;
194: if (new File(fname).exists()) {
195: try {
196: File f = new File(path);
197: String parentDir = f.getParent();
198: if (parentDir == null)
199: parentDir = path; // unix style
200: File f1 = new File(parentDir);
201: install = f1.getCanonicalPath();
202: if (installSysProp != null)
203: System.getProperties().put(installSysProp,
204: install);
205: if (home == null && homeSysProp != null)
206: System.getProperties().put(homeSysProp,
207: install);
208: return install;
209: } catch (Exception ex) {
210: ex.printStackTrace();
211: }
212: }
213: }
214: }
215:
216: // if install directory can't be found, use home as the default
217: if (home != null) {
218: System.getProperties().put(installSysProp, home);
219: return home;
220: }
221:
222: return null;
223: }
224:
225: /** Debug method, display the classpath
226: */
227: public static void displayClassPath(String msg, URL[] cp) {
228: System.out.println(msg);
229: for (int i = 0; i < cp.length; i++) {
230: System.out.println(cp[i].getFile());
231: }
232: }
233:
234: public static String PATH_SEPARATOR = System
235: .getProperty("path.separator");
236:
237: /**
238: * Adds classpath entries from a vector of URL's to the
239: * "tc_path_add" System property. This System property lists
240: * the classpath entries common to web applications. This System
241: * property is currently used by Jasper when its JSP servlet
242: * compiles the Java file for a JSP.
243: */
244: public static String classPathAdd(URL urls[], String cp) {
245: if (urls == null)
246: return cp;
247:
248: for (int i = 0; i < urls.length; i++) {
249: if (cp != null)
250: cp += PATH_SEPARATOR + urls[i].getFile();
251: else
252: cp = urls[i].getFile();
253: }
254: return cp;
255: }
256:
257: /** Find a method with the right name
258: If found, call the method ( if param is int or boolean we'll convert
259: value to the right type before) - that means you can have setDebug(1).
260: */
261: public static void setProperty(Object o, String name, String value) {
262: if (dbg > 1)
263: d("setProperty(" + o.getClass() + " " + name + "=" + value
264: + ")");
265:
266: String setter = "set" + capitalize(name);
267:
268: try {
269: Method methods[] = findMethods(o.getClass());
270: Method setPropertyMethod = null;
271:
272: // First, the ideal case - a setFoo( String ) method
273: for (int i = 0; i < methods.length; i++) {
274: Class paramT[] = methods[i].getParameterTypes();
275: if (setter.equals(methods[i].getName())
276: && paramT.length == 1
277: && "java.lang.String".equals(paramT[0]
278: .getName())) {
279:
280: methods[i].invoke(o, new Object[] { value });
281: return;
282: }
283: }
284:
285: // Try a setFoo ( int ) or ( boolean )
286: for (int i = 0; i < methods.length; i++) {
287: boolean ok = true;
288: if (setter.equals(methods[i].getName())
289: && methods[i].getParameterTypes().length == 1) {
290:
291: // match - find the type and invoke it
292: Class paramType = methods[i].getParameterTypes()[0];
293: Object params[] = new Object[1];
294:
295: // Try a setFoo ( int )
296: if ("java.lang.Integer".equals(paramType.getName())
297: || "int".equals(paramType.getName())) {
298: try {
299: params[0] = new Integer(value);
300: } catch (NumberFormatException ex) {
301: ok = false;
302: }
303:
304: // Try a setFoo ( boolean )
305: } else if ("java.lang.Boolean".equals(paramType
306: .getName())
307: || "boolean".equals(paramType.getName())) {
308: params[0] = new Boolean(value);
309:
310: // Try a setFoo ( InetAddress )
311: } else if ("java.net.InetAddress".equals(paramType
312: .getName())) {
313: try {
314: params[0] = InetAddress.getByName(value);
315: } catch (UnknownHostException exc) {
316: d("Unable to resolve host name:" + value);
317: ok = false;
318: }
319:
320: // Try a setFoo ( Object )
321: } else if ("java.lang.Object".equals(paramType
322: .getName())) {
323: params[0] = value;
324:
325: // Unknown type
326: } else {
327: d("Unknown type " + paramType.getName());
328: }
329:
330: if (ok) {
331: methods[i].invoke(o, params);
332: return;
333: }
334: }
335:
336: // save "setProperty" for later
337: if ("setProperty".equals(methods[i].getName())) {
338: setPropertyMethod = methods[i];
339: }
340: }
341:
342: // Ok, no setXXX found, try a setProperty("name", "value")
343: if (setPropertyMethod != null) {
344: Object params[] = new Object[2];
345: params[0] = name;
346: params[1] = value;
347: setPropertyMethod.invoke(o, params);
348: }
349:
350: } catch (IllegalArgumentException ex2) {
351: System.err.println("IAE " + o + " " + name + " " + value);
352: ex2.printStackTrace();
353: } catch (SecurityException ex1) {
354: if (dbg > 0)
355: d("SecurityException for " + o.getClass() + " " + name
356: + "=" + value + ")");
357: if (dbg > 1)
358: ex1.printStackTrace();
359: } catch (IllegalAccessException iae) {
360: if (dbg > 0)
361: d("IllegalAccessException for " + o.getClass() + " "
362: + name + "=" + value + ")");
363: if (dbg > 1)
364: iae.printStackTrace();
365: } catch (InvocationTargetException ie) {
366: if (dbg > 0)
367: d("InvocationTargetException for " + o.getClass() + " "
368: + name + "=" + value + ")");
369: if (dbg > 1)
370: ie.printStackTrace();
371: }
372: }
373:
374: public static Object getProperty(Object o, String name) {
375: String getter = "get" + capitalize(name);
376:
377: try {
378: Method methods[] = findMethods(o.getClass());
379: Method getPropertyMethod = null;
380:
381: // First, the ideal case - a getFoo() method
382: for (int i = 0; i < methods.length; i++) {
383: Class paramT[] = methods[i].getParameterTypes();
384: if (getter.equals(methods[i].getName())
385: && paramT.length == 0) {
386: return methods[i].invoke(o, (Object[]) null);
387: }
388:
389: if ("getProperty".equals(methods[i].getName())) {
390: getPropertyMethod = methods[i];
391: }
392: if ("getAttribute".equals(methods[i].getName())) {
393: getPropertyMethod = methods[i];
394: }
395: }
396:
397: // Ok, no setXXX found, try a getProperty("name")
398: if (getPropertyMethod != null) {
399: Object params[] = new Object[1];
400: params[0] = name;
401: getPropertyMethod.invoke(o, params);
402: }
403:
404: } catch (IllegalArgumentException ex2) {
405: System.err.println("IAE " + o + " " + name);
406: ex2.printStackTrace();
407: } catch (SecurityException ex1) {
408: if (dbg > 0)
409: d("SecurityException for " + o.getClass() + " " + name
410: + ")");
411: if (dbg > 1)
412: ex1.printStackTrace();
413: } catch (IllegalAccessException iae) {
414: if (dbg > 0)
415: d("IllegalAccessException for " + o.getClass() + " "
416: + name + ")");
417: if (dbg > 1)
418: iae.printStackTrace();
419: } catch (InvocationTargetException ie) {
420: if (dbg > 0)
421: d("InvocationTargetException for " + o.getClass() + " "
422: + name + ")");
423: if (dbg > 1)
424: ie.printStackTrace();
425: }
426: return null;
427: }
428:
429: /**
430: */
431: public static void setProperty(Object o, String name) {
432: String setter = "set" + capitalize(name);
433: try {
434: Method methods[] = findMethods(o.getClass());
435: Method setPropertyMethod = null;
436: // find setFoo() method
437: for (int i = 0; i < methods.length; i++) {
438: Class paramT[] = methods[i].getParameterTypes();
439: if (setter.equals(methods[i].getName())
440: && paramT.length == 0) {
441: methods[i].invoke(o, new Object[] {});
442: return;
443: }
444: }
445: } catch (Exception ex1) {
446: if (dbg > 0)
447: d("Exception for " + o.getClass() + " " + name);
448: if (dbg > 1)
449: ex1.printStackTrace();
450: }
451: }
452:
453: /** Replace ${NAME} with the property value
454: * @deprecated Use the explicit method
455: */
456: public static String replaceProperties(String value, Object getter) {
457: if (getter instanceof Hashtable)
458: return replaceProperties(value, (Hashtable) getter, null);
459:
460: if (getter instanceof PropertySource) {
461: PropertySource src[] = new PropertySource[] { (PropertySource) getter };
462: return replaceProperties(value, null, src);
463: }
464: return value;
465: }
466:
467: /** Replace ${NAME} with the property value
468: */
469: public static String replaceProperties(String value,
470: Hashtable staticProp, PropertySource dynamicProp[]) {
471: StringBuffer sb = new StringBuffer();
472: int prev = 0;
473: // assert value!=nil
474: int pos;
475: while ((pos = value.indexOf("$", prev)) >= 0) {
476: if (pos > 0) {
477: sb.append(value.substring(prev, pos));
478: }
479: if (pos == (value.length() - 1)) {
480: sb.append('$');
481: prev = pos + 1;
482: } else if (value.charAt(pos + 1) != '{') {
483: sb.append(value.charAt(pos + 1));
484: prev = pos + 2; // XXX
485: } else {
486: int endName = value.indexOf('}', pos);
487: if (endName < 0) {
488: sb.append(value.substring(pos));
489: prev = value.length();
490: continue;
491: }
492: String n = value.substring(pos + 2, endName);
493: String v = null;
494: if (staticProp != null) {
495: v = (String) ((Hashtable) staticProp).get(n);
496: }
497: if (v == null && dynamicProp != null) {
498: for (int i = 0; i < dynamicProp.length; i++) {
499: v = dynamicProp[i].getProperty(n);
500: if (v != null) {
501: break;
502: }
503: }
504: }
505: if (v == null)
506: v = "${" + n + "}";
507:
508: sb.append(v);
509: prev = endName + 1;
510: }
511: }
512: if (prev < value.length())
513: sb.append(value.substring(prev));
514: return sb.toString();
515: }
516:
517: /** Reverse of Introspector.decapitalize
518: */
519: public static String capitalize(String name) {
520: if (name == null || name.length() == 0) {
521: return name;
522: }
523: char chars[] = name.toCharArray();
524: chars[0] = Character.toUpperCase(chars[0]);
525: return new String(chars);
526: }
527:
528: public static String unCapitalize(String name) {
529: if (name == null || name.length() == 0) {
530: return name;
531: }
532: char chars[] = name.toCharArray();
533: chars[0] = Character.toLowerCase(chars[0]);
534: return new String(chars);
535: }
536:
537: // -------------------- Class path tools --------------------
538:
539: /** Add all the jar files in a dir to the classpath,
540: * represented as a Vector of URLs.
541: */
542: public static void addToClassPath(Vector cpV, String dir) {
543: try {
544: String cpComp[] = getFilesByExt(dir, ".jar");
545: if (cpComp != null) {
546: int jarCount = cpComp.length;
547: for (int i = 0; i < jarCount; i++) {
548: URL url = getURL(dir, cpComp[i]);
549: if (url != null)
550: cpV.addElement(url);
551: }
552: }
553: } catch (Exception ex) {
554: ex.printStackTrace();
555: }
556: }
557:
558: public static void addToolsJar(Vector v) {
559: try {
560: // Add tools.jar in any case
561: File f = new File(System.getProperty("java.home")
562: + "/../lib/tools.jar");
563:
564: if (!f.exists()) {
565: // On some systems java.home gets set to the root of jdk.
566: // That's a bug, but we can work around and be nice.
567: f = new File(System.getProperty("java.home")
568: + "/lib/tools.jar");
569: if (f.exists()) {
570: System.out
571: .println("Detected strange java.home value "
572: + System.getProperty("java.home")
573: + ", it should point to jre");
574: }
575: }
576: URL url = new URL("file", "", f.getAbsolutePath());
577:
578: v.addElement(url);
579: } catch (MalformedURLException ex) {
580: ex.printStackTrace();
581: }
582: }
583:
584: /** Return all files with a given extension in a dir
585: */
586: public static String[] getFilesByExt(String ld, String ext) {
587: File dir = new File(ld);
588: String[] names = null;
589: final String lext = ext;
590: if (dir.isDirectory()) {
591: names = dir.list(new FilenameFilter() {
592: public boolean accept(File d, String name) {
593: if (name.endsWith(lext)) {
594: return true;
595: }
596: return false;
597: }
598: });
599: }
600: return names;
601: }
602:
603: /** Construct a file url from a file, using a base dir
604: */
605: public static URL getURL(String base, String file) {
606: try {
607: File baseF = new File(base);
608: File f = new File(baseF, file);
609: String path = f.getCanonicalPath();
610: if (f.isDirectory()) {
611: path += "/";
612: }
613: if (!f.exists())
614: return null;
615: return new URL("file", "", path);
616: } catch (Exception ex) {
617: ex.printStackTrace();
618: return null;
619: }
620: }
621:
622: /**
623: * add elements from the classpath <i>cp</i> to a Vector
624: * <i>jars</i> as file URLs (We use Vector for JDK 1.1 compat).
625: *
626: * @param jars A vector of URLs
627: * @param cp a String classpath of directory or jar file
628: * elements separated by path.separator delimiters.
629: */
630: public static void addJarsFromClassPath(Vector jars, String cp)
631: throws IOException, MalformedURLException {
632: String sep = System.getProperty("path.separator");
633: String token;
634: StringTokenizer st;
635: if (cp != null) {
636: st = new StringTokenizer(cp, sep);
637: while (st.hasMoreTokens()) {
638: File f = new File(st.nextToken());
639: String path = f.getCanonicalPath();
640: if (f.isDirectory()) {
641: path += "/";
642: }
643: URL url = new URL("file", "", path);
644: if (!jars.contains(url)) {
645: jars.addElement(url);
646: }
647: }
648: }
649: }
650:
651: /** Return a URL[] that can be used to construct a class loader
652: */
653: public static URL[] getClassPath(Vector v) {
654: URL[] urls = new URL[v.size()];
655: for (int i = 0; i < v.size(); i++) {
656: urls[i] = (URL) v.elementAt(i);
657: }
658: return urls;
659: }
660:
661: /** Construct a URL classpath from files in a directory,
662: * a cpath property, and tools.jar.
663: */
664: public static URL[] getClassPath(String dir, String cpath,
665: String cpathProp, boolean addTools) throws IOException,
666: MalformedURLException {
667: Vector jarsV = new Vector();
668: if (dir != null) {
669: // Add dir/classes first, if it exists
670: URL url = getURL(dir, "classes");
671: if (url != null)
672: jarsV.addElement(url);
673: addToClassPath(jarsV, dir);
674: }
675:
676: if (cpath != null)
677: addJarsFromClassPath(jarsV, cpath);
678:
679: if (cpathProp != null) {
680: String cpath1 = System.getProperty(cpathProp);
681: addJarsFromClassPath(jarsV, cpath1);
682: }
683:
684: if (addTools)
685: addToolsJar(jarsV);
686:
687: return getClassPath(jarsV);
688: }
689:
690: // -------------------- Mapping command line params to setters
691:
692: public static boolean processArgs(Object proxy, String args[])
693: throws Exception {
694: String args0[] = null;
695: if (null != findMethod(proxy.getClass(), "getOptions1",
696: new Class[] {})) {
697: args0 = (String[]) callMethod0(proxy, "getOptions1");
698: }
699:
700: if (args0 == null) {
701: //args0=findVoidSetters(proxy.getClass());
702: args0 = findBooleanSetters(proxy.getClass());
703: }
704: Hashtable h = null;
705: if (null != findMethod(proxy.getClass(), "getOptionAliases",
706: new Class[] {})) {
707: h = (Hashtable) callMethod0(proxy, "getOptionAliases");
708: }
709: return processArgs(proxy, args, args0, null, h);
710: }
711:
712: public static boolean processArgs(Object proxy, String args[],
713: String args0[], String args1[], Hashtable aliases)
714: throws Exception {
715: for (int i = 0; i < args.length; i++) {
716: String arg = args[i];
717: if (arg.startsWith("-"))
718: arg = arg.substring(1);
719: if (aliases != null && aliases.get(arg) != null)
720: arg = (String) aliases.get(arg);
721:
722: if (args0 != null) {
723: boolean set = false;
724: for (int j = 0; j < args0.length; j++) {
725: if (args0[j].equalsIgnoreCase(arg)) {
726: setProperty(proxy, args0[j], "true");
727: set = true;
728: break;
729: }
730: }
731: if (set)
732: continue;
733: }
734: if (args1 != null) {
735: for (int j = 0; j < args1.length; j++) {
736: if (args1[j].equalsIgnoreCase(arg)) {
737: i++;
738: if (i >= args.length)
739: return false;
740: setProperty(proxy, arg, args[i]);
741: break;
742: }
743: }
744: } else {
745: // if args1 is not specified,assume all other options have param
746: i++;
747: if (i >= args.length)
748: return false;
749: setProperty(proxy, arg, args[i]);
750: }
751:
752: }
753: return true;
754: }
755:
756: // -------------------- other utils --------------------
757: public static String[] findVoidSetters(Class c) {
758: Method m[] = findMethods(c);
759: if (m == null)
760: return null;
761: Vector v = new Vector();
762: for (int i = 0; i < m.length; i++) {
763: if (m[i].getName().startsWith("set")
764: && m[i].getParameterTypes().length == 0) {
765: String arg = m[i].getName().substring(3);
766: v.addElement(unCapitalize(arg));
767: }
768: }
769: String s[] = new String[v.size()];
770: for (int i = 0; i < s.length; i++) {
771: s[i] = (String) v.elementAt(i);
772: }
773: return s;
774: }
775:
776: public static String[] findBooleanSetters(Class c) {
777: Method m[] = findMethods(c);
778: if (m == null)
779: return null;
780: Vector v = new Vector();
781: for (int i = 0; i < m.length; i++) {
782: if (m[i].getName().startsWith("set")
783: && m[i].getParameterTypes().length == 1
784: && "boolean".equalsIgnoreCase(m[i]
785: .getParameterTypes()[0].getName())) {
786: String arg = m[i].getName().substring(3);
787: v.addElement(unCapitalize(arg));
788: }
789: }
790: String s[] = new String[v.size()];
791: for (int i = 0; i < s.length; i++) {
792: s[i] = (String) v.elementAt(i);
793: }
794: return s;
795: }
796:
797: static Hashtable objectMethods = new Hashtable();
798:
799: public static void clear() {
800: objectMethods.clear();
801: }
802:
803: public static Method[] findMethods(Class c) {
804: Method methods[] = (Method[]) objectMethods.get(c);
805: if (methods != null)
806: return methods;
807:
808: methods = c.getMethods();
809: objectMethods.put(c, methods);
810: return methods;
811: }
812:
813: public static Method findMethod(Class c, String name,
814: Class params[]) {
815: Method methods[] = findMethods(c);
816: if (methods == null)
817: return null;
818: for (int i = 0; i < methods.length; i++) {
819: if (methods[i].getName().equals(name)) {
820: Class methodParams[] = methods[i].getParameterTypes();
821: if (methodParams == null)
822: if (params == null || params.length == 0)
823: return methods[i];
824: if (params == null)
825: if (methodParams == null
826: || methodParams.length == 0)
827: return methods[i];
828: if (params.length != methodParams.length)
829: continue;
830: boolean found = true;
831: for (int j = 0; j < params.length; j++) {
832: if (params[j] != methodParams[j]) {
833: found = false;
834: break;
835: }
836: }
837: if (found)
838: return methods[i];
839: }
840: }
841: return null;
842: }
843:
844: /** Test if the object implements a particular
845: * method
846: */
847: public static boolean hasHook(Object obj, String methodN) {
848: try {
849: Method myMethods[] = findMethods(obj.getClass());
850: for (int i = 0; i < myMethods.length; i++) {
851: if (methodN.equals(myMethods[i].getName())) {
852: // check if it's overriden
853: Class declaring = myMethods[i].getDeclaringClass();
854: Class parentOfDeclaring = declaring.getSuperclass();
855: // this works only if the base class doesn't extend
856: // another class.
857:
858: // if the method is declared in a top level class
859: // like BaseInterceptor parent is Object, otherwise
860: // parent is BaseInterceptor or an intermediate class
861: if (!"java.lang.Object".equals(parentOfDeclaring
862: .getName())) {
863: return true;
864: }
865: }
866: }
867: } catch (Exception ex) {
868: ex.printStackTrace();
869: }
870: return false;
871: }
872:
873: public static void callMain(Class c, String args[])
874: throws Exception {
875: Class p[] = new Class[1];
876: p[0] = args.getClass();
877: Method m = c.getMethod("main", p);
878: m.invoke(c, new Object[] { args });
879: }
880:
881: public static Object callMethod1(Object target, String methodN,
882: Object param1, String typeParam1, ClassLoader cl)
883: throws Exception {
884: if (target == null || param1 == null) {
885: d("Assert: Illegal params " + target + " " + param1);
886: }
887: if (dbg > 0)
888: d("callMethod1 " + target.getClass().getName() + " "
889: + param1.getClass().getName() + " " + typeParam1);
890:
891: Class params[] = new Class[1];
892: if (typeParam1 == null)
893: params[0] = param1.getClass();
894: else
895: params[0] = cl.loadClass(typeParam1);
896: Method m = findMethod(target.getClass(), methodN, params);
897: if (m == null)
898: throw new NoSuchMethodException(target.getClass().getName()
899: + " " + methodN);
900: return m.invoke(target, new Object[] { param1 });
901: }
902:
903: public static Object callMethod0(Object target, String methodN)
904: throws Exception {
905: if (target == null) {
906: d("Assert: Illegal params " + target);
907: return null;
908: }
909: if (dbg > 0)
910: d("callMethod0 " + target.getClass().getName() + "."
911: + methodN);
912:
913: Class params[] = new Class[0];
914: Method m = findMethod(target.getClass(), methodN, params);
915: if (m == null)
916: throw new NoSuchMethodException(target.getClass().getName()
917: + " " + methodN);
918: return m.invoke(target, emptyArray);
919: }
920:
921: static Object[] emptyArray = new Object[] {};
922:
923: public static Object callMethodN(Object target, String methodN,
924: Object params[], Class typeParams[]) throws Exception {
925: Method m = null;
926: m = findMethod(target.getClass(), methodN, typeParams);
927: if (m == null) {
928: d("Can't find method " + methodN + " in " + target
929: + " CLASS " + target.getClass());
930: return null;
931: }
932: Object o = m.invoke(target, params);
933:
934: if (dbg > 0) {
935: // debug
936: StringBuffer sb = new StringBuffer();
937: sb.append("" + target.getClass().getName() + "." + methodN
938: + "( ");
939: for (int i = 0; i < params.length; i++) {
940: if (i > 0)
941: sb.append(", ");
942: sb.append(params[i]);
943: }
944: sb.append(")");
945: d(sb.toString());
946: }
947: return o;
948: }
949:
950: // -------------------- Get property --------------------
951: // This provides a layer of abstraction
952:
953: public static interface PropertySource {
954:
955: public String getProperty(String key);
956:
957: }
958:
959: public static interface AttributeHolder {
960:
961: public void setAttribute(String key, Object o);
962:
963: }
964:
965: // debug --------------------
966: static final int dbg = 0;
967:
968: static void d(String s) {
969: System.out.println("IntrospectionUtils: " + s);
970: }
971: }
|