jexx.bean.DyBeanImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jexx-bean Show documentation
Show all versions of jexx-bean Show documentation
This is a simple tool for java!
The newest version!
package jexx.bean;
import jexx.convert.Convert;
import jexx.util.Assert;
import jexx.util.MapUtil;
import jexx.util.ReflectUtil;
import jexx.util.TypeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;
/**
* 参考spring的BeanWrapperImpl
* @author jeff
*/
public class DyBeanImpl extends AbstractBeanPropertyAccessor implements DyBean {
private static final Logger LOG = LoggerFactory.getLogger(DyBeanImpl.class);
protected CachedIntrospectionResults cachedIntrospectionResults;
@Override
protected AbstractBeanPropertyAccessor newNestedPropertyAccessor(Object object, String nestedPath) {
DyBeanImpl dyBean = new DyBeanImpl();
dyBean.setWrappedInstance(object, nestedPath, getWrappedInstance());
dyBean.setAllowCollectionAutoGrow(this.allowCollectionAutoGrow);
dyBean.setAllowCreateHoldValueIfNull(this.allowCreateHoldValueIfNull);
return dyBean;
}
protected CachedIntrospectionResults getCachedIntrospectionResults() {
if (this.cachedIntrospectionResults == null) {
this.cachedIntrospectionResults = CachedIntrospectionResults.forClass(getWrappedClass());
}
return this.cachedIntrospectionResults;
}
/**
* 设置bean对象;
* @param object 待包装对象,必须是bean
*/
@Override
public void setWrappedInstance(Object object){
Assert.isTrue(object != null && BeanUtil.isBean(object.getClass()), "object must be a bean");
setWrappedInstance(object, "", null);
}
/**
* 设置类型为map的代理对象; 获取field1属性对应的值需要如下调用:
*
* getPropertyValue("$[field1]")
*
* @param object map代理对象,只支持Map
*/
public void setWrappedInstance(Map object){
MapBean bean = new MapBean(object);
setWrappedInstance(bean, "", null);
}
@Override
public boolean isReadableProperty(String propertyName) {
PropertyDescriptor propertyDescriptor = getCachedIntrospectionResults().getPropertyDescriptor(propertyName);
if(propertyDescriptor == null){
LOG.debug("propertyName \"{}\" not found!", propertyName);
}
return propertyDescriptor != null && propertyDescriptor.getReadMethod() != null;
}
@Override
public boolean isWritableProperty(String propertyName) {
PropertyDescriptor propertyDescriptor = getCachedIntrospectionResults().getPropertyDescriptor(propertyName);
if(propertyDescriptor == null){
LOG.debug("propertyName \"{}\" not found!", propertyName);
}
return propertyDescriptor != null && propertyDescriptor.getWriteMethod() != null;
}
@Override
public PropertyDescriptor[] getPropertyDescriptors() {
return getCachedIntrospectionResults().getPropertyDescriptors();
}
@Override
public PropertyDescriptor getPropertyDescriptor(String propertyName) {
return getCachedIntrospectionResults().getPropertyDescriptor(propertyName);
}
@Override
protected PropertyHandle getPropertyHandle(String propertyName) {
PropertyDescriptor propertyDescriptor = getCachedIntrospectionResults().getPropertyDescriptor(propertyName);
if(propertyDescriptor == null){
return null;
}
return new BeanPropertyHandle(propertyDescriptor);
}
/**
* 当前包装对象是否为map对象
*/
public boolean isMap(){
return getWrappedInstance() instanceof Map;
}
protected class BeanPropertyHandle extends PropertyHandle{
private PropertyDescriptor propertyDescriptor;
public BeanPropertyHandle(PropertyDescriptor propertyDescriptor) {
super(propertyDescriptor.getName(), propertyDescriptor.getReadMethod() != null, propertyDescriptor.getWriteMethod() != null);
this.propertyDescriptor = propertyDescriptor;
}
@Override
public Object getValue() throws Exception {
final Method readMethod = this.propertyDescriptor.getReadMethod();
ReflectUtil.makeAccessible(readMethod);
Object wrappedObject = getWrappedInstance();
return readMethod.invoke(wrappedObject, (Object[]) null);
}
@Override
public Class> getPropertyType() {
return propertyDescriptor.getPropertyType();
}
@Override
public Class> getCollectionType(int nestingLevel) {
return getNestedType(nestingLevel);
}
@Override
public Class> getMapKeyType(int nestingLevel) {
return getNestedType(nestingLevel, MapUtil.toMap(nestingLevel, 0));
}
@Override
public Class> getMapValueType(int nestingLevel) {
return getNestedType(nestingLevel, MapUtil.toMap(nestingLevel, 1));
}
@Override
public void setValue(Object value) throws Exception {
final Method writeMethod = this.propertyDescriptor.getWriteMethod();
Class>[] parameterTypes = writeMethod.getParameterTypes();
ReflectUtil.makeAccessible(writeMethod);
writeMethod.invoke(getWrappedInstance(), Convert.convert(parameterTypes[0], value));
}
@Override
protected Class> getNestedType(int nestingLevel, Map typeIndexesPerLevel) {
final Method readMethod = this.propertyDescriptor.getReadMethod();
Type type = readMethod.getGenericReturnType();
Class clazz = type.getClass();
for(int i = 1; i <= nestingLevel; i++){
if(clazz.isArray()){
type = clazz.getComponentType();
}
else{
if(type instanceof ParameterizedType){
Type[] types = ((ParameterizedType) type).getActualTypeArguments();
Integer index = (typeIndexesPerLevel != null ? typeIndexesPerLevel.get(i) : null);
index = (index == null ? types.length - 1 : index);
type = types[index];
}
}
}
return resolveClass(type);
}
}
private class MapBean{
private Map $;
public MapBean(Map $) {
this.$ = $;
}
public Map get$() {
return $;
}
public void set$(Map $) {
this.$ = $;
}
}
}