
org.iworkz.common.helper.ReflectionHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of genesis Show documentation
Show all versions of genesis Show documentation
A simple dependency injection library
The newest version!
package org.iworkz.common.helper;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Predicate;
import javax.inject.Singleton;
import org.iworkz.common.reflection.PropertyInfo;
@Singleton
public class ReflectionHelper {
protected static final Set> FINAL_IMMUTABLES = new HashSet<>();
static {
FINAL_IMMUTABLES.add(String.class);
FINAL_IMMUTABLES.add(Boolean.class);
FINAL_IMMUTABLES.add(Character.class);
FINAL_IMMUTABLES.add(Byte.class);
FINAL_IMMUTABLES.add(Short.class);
FINAL_IMMUTABLES.add(Integer.class);
FINAL_IMMUTABLES.add(Long.class);
FINAL_IMMUTABLES.add(Float.class);
FINAL_IMMUTABLES.add(Double.class);
FINAL_IMMUTABLES.add(Locale.class);
FINAL_IMMUTABLES.add(UUID.class);
FINAL_IMMUTABLES.add(BigInteger.class);
FINAL_IMMUTABLES.add(BigDecimal.class);
FINAL_IMMUTABLES.add(LocalDate.class);
FINAL_IMMUTABLES.add(LocalDateTime.class);
FINAL_IMMUTABLES.add(OffsetDateTime.class);
FINAL_IMMUTABLES.add(ZonedDateTime.class);
}
public Map getFieldMap(Class objectClass) {
Map fieldMap = new HashMap<>();
for (Field field : getAllFields(objectClass)) {
fieldMap.putIfAbsent(field.getName(), field);
}
return fieldMap;
}
public Field[] getAllFields(Class objectClass) {
List fields = new ArrayList();
addAllFields(fields,objectClass);
return fields.toArray(new Field[fields.size()]);
}
protected void addAllFields(List fields, Class objectClass) {
fields.addAll(Arrays.asList(objectClass.getDeclaredFields()));
if (objectClass.getSuperclass() != null) {
addAllFields(fields, objectClass.getSuperclass());
}
}
/**
* Find the first declared method for which the predicate evaluates to true.
* The search starts in in the object class and continues recursively in super classes.
*
* @param objectClass
* @param predicate
* @return
*/
public Method findFirstDeclaredMethod(Class> objectClass, Predicate predicate) {
if (objectClass != null) {
Class> currentClass = objectClass;
while (currentClass != null) {
for (Method method : currentClass.getDeclaredMethods()) {
if (predicate.test(method)) {
return method;
}
}
currentClass = currentClass.getSuperclass();
}
}
return null;
}
public T createObject(Class objectClass) {
try {
Constructor defaultConstructor = objectClass.getConstructor();
T obj = defaultConstructor.newInstance();
return obj;
} catch (Exception ex) {
throw new RuntimeException("Can not create instance for class '"+objectClass.getName()+"'",ex);
}
}
public Class extends T> findClassWithPostfix(ClassLoader classLoader, Class type, String packagePostFix, String namePostFix) {
String className = type.getName();
String packagePart;
String classPart;
int lastDotIndex = className.lastIndexOf('.');
if (lastDotIndex >= 0) {
packagePart = className.substring(0,lastDotIndex);
classPart = className.substring(lastDotIndex+1);
} else {
packagePart = null;
classPart = className;
}
String parentClassPart;
int lastDollarIndex = classPart.lastIndexOf('$');
if (lastDollarIndex >= 0) {
parentClassPart = classPart.substring(0,lastDollarIndex);
classPart = classPart.substring(lastDollarIndex+1);
} else {
parentClassPart = null;
}
String customPackage = null;
if (packagePart != null && packagePart.length() > 0 ) {
if (packagePostFix != null) {
customPackage = packagePart+"."+packagePostFix;
} else {
customPackage = packagePart;
}
} else if (packagePostFix != null) {
customPackage = packagePostFix;
}
String customClass = null;
if (namePostFix != null) {
customClass = classPart+namePostFix;
} else {
customClass = classPart;
}
if (parentClassPart != null) {
customClass = parentClassPart + "$" + customClass;
}
String customClassName = null;
if (customPackage != null) {
customClassName = customPackage+"."+customClass;
} else {
customClassName=customClass;
}
try {
return load(classLoader, customClassName);
} catch (ClassNotFoundException ex) {
// ignore (and return null)
} catch (Exception ex) {
throw new RuntimeException("Can not find class with postfix '"+customClassName+"'");
}
return null;
}
@SuppressWarnings("unchecked")
public Class load(ClassLoader classLoader, String className) throws ClassNotFoundException {
return (Class) classLoader.loadClass(className);
}
public List createPropertyInfos(final Class> sourceClass) {
try {
/* get propertyInfos again but this time synchronized */
List propertyInfoList = new ArrayList<>();
BeanInfo beanInfo = Introspector.getBeanInfo(sourceClass);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
Map fields = getFieldMap(sourceClass);
for (PropertyDescriptor pd : propertyDescriptors) {
PropertyInfo propertyInfo = createPropertyInfo(pd);
if (propertyInfo != null) {
Field field = fields.get(pd.getName());
if (field != null) {
propertyInfo.setField(field);
}
propertyInfoList.add(propertyInfo);
}
}
return propertyInfoList;
} catch (Exception ex) {
throw new RuntimeException("Can not create property info list",ex);
}
}
public PropertyInfo createPropertyInfo(PropertyDescriptor pd) {
Method readMethod = pd.getReadMethod();
if (readMethod != null) {
Method writeMethod = pd.getWriteMethod();
if (writeMethod != null) {
Class> valueClass = pd.getPropertyType();
return createPropertyInfo(valueClass,readMethod,writeMethod);
}
}
return null;
}
public PropertyInfo createPropertyInfo(final Class> valueClass, Method readMethod, Method writeMethod) {
PropertyInfo propertyInfo = new PropertyInfo();
propertyInfo.setReadMethod(readMethod);
propertyInfo.setWriteMethod(writeMethod);
if (valueClass.isArray()) {
propertyInfo.setArray(true);
propertyInfo.setComponentImmutable(isImmutable(valueClass.getComponentType()));
} else if (Collection.class.isAssignableFrom(valueClass)) {
propertyInfo.setCollection(true);
} else if (Map.class.isAssignableFrom(valueClass)) {
propertyInfo.setMap(true);
} else if (isImmutable(valueClass)) {
propertyInfo.setImmutable(isImmutable(valueClass));
}
return propertyInfo;
}
public boolean isImmutable(Class> valueClass) {
if (valueClass.isPrimitive()) {
return false;
}
if (valueClass.isEnum()) {
return false;
}
return FINAL_IMMUTABLES.contains(valueClass);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy