package com.test.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.*;
public class ClassUtils {
private static final Logger log = LoggerFactory.getLogger(ClassUtils.class);
private static final Set<String> baseTypeSet = getBaseTypeSet();
private static final Set<String> collectionTypeSet = getCollectionTypeSet();
private static final Set<String> mapTypeSet = getMapTypeSet();
private ClassUtils() {
}
@Test
public void test1() {
String json = JsonUtils.object2Json(ClassUtils.getFieldInfo(YourTestClass.class, new HashSet<>()));
System.out.println(json);
Assert.assertNotNull(json);
}
public static Map<String, Object> getFieldInfo(Class<?> clazz, Set<Class<?>> existClass) {
HashMap<String, Object> map = new HashMap<>();
Field[] fields = clazz.getDeclaredFields();
map.put("oaFullPathClassName", clazz.getName());
if (existClass.contains(clazz)) {
map.put("duplicateClass", true);
return map;
}
if (!isBaseType(clazz)) {
existClass.add(clazz);
}
for (Field field : fields) {
Class<?> type = field.getType();
String fieldName = field.getName();
if (isCollectionType(type)) {
map.put(fieldName, getCollectionType(field, existClass));
}else if (type.isArray()){
map.put(fieldName, getArrayType(field, existClass));
}else if (isMapType(type)){
map.put(fieldName, getMapType(field, existClass));
}else {
map.put(fieldName, getValueType(type, existClass));
}
}
return map;
}
private static List<Object> getArrayType(Field field, Set<Class<?>> existClass) {
Class<?> type = field.getType();
String typeName = type.getTypeName();
String[] split = typeName.split("]");
if (split.length == 1) {
String className = split[0].substring(0, split[0].length() - 1);
try {
Class<?> baseClass = CollectionUtils.getBaseClassMap().get(className);
if (baseClass != null) {
return getCollectionType(baseClass, existClass);
}
return getCollectionType(Class.forName(className), existClass);
} catch (ClassNotFoundException e) {
log.error("getArrayType fail.", e);
}
return getCollectionType(Object.class, existClass);
}else {
throw new ClassCastException("Unsupported type. type: " + typeName +" , fieldName:" + field.getName());
}
}
private static List<Object> getCollectionType(Class<?> clazz, Set<Class<?>> existClass) {
return Collections.singletonList(getValueType(clazz, existClass));
}
private static List<Object> getCollectionType(Field field, Set<Class<?>> existClass) {
Class<?> actualTypeClazz;
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType
&& ((ParameterizedType) genericType).getActualTypeArguments()[0] instanceof Class) {
ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
actualTypeClazz = (Class<?>) parameterizedType.getActualTypeArguments()[0];
}else {
actualTypeClazz = Object.class;
}
return getCollectionType(actualTypeClazz, existClass);
}
private static Map<String, Object> getMapType(Field field, Set<Class<?>> existClass) {
HashMap<String, Object> mapTypeMap = new HashMap<>();
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType
&& ((ParameterizedType) genericType).getActualTypeArguments()[0] instanceof Class
&& ((ParameterizedType) genericType).getActualTypeArguments()[1] instanceof Class) {
ParameterizedType parameterizedType = (ParameterizedType) genericType;
Class<?> keyClass = (Class<?>) parameterizedType.getActualTypeArguments()[0];
mapTypeMap.put("mapKey", getValueType(keyClass, existClass));
Class<?> valueClass = (Class<?>) parameterizedType.getActualTypeArguments()[1];
mapTypeMap.put("mapValue", getValueType(valueClass, existClass));
}else {
mapTypeMap.put("mapKey", Object.class.getName());
mapTypeMap.put("mapValue", Object.class.getName());
}
return mapTypeMap;
}
private static Object getValueType(Class<?> clazz, Set<Class<?>> existClass) {
if (isBaseType(clazz)) {
return clazz.getTypeName();
}
return getFieldInfo(clazz, existClass);
}
private static boolean isMapType(Class<?> clazz) {
return mapTypeSet.contains(clazz.getName());
}
private static boolean isCollectionType(Class<?> clazz) {
return collectionTypeSet.contains(clazz.getName());
}
private static boolean isBaseType(Class<?> clazz) {
return baseTypeSet.contains(clazz.getName());
}
private static Set<String> getBaseTypeSet() {
String[] types = {Integer.class.getName(),
Double.class.getName(),
Long.class.getName(),
Short.class.getName(),
Byte.class.getName(),
Boolean.class.getName(),
Character.class.getName(),
Float.class.getName(),
String.class.getName(),
Object.class.getName(),
BigDecimal.class.getName(),
Date.class.getName(),
int.class.getName(),
double.class.getName(),
long.class.getName(),
short.class.getName(),
byte.class.getName(),
boolean.class.getName(),
char.class.getName(),
float.class.getName()};
return new HashSet<>(Arrays.asList(types));
}
private static Set<String> getCollectionTypeSet() {
String[] types = {List.class.getName(), Set.class.getName(), ArrayList.class.getName(), HashSet.class.getName()};
return new HashSet<>(Arrays.asList(types));
}
private static Set<String> getMapTypeSet() {
String[] types = {Map.class.getName(), HashMap.class.getName()};
return new HashSet<>(Arrays.asList(types));
}
public static Object getFieldValue(Object obj, String fieldName) {
for (Method method : obj.getClass().getDeclaredMethods()) {
if (("get" + fieldName).equalsIgnoreCase(method.getName())) {
try {
return method.invoke(obj);
} catch (Exception e) {
log.error("getFieldValue has exception. fieldName:{}", fieldName);
}
}
}
log.warn("getFieldValue fail. fieldName:{}", fieldName);
return null;
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
public class CollectionUtils {
private static final Logger log = LoggerFactory.getLogger(CollectionUtils.class);
private static Set<Class<?>> baseClassSet;
private static Map<String, Class<?>> baseClassMap;
private CollectionUtils() {
}
public static <K, V> Map<K, V> collectionToMap(Collection<V> collection, Method method) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
if (collection == null || collection.isEmpty()) {
return Collections.emptyMap();
}
HashMap<K, V> map = new HashMap<>();
for (V v : collection) {
map.put((K)method.invoke(v), v);
}
return map;
}
public static Map<String, Class<?>> getBaseClassMap() {
if (baseClassMap == null) {
try {
Method method = Class.class.getDeclaredMethod("getName");
baseClassMap = collectionToMap(getBaseClassSet(), method);
} catch (Exception e) {
log.error("getBaseTypeMap fail", e);
baseClassMap = Collections.emptyMap();
}
}
return baseClassMap;
}
public static Set<Class<?>> getBaseClassSet() {
if (baseClassSet == null) {
Class<?>[] clazzArray = {int.class,
double.class,
long.class,
short.class,
byte.class,
boolean.class,
char.class,
float.class};
baseClassSet = new HashSet<>(Arrays.asList(clazzArray));
}
return baseClassSet;
}
}