0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017:
0018: package org.apache.tomcat.util;
0019:
0020: import java.io.File;
0021: import java.io.FilenameFilter;
0022: import java.io.IOException;
0023: import java.lang.reflect.InvocationTargetException;
0024: import java.lang.reflect.Method;
0025: import java.net.InetAddress;
0026: import java.net.MalformedURLException;
0027: import java.net.URL;
0028: import java.net.UnknownHostException;
0029: import java.util.Hashtable;
0030: import java.util.StringTokenizer;
0031: import java.util.Vector;
0032:
0033: // Depends: JDK1.1
0034:
0035: /**
0036: * Utils for introspection and reflection
0037: */
0038: public final class IntrospectionUtils {
0039:
0040: private static org.apache.juli.logging.Log log = org.apache.juli.logging.LogFactory
0041: .getLog(IntrospectionUtils.class);
0042:
0043: /**
0044: * Call execute() - any ant-like task should work
0045: */
0046: public static void execute(Object proxy, String method)
0047: throws Exception {
0048: Method executeM = null;
0049: Class c = proxy.getClass();
0050: Class params[] = new Class[0];
0051: // params[0]=args.getClass();
0052: executeM = findMethod(c, method, params);
0053: if (executeM == null) {
0054: throw new RuntimeException("No execute in "
0055: + proxy.getClass());
0056: }
0057: executeM.invoke(proxy, (Object[]) null);//new Object[] { args });
0058: }
0059:
0060: /**
0061: * Call void setAttribute( String ,Object )
0062: */
0063: public static void setAttribute(Object proxy, String n, Object v)
0064: throws Exception {
0065: if (proxy instanceof AttributeHolder) {
0066: ((AttributeHolder) proxy).setAttribute(n, v);
0067: return;
0068: }
0069:
0070: Method executeM = null;
0071: Class c = proxy.getClass();
0072: Class params[] = new Class[2];
0073: params[0] = String.class;
0074: params[1] = Object.class;
0075: executeM = findMethod(c, "setAttribute", params);
0076: if (executeM == null) {
0077: if (log.isDebugEnabled())
0078: log.debug("No setAttribute in " + proxy.getClass());
0079: return;
0080: }
0081: if (false)
0082: if (log.isDebugEnabled())
0083: log.debug("Setting " + n + "=" + v + " in " + proxy);
0084: executeM.invoke(proxy, new Object[] { n, v });
0085: return;
0086: }
0087:
0088: /**
0089: * Call void getAttribute( String )
0090: */
0091: public static Object getAttribute(Object proxy, String n)
0092: throws Exception {
0093: Method executeM = null;
0094: Class c = proxy.getClass();
0095: Class params[] = new Class[1];
0096: params[0] = String.class;
0097: executeM = findMethod(c, "getAttribute", params);
0098: if (executeM == null) {
0099: if (log.isDebugEnabled())
0100: log.debug("No getAttribute in " + proxy.getClass());
0101: return null;
0102: }
0103: return executeM.invoke(proxy, new Object[] { n });
0104: }
0105:
0106: /**
0107: * Construct a URLClassLoader. Will compile and work in JDK1.1 too.
0108: */
0109: public static ClassLoader getURLClassLoader(URL urls[],
0110: ClassLoader parent) {
0111: try {
0112: Class urlCL = Class.forName("java.net.URLClassLoader");
0113: Class paramT[] = new Class[2];
0114: paramT[0] = urls.getClass();
0115: paramT[1] = ClassLoader.class;
0116: Method m = findMethod(urlCL, "newInstance", paramT);
0117: if (m == null)
0118: return null;
0119:
0120: ClassLoader cl = (ClassLoader) m.invoke(urlCL,
0121: new Object[] { urls, parent });
0122: return cl;
0123: } catch (ClassNotFoundException ex) {
0124: // jdk1.1
0125: return null;
0126: } catch (Exception ex) {
0127: ex.printStackTrace();
0128: return null;
0129: }
0130: }
0131:
0132: public static String guessInstall(String installSysProp,
0133: String homeSysProp, String jarName) {
0134: return guessInstall(installSysProp, homeSysProp, jarName, null);
0135: }
0136:
0137: /**
0138: * Guess a product install/home by analyzing the class path. It works for
0139: * product using the pattern: lib/executable.jar or if executable.jar is
0140: * included in classpath by a shell script. ( java -jar also works )
0141: *
0142: * Insures both "install" and "home" System properties are set. If either or
0143: * both System properties are unset, "install" and "home" will be set to the
0144: * same value. This value will be the other System property that is set, or
0145: * the guessed value if neither is set.
0146: */
0147: public static String guessInstall(String installSysProp,
0148: String homeSysProp, String jarName, String classFile) {
0149: String install = null;
0150: String home = null;
0151:
0152: if (installSysProp != null)
0153: install = System.getProperty(installSysProp);
0154:
0155: if (homeSysProp != null)
0156: home = System.getProperty(homeSysProp);
0157:
0158: if (install != null) {
0159: if (home == null)
0160: System.getProperties().put(homeSysProp, install);
0161: return install;
0162: }
0163:
0164: // Find the directory where jarName.jar is located
0165:
0166: String cpath = System.getProperty("java.class.path");
0167: String pathSep = System.getProperty("path.separator");
0168: StringTokenizer st = new StringTokenizer(cpath, pathSep);
0169: while (st.hasMoreTokens()) {
0170: String path = st.nextToken();
0171: // log( "path " + path );
0172: if (path.endsWith(jarName)) {
0173: home = path.substring(0, path.length()
0174: - jarName.length());
0175: try {
0176: if ("".equals(home)) {
0177: home = new File("./").getCanonicalPath();
0178: } else if (home.endsWith(File.separator)) {
0179: home = home.substring(0, home.length() - 1);
0180: }
0181: File f = new File(home);
0182: String parentDir = f.getParent();
0183: if (parentDir == null)
0184: parentDir = home; // unix style
0185: File f1 = new File(parentDir);
0186: install = f1.getCanonicalPath();
0187: if (installSysProp != null)
0188: System.getProperties().put(installSysProp,
0189: install);
0190: if (home == null && homeSysProp != null)
0191: System.getProperties()
0192: .put(homeSysProp, install);
0193: return install;
0194: } catch (Exception ex) {
0195: ex.printStackTrace();
0196: }
0197: } else {
0198: String fname = path + (path.endsWith("/") ? "" : "/")
0199: + classFile;
0200: if (new File(fname).exists()) {
0201: try {
0202: File f = new File(path);
0203: String parentDir = f.getParent();
0204: if (parentDir == null)
0205: parentDir = path; // unix style
0206: File f1 = new File(parentDir);
0207: install = f1.getCanonicalPath();
0208: if (installSysProp != null)
0209: System.getProperties().put(installSysProp,
0210: install);
0211: if (home == null && homeSysProp != null)
0212: System.getProperties().put(homeSysProp,
0213: install);
0214: return install;
0215: } catch (Exception ex) {
0216: ex.printStackTrace();
0217: }
0218: }
0219: }
0220: }
0221:
0222: // if install directory can't be found, use home as the default
0223: if (home != null) {
0224: System.getProperties().put(installSysProp, home);
0225: return home;
0226: }
0227:
0228: return null;
0229: }
0230:
0231: /**
0232: * Debug method, display the classpath
0233: */
0234: public static void displayClassPath(String msg, URL[] cp) {
0235: if (log.isDebugEnabled()) {
0236: log.debug(msg);
0237: for (int i = 0; i < cp.length; i++) {
0238: log.debug(cp[i].getFile());
0239: }
0240: }
0241: }
0242:
0243: public static String PATH_SEPARATOR = System
0244: .getProperty("path.separator");
0245:
0246: /**
0247: * Adds classpath entries from a vector of URL's to the "tc_path_add" System
0248: * property. This System property lists the classpath entries common to web
0249: * applications. This System property is currently used by Jasper when its
0250: * JSP servlet compiles the Java file for a JSP.
0251: */
0252: public static String classPathAdd(URL urls[], String cp) {
0253: if (urls == null)
0254: return cp;
0255:
0256: for (int i = 0; i < urls.length; i++) {
0257: if (cp != null)
0258: cp += PATH_SEPARATOR + urls[i].getFile();
0259: else
0260: cp = urls[i].getFile();
0261: }
0262: return cp;
0263: }
0264:
0265: /**
0266: * Find a method with the right name If found, call the method ( if param is
0267: * int or boolean we'll convert value to the right type before) - that means
0268: * you can have setDebug(1).
0269: */
0270: public static void setProperty(Object o, String name, String value) {
0271: if (dbg > 1)
0272: d("setProperty(" + o.getClass() + " " + name + "=" + value
0273: + ")");
0274:
0275: String setter = "set" + capitalize(name);
0276:
0277: try {
0278: Method methods[] = findMethods(o.getClass());
0279: Method setPropertyMethod = null;
0280:
0281: // First, the ideal case - a setFoo( String ) method
0282: for (int i = 0; i < methods.length; i++) {
0283: Class paramT[] = methods[i].getParameterTypes();
0284: if (setter.equals(methods[i].getName())
0285: && paramT.length == 1
0286: && "java.lang.String".equals(paramT[0]
0287: .getName())) {
0288:
0289: methods[i].invoke(o, new Object[] { value });
0290: return;
0291: }
0292: }
0293:
0294: // Try a setFoo ( int ) or ( boolean )
0295: for (int i = 0; i < methods.length; i++) {
0296: boolean ok = true;
0297: if (setter.equals(methods[i].getName())
0298: && methods[i].getParameterTypes().length == 1) {
0299:
0300: // match - find the type and invoke it
0301: Class paramType = methods[i].getParameterTypes()[0];
0302: Object params[] = new Object[1];
0303:
0304: // Try a setFoo ( int )
0305: if ("java.lang.Integer".equals(paramType.getName())
0306: || "int".equals(paramType.getName())) {
0307: try {
0308: params[0] = new Integer(value);
0309: } catch (NumberFormatException ex) {
0310: ok = false;
0311: }
0312: // Try a setFoo ( long )
0313: } else if ("java.lang.Long".equals(paramType
0314: .getName())
0315: || "long".equals(paramType.getName())) {
0316: try {
0317: params[0] = new Long(value);
0318: } catch (NumberFormatException ex) {
0319: ok = false;
0320: }
0321:
0322: // Try a setFoo ( boolean )
0323: } else if ("java.lang.Boolean".equals(paramType
0324: .getName())
0325: || "boolean".equals(paramType.getName())) {
0326: params[0] = new Boolean(value);
0327:
0328: // Try a setFoo ( InetAddress )
0329: } else if ("java.net.InetAddress".equals(paramType
0330: .getName())) {
0331: try {
0332: params[0] = InetAddress.getByName(value);
0333: } catch (UnknownHostException exc) {
0334: d("Unable to resolve host name:" + value);
0335: ok = false;
0336: }
0337:
0338: // Unknown type
0339: } else {
0340: d("Unknown type " + paramType.getName());
0341: }
0342:
0343: if (ok) {
0344: methods[i].invoke(o, params);
0345: return;
0346: }
0347: }
0348:
0349: // save "setProperty" for later
0350: if ("setProperty".equals(methods[i].getName())) {
0351: setPropertyMethod = methods[i];
0352: }
0353: }
0354:
0355: // Ok, no setXXX found, try a setProperty("name", "value")
0356: if (setPropertyMethod != null) {
0357: Object params[] = new Object[2];
0358: params[0] = name;
0359: params[1] = value;
0360: setPropertyMethod.invoke(o, params);
0361: }
0362:
0363: } catch (IllegalArgumentException ex2) {
0364: log.warn("IAE " + o + " " + name + " " + value, ex2);
0365: } catch (SecurityException ex1) {
0366: if (dbg > 0)
0367: d("SecurityException for " + o.getClass() + " " + name
0368: + "=" + value + ")");
0369: if (dbg > 1)
0370: ex1.printStackTrace();
0371: } catch (IllegalAccessException iae) {
0372: if (dbg > 0)
0373: d("IllegalAccessException for " + o.getClass() + " "
0374: + name + "=" + value + ")");
0375: if (dbg > 1)
0376: iae.printStackTrace();
0377: } catch (InvocationTargetException ie) {
0378: if (dbg > 0)
0379: d("InvocationTargetException for " + o.getClass() + " "
0380: + name + "=" + value + ")");
0381: if (dbg > 1)
0382: ie.printStackTrace();
0383: }
0384: }
0385:
0386: public static Object getProperty(Object o, String name) {
0387: String getter = "get" + capitalize(name);
0388: String isGetter = "is" + capitalize(name);
0389:
0390: try {
0391: Method methods[] = findMethods(o.getClass());
0392: Method getPropertyMethod = null;
0393:
0394: // First, the ideal case - a getFoo() method
0395: for (int i = 0; i < methods.length; i++) {
0396: Class paramT[] = methods[i].getParameterTypes();
0397: if (getter.equals(methods[i].getName())
0398: && paramT.length == 0) {
0399: return methods[i].invoke(o, (Object[]) null);
0400: }
0401: if (isGetter.equals(methods[i].getName())
0402: && paramT.length == 0) {
0403: return methods[i].invoke(o, (Object[]) null);
0404: }
0405:
0406: if ("getProperty".equals(methods[i].getName())) {
0407: getPropertyMethod = methods[i];
0408: }
0409: }
0410:
0411: // Ok, no setXXX found, try a getProperty("name")
0412: if (getPropertyMethod != null) {
0413: Object params[] = new Object[1];
0414: params[0] = name;
0415: return getPropertyMethod.invoke(o, params);
0416: }
0417:
0418: } catch (IllegalArgumentException ex2) {
0419: log.warn("IAE " + o + " " + name, ex2);
0420: } catch (SecurityException ex1) {
0421: if (dbg > 0)
0422: d("SecurityException for " + o.getClass() + " " + name
0423: + ")");
0424: if (dbg > 1)
0425: ex1.printStackTrace();
0426: } catch (IllegalAccessException iae) {
0427: if (dbg > 0)
0428: d("IllegalAccessException for " + o.getClass() + " "
0429: + name + ")");
0430: if (dbg > 1)
0431: iae.printStackTrace();
0432: } catch (InvocationTargetException ie) {
0433: if (dbg > 0)
0434: d("InvocationTargetException for " + o.getClass() + " "
0435: + name + ")");
0436: if (dbg > 1)
0437: ie.printStackTrace();
0438: }
0439: return null;
0440: }
0441:
0442: /**
0443: */
0444: public static void setProperty(Object o, String name) {
0445: String setter = "set" + capitalize(name);
0446: try {
0447: Method methods[] = findMethods(o.getClass());
0448: Method setPropertyMethod = null;
0449: // find setFoo() method
0450: for (int i = 0; i < methods.length; i++) {
0451: Class paramT[] = methods[i].getParameterTypes();
0452: if (setter.equals(methods[i].getName())
0453: && paramT.length == 0) {
0454: methods[i].invoke(o, new Object[] {});
0455: return;
0456: }
0457: }
0458: } catch (Exception ex1) {
0459: if (dbg > 0)
0460: d("Exception for " + o.getClass() + " " + name);
0461: if (dbg > 1)
0462: ex1.printStackTrace();
0463: }
0464: }
0465:
0466: /**
0467: * Replace ${NAME} with the property value
0468: *
0469: * @deprecated Use the explicit method
0470: */
0471: public static String replaceProperties(String value, Object getter) {
0472: if (getter instanceof Hashtable)
0473: return replaceProperties(value, (Hashtable) getter, null);
0474:
0475: if (getter instanceof PropertySource) {
0476: PropertySource src[] = new PropertySource[] { (PropertySource) getter };
0477: return replaceProperties(value, null, src);
0478: }
0479: return value;
0480: }
0481:
0482: /**
0483: * Replace ${NAME} with the property value
0484: */
0485: public static String replaceProperties(String value,
0486: Hashtable staticProp, PropertySource dynamicProp[]) {
0487: StringBuffer sb = new StringBuffer();
0488: int prev = 0;
0489: // assert value!=nil
0490: int pos;
0491: while ((pos = value.indexOf("$", prev)) >= 0) {
0492: if (pos > 0) {
0493: sb.append(value.substring(prev, pos));
0494: }
0495: if (pos == (value.length() - 1)) {
0496: sb.append('$');
0497: prev = pos + 1;
0498: } else if (value.charAt(pos + 1) != '{') {
0499: sb.append('$');
0500: prev = pos + 1; // XXX
0501: } else {
0502: int endName = value.indexOf('}', pos);
0503: if (endName < 0) {
0504: sb.append(value.substring(pos));
0505: prev = value.length();
0506: continue;
0507: }
0508: String n = value.substring(pos + 2, endName);
0509: String v = null;
0510: if (staticProp != null) {
0511: v = (String) ((Hashtable) staticProp).get(n);
0512: }
0513: if (v == null && dynamicProp != null) {
0514: for (int i = 0; i < dynamicProp.length; i++) {
0515: v = dynamicProp[i].getProperty(n);
0516: if (v != null) {
0517: break;
0518: }
0519: }
0520: }
0521: if (v == null)
0522: v = "${" + n + "}";
0523:
0524: sb.append(v);
0525: prev = endName + 1;
0526: }
0527: }
0528: if (prev < value.length())
0529: sb.append(value.substring(prev));
0530: return sb.toString();
0531: }
0532:
0533: /**
0534: * Reverse of Introspector.decapitalize
0535: */
0536: public static String capitalize(String name) {
0537: if (name == null || name.length() == 0) {
0538: return name;
0539: }
0540: char chars[] = name.toCharArray();
0541: chars[0] = Character.toUpperCase(chars[0]);
0542: return new String(chars);
0543: }
0544:
0545: public static String unCapitalize(String name) {
0546: if (name == null || name.length() == 0) {
0547: return name;
0548: }
0549: char chars[] = name.toCharArray();
0550: chars[0] = Character.toLowerCase(chars[0]);
0551: return new String(chars);
0552: }
0553:
0554: // -------------------- Class path tools --------------------
0555:
0556: /**
0557: * Add all the jar files in a dir to the classpath, represented as a Vector
0558: * of URLs.
0559: */
0560: public static void addToClassPath(Vector cpV, String dir) {
0561: try {
0562: String cpComp[] = getFilesByExt(dir, ".jar");
0563: if (cpComp != null) {
0564: int jarCount = cpComp.length;
0565: for (int i = 0; i < jarCount; i++) {
0566: URL url = getURL(dir, cpComp[i]);
0567: if (url != null)
0568: cpV.addElement(url);
0569: }
0570: }
0571: } catch (Exception ex) {
0572: ex.printStackTrace();
0573: }
0574: }
0575:
0576: public static void addToolsJar(Vector v) {
0577: try {
0578: // Add tools.jar in any case
0579: File f = new File(System.getProperty("java.home")
0580: + "/../lib/tools.jar");
0581:
0582: if (!f.exists()) {
0583: // On some systems java.home gets set to the root of jdk.
0584: // That's a bug, but we can work around and be nice.
0585: f = new File(System.getProperty("java.home")
0586: + "/lib/tools.jar");
0587: if (f.exists()) {
0588: if (log.isDebugEnabled())
0589: log.debug("Detected strange java.home value "
0590: + System.getProperty("java.home")
0591: + ", it should point to jre");
0592: }
0593: }
0594: URL url = new URL("file", "", f.getAbsolutePath());
0595:
0596: v.addElement(url);
0597: } catch (MalformedURLException ex) {
0598: ex.printStackTrace();
0599: }
0600: }
0601:
0602: /**
0603: * Return all files with a given extension in a dir
0604: */
0605: public static String[] getFilesByExt(String ld, String ext) {
0606: File dir = new File(ld);
0607: String[] names = null;
0608: final String lext = ext;
0609: if (dir.isDirectory()) {
0610: names = dir.list(new FilenameFilter() {
0611: public boolean accept(File d, String name) {
0612: if (name.endsWith(lext)) {
0613: return true;
0614: }
0615: return false;
0616: }
0617: });
0618: }
0619: return names;
0620: }
0621:
0622: /**
0623: * Construct a file url from a file, using a base dir
0624: */
0625: public static URL getURL(String base, String file) {
0626: try {
0627: File baseF = new File(base);
0628: File f = new File(baseF, file);
0629: String path = f.getCanonicalPath();
0630: if (f.isDirectory()) {
0631: path += "/";
0632: }
0633: if (!f.exists())
0634: return null;
0635: return new URL("file", "", path);
0636: } catch (Exception ex) {
0637: ex.printStackTrace();
0638: return null;
0639: }
0640: }
0641:
0642: /**
0643: * Add elements from the classpath <i>cp </i> to a Vector <i>jars </i> as
0644: * file URLs (We use Vector for JDK 1.1 compat).
0645: * <p>
0646: *
0647: * @param jars The jar list
0648: * @param cp a String classpath of directory or jar file elements
0649: * separated by path.separator delimiters.
0650: * @throws IOException If an I/O error occurs
0651: * @throws MalformedURLException Doh ;)
0652: */
0653: public static void addJarsFromClassPath(Vector jars, String cp)
0654: throws IOException, MalformedURLException {
0655: String sep = System.getProperty("path.separator");
0656: String token;
0657: StringTokenizer st;
0658: if (cp != null) {
0659: st = new StringTokenizer(cp, sep);
0660: while (st.hasMoreTokens()) {
0661: File f = new File(st.nextToken());
0662: String path = f.getCanonicalPath();
0663: if (f.isDirectory()) {
0664: path += "/";
0665: }
0666: URL url = new URL("file", "", path);
0667: if (!jars.contains(url)) {
0668: jars.addElement(url);
0669: }
0670: }
0671: }
0672: }
0673:
0674: /**
0675: * Return a URL[] that can be used to construct a class loader
0676: */
0677: public static URL[] getClassPath(Vector v) {
0678: URL[] urls = new URL[v.size()];
0679: for (int i = 0; i < v.size(); i++) {
0680: urls[i] = (URL) v.elementAt(i);
0681: }
0682: return urls;
0683: }
0684:
0685: /**
0686: * Construct a URL classpath from files in a directory, a cpath property,
0687: * and tools.jar.
0688: */
0689: public static URL[] getClassPath(String dir, String cpath,
0690: String cpathProp, boolean addTools) throws IOException,
0691: MalformedURLException {
0692: Vector jarsV = new Vector();
0693: if (dir != null) {
0694: // Add dir/classes first, if it exists
0695: URL url = getURL(dir, "classes");
0696: if (url != null)
0697: jarsV.addElement(url);
0698: addToClassPath(jarsV, dir);
0699: }
0700:
0701: if (cpath != null)
0702: addJarsFromClassPath(jarsV, cpath);
0703:
0704: if (cpathProp != null) {
0705: String cpath1 = System.getProperty(cpathProp);
0706: addJarsFromClassPath(jarsV, cpath1);
0707: }
0708:
0709: if (addTools)
0710: addToolsJar(jarsV);
0711:
0712: return getClassPath(jarsV);
0713: }
0714:
0715: // -------------------- Mapping command line params to setters
0716:
0717: public static boolean processArgs(Object proxy, String args[])
0718: throws Exception {
0719: String args0[] = null;
0720: if (null != findMethod(proxy.getClass(), "getOptions1",
0721: new Class[] {})) {
0722: args0 = (String[]) callMethod0(proxy, "getOptions1");
0723: }
0724:
0725: if (args0 == null) {
0726: //args0=findVoidSetters(proxy.getClass());
0727: args0 = findBooleanSetters(proxy.getClass());
0728: }
0729: Hashtable h = null;
0730: if (null != findMethod(proxy.getClass(), "getOptionAliases",
0731: new Class[] {})) {
0732: h = (Hashtable) callMethod0(proxy, "getOptionAliases");
0733: }
0734: return processArgs(proxy, args, args0, null, h);
0735: }
0736:
0737: public static boolean processArgs(Object proxy, String args[],
0738: String args0[], String args1[], Hashtable aliases)
0739: throws Exception {
0740: for (int i = 0; i < args.length; i++) {
0741: String arg = args[i];
0742: if (arg.startsWith("-"))
0743: arg = arg.substring(1);
0744: if (aliases != null && aliases.get(arg) != null)
0745: arg = (String) aliases.get(arg);
0746:
0747: if (args0 != null) {
0748: boolean set = false;
0749: for (int j = 0; j < args0.length; j++) {
0750: if (args0[j].equalsIgnoreCase(arg)) {
0751: setProperty(proxy, args0[j], "true");
0752: set = true;
0753: break;
0754: }
0755: }
0756: if (set)
0757: continue;
0758: }
0759: if (args1 != null) {
0760: for (int j = 0; j < args1.length; j++) {
0761: if (args1[j].equalsIgnoreCase(arg)) {
0762: i++;
0763: if (i >= args.length)
0764: return false;
0765: setProperty(proxy, arg, args[i]);
0766: break;
0767: }
0768: }
0769: } else {
0770: // if args1 is not specified,assume all other options have param
0771: i++;
0772: if (i >= args.length)
0773: return false;
0774: setProperty(proxy, arg, args[i]);
0775: }
0776:
0777: }
0778: return true;
0779: }
0780:
0781: // -------------------- other utils --------------------
0782: public static void clear() {
0783: objectMethods.clear();
0784: }
0785:
0786: public static String[] findVoidSetters(Class c) {
0787: Method m[] = findMethods(c);
0788: if (m == null)
0789: return null;
0790: Vector v = new Vector();
0791: for (int i = 0; i < m.length; i++) {
0792: if (m[i].getName().startsWith("set")
0793: && m[i].getParameterTypes().length == 0) {
0794: String arg = m[i].getName().substring(3);
0795: v.addElement(unCapitalize(arg));
0796: }
0797: }
0798: String s[] = new String[v.size()];
0799: for (int i = 0; i < s.length; i++) {
0800: s[i] = (String) v.elementAt(i);
0801: }
0802: return s;
0803: }
0804:
0805: public static String[] findBooleanSetters(Class c) {
0806: Method m[] = findMethods(c);
0807: if (m == null)
0808: return null;
0809: Vector v = new Vector();
0810: for (int i = 0; i < m.length; i++) {
0811: if (m[i].getName().startsWith("set")
0812: && m[i].getParameterTypes().length == 1
0813: && "boolean".equalsIgnoreCase(m[i]
0814: .getParameterTypes()[0].getName())) {
0815: String arg = m[i].getName().substring(3);
0816: v.addElement(unCapitalize(arg));
0817: }
0818: }
0819: String s[] = new String[v.size()];
0820: for (int i = 0; i < s.length; i++) {
0821: s[i] = (String) v.elementAt(i);
0822: }
0823: return s;
0824: }
0825:
0826: static Hashtable objectMethods = new Hashtable();
0827:
0828: public static Method[] findMethods(Class c) {
0829: Method methods[] = (Method[]) objectMethods.get(c);
0830: if (methods != null)
0831: return methods;
0832:
0833: methods = c.getMethods();
0834: objectMethods.put(c, methods);
0835: return methods;
0836: }
0837:
0838: public static Method findMethod(Class c, String name,
0839: Class params[]) {
0840: Method methods[] = findMethods(c);
0841: if (methods == null)
0842: return null;
0843: for (int i = 0; i < methods.length; i++) {
0844: if (methods[i].getName().equals(name)) {
0845: Class methodParams[] = methods[i].getParameterTypes();
0846: if (methodParams == null)
0847: if (params == null || params.length == 0)
0848: return methods[i];
0849: if (params == null)
0850: if (methodParams == null
0851: || methodParams.length == 0)
0852: return methods[i];
0853: if (params.length != methodParams.length)
0854: continue;
0855: boolean found = true;
0856: for (int j = 0; j < params.length; j++) {
0857: if (params[j] != methodParams[j]) {
0858: found = false;
0859: break;
0860: }
0861: }
0862: if (found)
0863: return methods[i];
0864: }
0865: }
0866: return null;
0867: }
0868:
0869: /** Test if the object implements a particular
0870: * method
0871: */
0872: public static boolean hasHook(Object obj, String methodN) {
0873: try {
0874: Method myMethods[] = findMethods(obj.getClass());
0875: for (int i = 0; i < myMethods.length; i++) {
0876: if (methodN.equals(myMethods[i].getName())) {
0877: // check if it's overriden
0878: Class declaring = myMethods[i].getDeclaringClass();
0879: Class parentOfDeclaring = declaring.getSuperclass();
0880: // this works only if the base class doesn't extend
0881: // another class.
0882:
0883: // if the method is declared in a top level class
0884: // like BaseInterceptor parent is Object, otherwise
0885: // parent is BaseInterceptor or an intermediate class
0886: if (!"java.lang.Object".equals(parentOfDeclaring
0887: .getName())) {
0888: return true;
0889: }
0890: }
0891: }
0892: } catch (Exception ex) {
0893: ex.printStackTrace();
0894: }
0895: return false;
0896: }
0897:
0898: public static void callMain(Class c, String args[])
0899: throws Exception {
0900: Class p[] = new Class[1];
0901: p[0] = args.getClass();
0902: Method m = c.getMethod("main", p);
0903: m.invoke(c, new Object[] { args });
0904: }
0905:
0906: public static Object callMethod1(Object target, String methodN,
0907: Object param1, String typeParam1, ClassLoader cl)
0908: throws Exception {
0909: if (target == null || param1 == null) {
0910: d("Assert: Illegal params " + target + " " + param1);
0911: }
0912: if (dbg > 0)
0913: d("callMethod1 " + target.getClass().getName() + " "
0914: + param1.getClass().getName() + " " + typeParam1);
0915:
0916: Class params[] = new Class[1];
0917: if (typeParam1 == null)
0918: params[0] = param1.getClass();
0919: else
0920: params[0] = cl.loadClass(typeParam1);
0921: Method m = findMethod(target.getClass(), methodN, params);
0922: if (m == null)
0923: throw new NoSuchMethodException(target.getClass().getName()
0924: + " " + methodN);
0925: return m.invoke(target, new Object[] { param1 });
0926: }
0927:
0928: public static Object callMethod0(Object target, String methodN)
0929: throws Exception {
0930: if (target == null) {
0931: d("Assert: Illegal params " + target);
0932: return null;
0933: }
0934: if (dbg > 0)
0935: d("callMethod0 " + target.getClass().getName() + "."
0936: + methodN);
0937:
0938: Class params[] = new Class[0];
0939: Method m = findMethod(target.getClass(), methodN, params);
0940: if (m == null)
0941: throw new NoSuchMethodException(target.getClass().getName()
0942: + " " + methodN);
0943: return m.invoke(target, emptyArray);
0944: }
0945:
0946: static Object[] emptyArray = new Object[] {};
0947:
0948: public static Object callMethodN(Object target, String methodN,
0949: Object params[], Class typeParams[]) throws Exception {
0950: Method m = null;
0951: m = findMethod(target.getClass(), methodN, typeParams);
0952: if (m == null) {
0953: d("Can't find method " + methodN + " in " + target
0954: + " CLASS " + target.getClass());
0955: return null;
0956: }
0957: Object o = m.invoke(target, params);
0958:
0959: if (dbg > 0) {
0960: // debug
0961: StringBuffer sb = new StringBuffer();
0962: sb.append("" + target.getClass().getName() + "." + methodN
0963: + "( ");
0964: for (int i = 0; i < params.length; i++) {
0965: if (i > 0)
0966: sb.append(", ");
0967: sb.append(params[i]);
0968: }
0969: sb.append(")");
0970: d(sb.toString());
0971: }
0972: return o;
0973: }
0974:
0975: public static Object convert(String object, Class paramType) {
0976: Object result = null;
0977: if ("java.lang.String".equals(paramType.getName())) {
0978: result = object;
0979: } else if ("java.lang.Integer".equals(paramType.getName())
0980: || "int".equals(paramType.getName())) {
0981: try {
0982: result = new Integer(object);
0983: } catch (NumberFormatException ex) {
0984: }
0985: // Try a setFoo ( boolean )
0986: } else if ("java.lang.Boolean".equals(paramType.getName())
0987: || "boolean".equals(paramType.getName())) {
0988: result = new Boolean(object);
0989:
0990: // Try a setFoo ( InetAddress )
0991: } else if ("java.net.InetAddress".equals(paramType.getName())) {
0992: try {
0993: result = InetAddress.getByName(object);
0994: } catch (UnknownHostException exc) {
0995: d("Unable to resolve host name:" + object);
0996: }
0997:
0998: // Unknown type
0999: } else {
1000: d("Unknown type " + paramType.getName());
1001: }
1002: if (result == null) {
1003: throw new IllegalArgumentException(
1004: "Can't convert argument: " + object);
1005: }
1006: return result;
1007: }
1008:
1009: // -------------------- Get property --------------------
1010: // This provides a layer of abstraction
1011:
1012: public static interface PropertySource {
1013:
1014: public String getProperty(String key);
1015:
1016: }
1017:
1018: public static interface AttributeHolder {
1019:
1020: public void setAttribute(String key, Object o);
1021:
1022: }
1023:
1024: // debug --------------------
1025: static final int dbg = 0;
1026:
1027: static void d(String s) {
1028: if (log.isDebugEnabled())
1029: log.debug("IntrospectionUtils: " + s);
1030: }
1031: }
|