package org.theonefx.wcframework.ioc; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import org.theonefx.wcframework.core.TypeConverter; import org.theonefx.wcframework.core.exception.BeansException; import org.theonefx.wcframework.core.propertyeditor.PropertyEditorRegistrySupport; import org.theonefx.wcframework.ioc.exception.InvalidPropertyException; import org.theonefx.wcframework.ioc.exception.NotWritablePropertyException; import org.theonefx.wcframework.ioc.exception.NullValueInNestedPathException; import org.theonefx.wcframework.ioc.exception.PropertyAccessException; import org.theonefx.wcframework.ioc.exception.PropertyBatchUpdateException; import org.theonefx.wcframework.ioc.exception.TypeMismatchException; import org.theonefx.wcframework.ioc.val.MutablePropertyValues; /** * 接口{@link PropertyAccessor}的抽象实现. * 提供所有转换方法的基本能实现. * 实际的属性访问的实现留给子类. */ public abstract class AbstractPropertyAccessor extends PropertyEditorRegistrySupport implements PropertyAccessor, TypeConverter { public void setPropertyValue(PropertyValue pv) throws BeansException { setPropertyValue(pv.getName(), pv.getValue()); } public void setPropertyValues(PropertyValues pvs) throws BeansException { setPropertyValues(pvs, false, false); } public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) throws BeansException { List<PropertyAccessException> propertyAccessExceptions = null; List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ? ((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues())); for (PropertyValue pv : propertyValues) { try { // This method may throw any BeansException, // which won't be caught here, // if there is a critical failure such as no matching field. // We can attempt to deal only with less serious exceptions. setPropertyValue(pv); } catch (NotWritablePropertyException ex) { if (!ignoreUnknown) { throw ex; } else { // 否则忽略并继续... } } catch (NullValueInNestedPathException ex) { if (!ignoreInvalid) { throw ex; } else { // 否则忽略并继续... } } catch (PropertyAccessException ex) { ex.printStackTrace(); if (propertyAccessExceptions == null) { propertyAccessExceptions = new LinkedList<PropertyAccessException>(); } propertyAccessExceptions.add(ex); } } // If we encountered individual exceptions, throw the composite exception. if (propertyAccessExceptions != null) { PropertyAccessException[] paeArray = propertyAccessExceptions.toArray(new PropertyAccessException[propertyAccessExceptions.size()]); throw new PropertyBatchUpdateException(paeArray); } } public <T> T convertIfNecessary(Object value, Class<T> requiredType) throws TypeMismatchException { return convertIfNecessary(value, requiredType, null); } /** * 获取属性值的真正实现在子类中进行. * @param propertyName 需要被获取值的属性的名称 * @return 目标属性的值 * @throws InvalidPropertyException 如果找不到该属性或者该属性不可读 * @throws PropertyAccessException 如果该属性是有效的,但是对该属性的访问却失败了 */ public abstract Object getPropertyValue(String propertyName) throws BeansException; /** * 设置属性值的真正实现在子类中进行. * @param propertyName 需要被设置值的属性的名称 * @param value 属性的新的值 * @throws InvalidPropertyException 如果找不到该属性或者该属性不可写 * @throws PropertyAccessException 该属性本身是有效的,但是调用访问方法时失败或者新的值类型不匹配 */ public abstract void setPropertyValue(String propertyName, Object value) throws BeansException; }