blob: 83ceaac238aaa201a892313ed8ea20338cadd43a [file] [log] [blame]
/* *******************************************************************
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Xerox/PARC initial implementation
* ******************************************************************/
package org.aspectj.util;
import java.io.File;
import java.lang.reflect.*;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
//import java.util.StringTokenizer;
public class Reflection {
public static final Class<?>[] MAIN_PARM_TYPES = new Class[] {String[].class};
private Reflection() {
}
public static Object invokestaticN(Class<?> class_, String name, Object[] args) {
return invokeN(class_, name, null, args);
}
public static Object invoke(Class<?> class_, Object target, String name, Object arg1, Object arg2) {
return invokeN(class_, name, target, new Object[] { arg1, arg2 });
}
public static Object invoke(Class<?> class_, Object target, String name, Object arg1, Object arg2, Object arg3) {
return invokeN(class_, name, target, new Object[] { arg1, arg2, arg3 });
}
public static Object invokeN(Class<?> class_, String name, Object target, Object[] args) {
Method meth = getMatchingMethod(class_, name, args);
try {
return meth.invoke(target, args);
} catch (IllegalAccessException e) {
throw new RuntimeException(e.toString());
} catch (InvocationTargetException e) {
Throwable t = e.getTargetException();
if (t instanceof Error) throw (Error)t;
if (t instanceof RuntimeException) throw (RuntimeException)t;
t.printStackTrace();
throw new RuntimeException(t.toString());
}
}
public static Method getMatchingMethod(Class<?> class_, String name, Object[] args) {
Method[] meths = class_.getMethods();
for (int i=0; i < meths.length; i++) {
Method meth = meths[i];
if (meth.getName().equals(name) && isCompatible(meth, args)) {
return meth;
}
}
return null;
}
private static boolean isCompatible(Method meth, Object[] args) {
// ignore methods with overloading other than lengths
return meth.getParameterTypes().length == args.length;
}
public static Object getStaticField(Class<?> class_, String name) {
try {
return class_.getField(name).get(null);
} catch (IllegalAccessException e) {
throw new RuntimeException("unimplemented");
} catch (NoSuchFieldException e) {
throw new RuntimeException("unimplemented");
}
}
public static void runMainInSameVM(
String classpath,
String className,
String[] args)
throws SecurityException, NoSuchMethodException,
IllegalArgumentException, IllegalAccessException,
InvocationTargetException, ClassNotFoundException {
LangUtil.throwIaxIfNull(className, "class name");
if (LangUtil.isEmpty(classpath)) {
Class<?> mainClass = Class.forName(className);
runMainInSameVM(mainClass, args);
return;
}
ArrayList<File> dirs = new ArrayList<File>();
ArrayList<File> libs = new ArrayList<File>();
ArrayList<URL> urls = new ArrayList<URL>();
String[] entries = LangUtil.splitClasspath(classpath);
for (int i = 0; i < entries.length; i++) {
String entry = entries[i];
URL url = makeURL(entry);
if (null != url) {
urls.add(url);
}
File file = new File(entries[i]);
// tolerate bad entries b/c bootclasspath sometimes has them
// if (!file.canRead()) {
// throw new IllegalArgumentException("cannot read " + file);
// }
if (FileUtil.isZipFile(file)) {
libs.add(file);
} else if (file.isDirectory()) {
dirs.add(file);
} else {
// not URL, zip, or dir - unsure what to do
}
}
File[] dirRa = (File[]) dirs.toArray(new File[0]);
File[] libRa = (File[]) libs.toArray(new File[0]);
URL[] urlRa = (URL[]) urls.toArray(new URL[0]);
runMainInSameVM(urlRa, libRa, dirRa, className, args);
}
public static void runMainInSameVM(
URL[] urls,
File[] libs,
File[] dirs,
String className,
String[] args)
throws SecurityException, NoSuchMethodException,
IllegalArgumentException, IllegalAccessException,
InvocationTargetException, ClassNotFoundException {
LangUtil.throwIaxIfNull(className, "class name");
LangUtil.throwIaxIfNotAssignable(libs, File.class, "jars");
LangUtil.throwIaxIfNotAssignable(dirs, File.class, "dirs");
URL[] libUrls = FileUtil.getFileURLs(libs);
if (!LangUtil.isEmpty(libUrls)) {
if (!LangUtil.isEmpty(urls)) {
URL[] temp = new URL[libUrls.length + urls.length];
System.arraycopy(urls, 0, temp, 0, urls.length);
System.arraycopy(urls, 0, temp, libUrls.length, urls.length);
urls = temp;
} else {
urls = libUrls;
}
}
UtilClassLoader loader = new UtilClassLoader(urls, dirs);
Class<?> targetClass = null;
try {
targetClass = loader.loadClass(className);
} catch (ClassNotFoundException e) {
String s = "unable to load class " + className
+ " using class loader " + loader;
throw new ClassNotFoundException(s);
}
Method main = targetClass.getMethod("main", MAIN_PARM_TYPES);
main.invoke(null, new Object[] { args });
}
public static void runMainInSameVM(Class<?> mainClass, String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
LangUtil.throwIaxIfNull(mainClass, "main class");
Method main = mainClass.getMethod("main", MAIN_PARM_TYPES);
main.invoke(null, new Object[] { args });
}
/** @return URL if the input is valid as such */
private static URL makeURL(String s) {
try {
return new URL(s);
} catch (Throwable t) {
return null;
}
}
}