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