
org.unidal.helper.Reflects Maven / Gradle / Ivy
The newest version!
package org.unidal.helper;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class Reflects {
private Reflects() {
}
public static ClassReflector forClass() {
return ClassReflector.INSTANCE;
}
public static ConstructorReflector forConstructor() {
return ConstructorReflector.INSTANCE;
}
public static FieldReflector forField() {
return FieldReflector.INSTANCE;
}
public static MethodReflector forMethod() {
return MethodReflector.INSTANCE;
}
public static ModifierReflector forModifier() {
return ModifierReflector.INSTANCE;
}
public static ResourceReflector forResource() {
return ResourceReflector.INSTANCE;
}
public enum ClassReflector {
INSTANCE;
/**
* for class name like "a.b.C" or "a.b.C$D$E"
*
* @param className
* @return class from current context class loader
*/
public Class> getClass(String className) {
return getClass(className, null);
}
/**
* for class name like "a.b.C" or "a.b.C$D$E"
*
* @param className
* @param classloader
* @return class from current context class loader
*/
public Class> getClass(String className, ClassLoader classloader) {
Class> clazz = null;
if (classloader != null) {
try {
clazz = classloader.loadClass(className);
} catch (Throwable e) {
// ignore it
}
} else {
// step1: try to load from caller class loader
try {
clazz = Class.forName(className);
} catch (Throwable e) {
// step2: try to load from thread context class loader
if (clazz == null) {
clazz = getClass(className, Thread.currentThread().getContextClassLoader());
}
// step3: try to load from current-class class loader
if (clazz == null) {
clazz = getClass(className, Reflects.class.getClassLoader());
}
}
}
return clazz;
}
/**
* for class name like "a.b.C" or "a.b.C.D.E"
*
* @param className
* @return class from current context class loader
*/
public Class> getClass2(String className) {
return getClass2(className, null);
}
/**
* for class name like "a.b.C" or "a.b.C.D.E"
*
* @param className
* @return class from current context class loader
*/
public Class> getClass2(String className, ClassLoader classloader) {
Class> clazz;
String name = className;
while (true) {
clazz = getClass(name, classloader);
if (clazz != null) {
break;
}
// try with inner class name
int pos = name.lastIndexOf('.');
if (pos < 0) {
break;
}
name = name.substring(0, pos) + '$' + name.substring(pos + 1);
}
return clazz;
}
public Class> getNestedClass(Class> clazz, String simpleName) {
if (clazz != null) {
Class>[] subClasses = clazz.getDeclaredClasses();
if (subClasses != null) {
for (Class> subClass : subClasses) {
if (subClass.getSimpleName().equals(simpleName)) {
return subClass;
}
}
}
}
return null;
}
public Class> getNestedClass(String className, String simpleName) {
return getNestedClass(getClass(className), simpleName);
}
public Class> getNestedClass(String className, String simpleName, ClassLoader classloader) {
return getNestedClass(getClass(className, classloader), simpleName);
}
}
public enum ConstructorReflector {
INSTANCE;
public Object createInstance(Class> clazz, Object... typesAndParameters) {
try {
TypeArguments typeArgs = new TypeArguments(typesAndParameters);
Constructor> constructor = clazz.getConstructor(typeArgs.getTypes());
return constructor.newInstance(typeArgs.getArguments());
} catch (Exception e) {
// ignore it
}
return null;
}
}
public enum FieldFilter implements IMemberFilter {
PUBLIC {
public boolean filter(Field field) {
return ModifierReflector.INSTANCE.isPublic(field);
}
},
STATIC {
public boolean filter(Field field) {
return ModifierReflector.INSTANCE.isStatic(field);
}
},
PUBLIC_STATIC {
public boolean filter(Field field) {
return ModifierReflector.INSTANCE.isPublic(field) && ModifierReflector.INSTANCE.isStatic(field);
}
};
}
public enum FieldReflector {
INSTANCE;
public List getAllDeclaredFields(Class> clazz, IMemberFilter filter) {
List list = new ArrayList();
Class> current = clazz;
while (current != null && current != Object.class) {
Field[] fields = current.getDeclaredFields();
for (Field field : fields) {
if (filter == null || filter.filter(field)) {
list.add(field);
}
}
current = current.getSuperclass();
}
return list;
}
public Field getDeclaredField(Class> clazz, String fieldName) {
if (clazz != null) {
try {
Field field = clazz.getDeclaredField(fieldName);
return field;
} catch (Exception e) {
// ignore
}
}
return null;
}
public Field getDeclaredField(Object instance, String fieldName) {
Class> clazz = instance.getClass();
while (clazz != null) {
try {
return clazz.getDeclaredField(fieldName);
} catch (Exception e) {
// ignore
}
clazz = clazz.getSuperclass();
}
return null;
}
public List getDeclaredFields(Class> clazz, IMemberFilter filter) {
List list = new ArrayList();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (filter == null || filter.filter(field)) {
list.add(field);
}
}
return list;
}
public List getDeclaredFields(Object instance, IMemberFilter filter) {
List list = new ArrayList();
Class> clazz = instance.getClass();
while (clazz != null) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (filter == null || filter.filter(field)) {
list.add(field);
}
}
clazz = clazz.getSuperclass();
}
return list;
}
@SuppressWarnings("unchecked")
public T getDeclaredFieldValue(Class> clazz, String fieldName, Object instance) {
Field field = getDeclaredField(clazz, fieldName);
if (field != null) {
try {
if (!field.isAccessible()) {
field.setAccessible(true);
}
return (T) field.get(instance);
} catch (Exception e) {
// ignore
}
}
return null;
}
@SuppressWarnings("unchecked")
public T getDeclaredFieldValue(Object instance, String... fields) {
Object value = instance;
for (String field : fields) {
value = getDeclaredFieldValue(value.getClass(), field, value);
if (value == null) {
break;
}
}
return (T) value;
}
public List getFields(Class> clazz, IMemberFilter filter) {
List list = new ArrayList();
Field[] fields = clazz.getFields();
for (Field field : fields) {
if (filter == null || filter.filter(field)) {
list.add(field);
}
}
return list;
}
@SuppressWarnings("unchecked")
public T getFieldValue(Object instance, String fieldName) {
if (instance != null) {
try {
Field field = instance.getClass().getField(fieldName);
return (T) field.get(instance);
} catch (Exception e) {
// ignore
}
}
return null;
}
@SuppressWarnings("unchecked")
public T getStaticFieldValue(Class> clazz, String fieldName) {
if (clazz != null) {
try {
Field field = clazz.getField(fieldName);
return (T) field.get(null);
} catch (Exception e) {
// ignore
}
}
return null;
}
@SuppressWarnings("unchecked")
public T getStaticFieldValue(String className, String fieldName) {
try {
Class> clazz = forClass().getClass(className);
if (clazz != null) {
return (T) getStaticFieldValue(clazz, fieldName);
}
} catch (Exception e) {
// ignore it
}
return null;
}
public boolean setDeclaredFieldValue(Class> clazz, String fieldName, Object instance, Object value) {
Field field = getDeclaredField(clazz, fieldName);
if (field != null) {
try {
if (!field.isAccessible()) {
field.setAccessible(true);
}
field.set(instance, value);
return true;
} catch (Exception e) {
// ignore
}
}
return false;
}
}
public static interface IMemberFilter {
public boolean filter(T member);
}
public enum MethodFilter implements IMemberFilter {
PUBLIC {
public boolean filter(Method method) {
return ModifierReflector.INSTANCE.isPublic(method);
}
},
STATIC {
public boolean filter(Method method) {
return ModifierReflector.INSTANCE.isStatic(method);
}
},
PUBLIC_STATIC {
public boolean filter(Method method) {
return ModifierReflector.INSTANCE.isPublic(method) && ModifierReflector.INSTANCE.isStatic(method);
}
};
}
public enum MethodReflector {
INSTANCE;
public Method getDeclaredMethod(Class> clazz, String methodName, Class>... parameterTypes) {
try {
return clazz.getDeclaredMethod(methodName, parameterTypes);
} catch (Exception e) {
// ignore it
}
return null;
}
public List getDeclaredMethods(Class> clazz, IMemberFilter filter) {
List list = new ArrayList();
try {
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if (filter == null || filter.filter(method)) {
list.add(method);
}
}
} catch (Exception e) {
// ignore it
}
return list;
}
public String getGetMethodName(String property) {
int len = property == null ? 0 : property.length();
if (len == 0) {
throw new IllegalArgumentException(String.format("Invalid property name: %s!", property));
}
StringBuilder sb = new StringBuilder(len + 3);
boolean upper = true;
sb.append("get");
for (int i = 0; i < len; i++) {
char ch = property.charAt(i);
if (upper) {
sb.append(Character.toUpperCase(ch));
upper = false;
} else {
if (ch == '_' || !Character.isLetterOrDigit(ch)) {
upper = true;
} else {
sb.append(ch);
}
}
}
return sb.toString();
}
public String getGetterName(Method method) {
String name = method.getName();
int length = name.length();
if (length > 3 && name.startsWith("get")) {
return Character.toLowerCase(name.charAt(3)) + name.substring(4);
} else if (length > 2 && name.startsWith("is")) {
return Character.toLowerCase(name.charAt(2)) + name.substring(3);
} else {
return name;
}
}
public Method getMethod(Class> clazz, String methodName, Class>... parameterTypes) {
try {
return clazz.getMethod(methodName, parameterTypes);
} catch (Exception e) {
// ignore it
}
return null;
}
public List getMethods(Class> clazz, IMemberFilter filter) {
List list = new ArrayList();
try {
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (filter == null || filter.filter(method)) {
list.add(method);
}
}
} catch (Exception e) {
// ignore it
}
return list;
}
@SuppressWarnings("unchecked")
public T getPropertyValue(Object instance, String propertyName) {
String methodName = getGetMethodName(propertyName);
Object value = invokeMethod(instance, methodName);
return (T) value;
}
public String getSetMethodName(String property) {
int len = property == null ? 0 : property.length();
if (len == 0) {
throw new IllegalArgumentException(String.format("Invalid property name: %s!", property));
}
StringBuilder sb = new StringBuilder(len + 3);
boolean upper = true;
sb.append("set");
for (int i = 0; i < len; i++) {
char ch = property.charAt(i);
if (upper) {
sb.append(Character.toUpperCase(ch));
upper = false;
} else {
if (ch == '_' || !Character.isLetterOrDigit(ch)) {
upper = true;
} else {
sb.append(ch);
}
}
}
return sb.toString();
}
public Method getSetterMethod(Object instance, String propertyName) {
String methodName = getSetMethodName(propertyName);
Method[] methods = instance.getClass().getMethods();
try {
for (Method method : methods) {
if (method.getParameterTypes().length == 1 && method.getName().equals(methodName)) {
return method;
}
}
} catch (Exception e) {
// ignore it
}
return null;
}
@SuppressWarnings("unchecked")
public T invokeDeclaredMethod(Object instance, String methodName, Object... typesAndParameters) {
if (instance == null) {
return null;
}
TypeArguments typeArgs = new TypeArguments(typesAndParameters);
Method method = getDeclaredMethod(instance.getClass(), methodName, typeArgs.getTypes());
if (method != null) {
try {
method.setAccessible(true);
return (T) method.invoke(instance, typeArgs.getArguments());
} catch (Exception e) {
// ignore it
}
}
return null;
}
@SuppressWarnings("unchecked")
public T invokeMethod(Object instance, String methodName, Object... typesAndParameters) {
if (instance == null) {
return null;
}
TypeArguments typeArgs = new TypeArguments(typesAndParameters);
Method method = getMethod(instance.getClass(), methodName, typeArgs.getTypes());
if (method != null) {
try {
return (T) method.invoke(instance, typeArgs.getArguments());
} catch (Exception e) {
// ignore it
}
}
return null;
}
@SuppressWarnings("unchecked")
public T invokeStaticMethod(Class> clazz, String methodName, Object... typesAndParameters) {
if (clazz == null) {
return null;
}
TypeArguments typeArgs = new TypeArguments(typesAndParameters);
Method method = getMethod(clazz, methodName, typeArgs.getTypes());
if (method != null) {
try {
return (T) method.invoke(null);
} catch (Exception e) {
// ignore it
}
}
return null;
}
public boolean isGetter(Method method) {
if (method.getParameterTypes().length > 0) {
return false;
}
int modifier = method.getModifiers();
if (!Modifier.isPublic(modifier) || Modifier.isStatic(modifier)) {
return false;
}
String name = method.getName();
if (name.startsWith("get") && !name.equals("getClass")) {
return true;
} else if (name.startsWith("is") && method.getReturnType() == Boolean.TYPE) {
return true;
} else {
return false;
}
}
}
public enum ModifierReflector {
INSTANCE;
public boolean isAbstract(Class> clazz) {
return Modifier.isAbstract(clazz.getModifiers());
}
public boolean isAbstract(Member member) {
return Modifier.isAbstract(member.getModifiers());
}
public boolean isPublic(Class> clazz) {
return Modifier.isPublic(clazz.getModifiers());
}
public boolean isPublic(Member member) {
return Modifier.isPublic(member.getModifiers());
}
public boolean isStatic(Class> clazz) {
return Modifier.isStatic(clazz.getModifiers());
}
public boolean isStatic(Member member) {
return Modifier.isStatic(member.getModifiers());
}
}
public enum ResourceReflector {
INSTANCE;
public Properties getResource(Class> anchorClass, String resName) {
// step1: try to load from current class loader
Properties prop = getResource(getClass().getClassLoader(), anchorClass, resName);
// step2: try to load from thread context class loader
if (prop == null) {
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
prop = getResource(classloader, anchorClass, resName);
}
return prop;
}
public Properties getResource(ClassLoader classloader, Class> anchorClass, String resName) {
resName = getResourceName(anchorClass, resName);
URL url = classloader.getResource(resName);
if (url != null) {
try {
Properties prop = new Properties();
prop.load(url.openStream());
return prop;
} catch (IOException e) {
// ignore it
}
}
return null;
}
public Properties getResource(String resName) {
return getResource(Reflects.class, resName);
}
private String getResourceName(Class> clazz, String resName) {
// Turn package name into a directory path
if (resName.length() > 0 && resName.charAt(0) == '/')
return resName.substring(1);
String qualifiedClassName = clazz != null ? clazz.getName() : getClass().getName();
int classIndex = qualifiedClassName.lastIndexOf('.');
if (classIndex == -1)
return resName; // from a default package
return qualifiedClassName.substring(0, classIndex + 1).replace('.', '/') + resName;
}
}
static class TypeArguments {
private Class>[] m_types;
private Object[] m_arguments;
public TypeArguments(Object... typesAndParameters) {
int length = typesAndParameters.length;
if (length % 2 != 0) {
throw new IllegalArgumentException(String.format("Constrcutor argument types and data should be even"
+ ", but was odd: %s.", length));
}
int half = length / 2;
Class>[] types = new Class>[half];
Object[] arguments = new Object[half];
for (int i = 0; i < half; i++) {
types[i] = (Class>) typesAndParameters[2 * i];
arguments[i] = typesAndParameters[2 * i + 1];
}
m_types = types;
m_arguments = arguments;
}
public Object[] getArguments() {
return m_arguments;
}
public Class>[] getTypes() {
return m_types;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy