/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.java.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.whole.lang.exceptions.WholeRuntimeException;
/**
* @author Enrico Persiani
*/
public class JavaReflectUtils {
public static class JavaSignature {
public final String name;
public final Class<?>[] types;
public final boolean isVarArgs;
private JavaSignature(String name, Class<?>[] types, boolean isVarArgs) {
this.name = name;
this.types = types;
this.isVarArgs = isVarArgs;
}
}
public static JavaSignature create(String name, Class<?>[] types, boolean isVarArgs) {
return new JavaSignature(name, types, isVarArgs);
}
public static JavaSignature fromMethod(Method method) {
return new JavaSignature(method.getName(), method.getParameterTypes(),
method.isVarArgs());
}
public static Method toMethod(Class<?> declaringClass, JavaSignature signature)
throws SecurityException, NoSuchMethodException {
return declaringClass.getMethod(signature.name, signature.types);
}
public static JavaSignature fromConstructor(Constructor<?> constructor) {
return new JavaSignature(constructor.getDeclaringClass().getSimpleName(),
constructor.getParameterTypes(), constructor.isVarArgs());
}
public static <T> Constructor<T> toConstructor(Class<T> declaringClass,
JavaSignature signature) throws SecurityException, NoSuchMethodException {
assert declaringClass.getSimpleName().equals(signature.name);
return declaringClass.getConstructor(signature.types);
}
public static JavaSignature parse(String signature, ClassLoader loader) {
return new JavaSignaturesPredictiveParser(signature, loader).parseSignature();
}
public static String unparse(JavaSignature signature) {
StringBuilder sb = new StringBuilder();
sb.append(signature.name);
sb.append('(');
int length = signature.types.length - (signature.isVarArgs ? 1 : 0);
for (int i = 0; i < length; i++) {
if (i>0)
sb.append(", ");
sb.append(signature.types[i].getCanonicalName());
}
if (signature.isVarArgs) {
if (length>0)
sb.append(", ");
Class<?> type = signature.types[length];
sb.append(type.getComponentType().getCanonicalName());
sb.append("...");
}
sb.append(')');
return sb.toString();
}
public static final Class<?> forName(String className, ClassLoader loader) {
try {
return Class.forName(className, true, loader);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("cannot find class", e);
}
}
public static String getSignature(Constructor<?> constructor) {
return unparse(fromConstructor(constructor));
}
public static String getSignature(Method method) {
return unparse(fromMethod(method));
}
public static Method getMethod(String className, String signature, ClassLoader loader) {
return getMethod(forName(className, loader), signature, loader);
}
public static Method getMethod(Class<?> declaringClass, String signature, ClassLoader loader) {
return getMethod(declaringClass, parse(signature, loader));
}
public static Method getMethod(Class<?> declaringClass, JavaSignature signature) {
try {
return toMethod(declaringClass, signature);
} catch (Exception e) {
throw new IllegalArgumentException("cannot find method", e);
}
}
public static Constructor<?> getConstructor(String className, String signature, ClassLoader loader) {
return getConstructor(forName(className, loader), signature, loader);
}
public static <T> Constructor<T> getConstructor(Class<T> declaringClass, String signature, ClassLoader loader) {
return getConstructor(declaringClass, parse(signature, loader));
}
public static <T> Constructor<T> getConstructor(Class<T> declaringClass, JavaSignature signature) {
try {
return toConstructor(declaringClass, signature);
} catch (Exception e) {
throw new IllegalArgumentException("cannot find method", e);
}
}
public static Object invokeMethod(Method method, Object... arguments) {
return invokeMethod(null, method, arguments);
}
public static Object invokeMethod(Object instance, Method method, Object... arguments) {
try {
return method.invoke(instance, arguments);
} catch (InvocationTargetException e) {
throw new WholeRuntimeException(e.getTargetException());
} catch (Exception e) {
throw new IllegalStateException("method invocation error", e);
}
}
public static <T> T invokeConstructor(Constructor<T> constructor, Object... arguments) {
try {
return constructor.newInstance(arguments);
} catch (Exception e) {
throw new IllegalStateException("constructor invocation error", e);
}
}
}