package org.dayatang.utils;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;
/**
* 针对JavaBean Class的工具类。
*
* @author yyang (<a href="mailto:gdyangyu@gmail.com">gdyangyu@gmail.com</a>)
*/
public class BeanClassUtils {
private final Class<?> clazz;
/**
* 接受一个类,生成BeanClassUtils实例
*
* @param clazz 原始类
*/
public BeanClassUtils(final Class<?> clazz) {
Assert.notNull(clazz);
this.clazz = clazz;
}
/**
* 获得所有属性的类型,包括从父类继承的属性
*
* @return 一个Map,Key为属性名, Value为属性所属的类
*/
public Map<String, Class<?>> getPropTypes() {
Map<String, Class<?>> results = new HashMap<String, Class<?>>();
for (Map.Entry<String, PropertyDescriptor> each : getPropertyDescriptors().entrySet()) {
results.put(each.getKey(), each.getValue().getPropertyType());
}
return results;
}
/**
* 获得指定JavaBean类型的所有属性的名字,包括从父类继承的属性
*
* @return JavaBean的属性名的集合
*/
public Set<String> getPropNames() {
return getPropertyDescriptors().keySet();
}
/**
* 获得指定JavaBean类型的所有可读属性的名字,包括从父类继承的属性
*
* @return JavaBean的属性名的集合
*/
public Set<String> getReadablePropNames() {
Set<String> results = new HashSet<String>();
for (Map.Entry<String, PropertyDescriptor> each : getPropertyDescriptors().entrySet()) {
if (each.getValue().getReadMethod() == null) {
continue;
}
results.add(each.getKey());
}
return results;
}
/**
* 获得指定JavaBean类型的所有可写属性的名字,包括从父类继承的属性
*
* @return JavaBean的属性名的集合
*/
public Set<String> getWritablePropNames() {
Set<String> results = new HashSet<String>();
for (Map.Entry<String, PropertyDescriptor> each : getPropertyDescriptors().entrySet()) {
if (each.getValue().getWriteMethod() == null) {
continue;
}
results.add(each.getKey());
}
return results;
}
/**
* 获得JavaBean的属性值的值,包括从父类继承的属性,不包含指定的属性。
*
* @param excludePropNames 要排除的属性名
* @return 一个Map,其中Key为属性名,Value为属性值。
*/
public Set<String> getReadablePropNamesExclude(String... excludePropNames) {
List<String> propNamesExclude = Arrays.asList(excludePropNames);
Set<String> results = new HashSet<String>();
for (String propName : getReadablePropNames()) {
if (propNamesExclude.contains(propName)) {
continue;
}
results.add(propName);
}
return results;
}
/**
* 获得JavaBean的属性值的值,包括从父类继承的属性,不包含指定由指定Annotation标记的的属性。
*
* @param excludeAnnotations 一批Annotation,被这些Annotation标注的属性将被排除
* @return 一个Map,其中Key为属性名,Value为属性值。
*/
public Set<String> getReadablePropNamesExclude(Class<? extends Annotation>... excludeAnnotations) {
List<Class<? extends Annotation>> annotationsExclude = Arrays.asList(excludeAnnotations);
Set<String> results = new HashSet<String>();
Map<String, PropertyDescriptor> props = getPropertyDescriptors();
for (String propName : getReadablePropNames()) {
PropertyDescriptor propertyDescriptor = props.get(propName);
Method readMethod = propertyDescriptor.getReadMethod();
if (readMethod == null) {
continue;
}
if (methodContainsAnnotation(readMethod, annotationsExclude)) {
continue;
}
results.add(propName);
}
return results;
}
/**
* 获得类的属性描述
*
* @return 类的属性描述的Map,Key为属性名,Value为属性描述对象
*/
Map<String, PropertyDescriptor> getPropertyDescriptors() {
Map<String, PropertyDescriptor> results = new HashMap<String, PropertyDescriptor>();
try {
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
results.put(propertyDescriptor.getName(), propertyDescriptor);
}
results.remove("class");
} catch (IntrospectionException e) {
throw new RuntimeException(e);
}
return results;
}
private boolean methodContainsAnnotation(Method readMethod, List<Class<? extends Annotation>> annotationsExclude) {
for (Class<? extends Annotation> annotationClass : annotationsExclude) {
if (readMethod.isAnnotationPresent(annotationClass)) {
return true;
}
}
return false;
}
}