package org.theonefx.wcframework.ioc; import java.beans.PropertyDescriptor; import java.io.Serializable; import org.theonefx.wcframework.core.inject.Injector; import org.theonefx.wcframework.utils.Assert; import org.theonefx.wcframework.utils.ObjectUtils; /** * 用于持有指定的Bean的Property的值和相关信息。 * 在设立使用一个对象而不是简单的将所有Property存储在一个map里,目的是为了获得更多的灵活性. * 同时还可以支持基于索引的Property处理。 * * <p>需要注意的一点是,value不一定是最终需要的类型: * {@link BeanWrapper} 的实现需要处理所有需要的类型转换,而此对象根本就不知道也不需要关心任何关于自己会被如何使用。 */ public class PropertyValue extends BeanMetadataAttributeAccessor implements Serializable { private static final long serialVersionUID = 1L; private final String name; private final Object value; private Object source; private boolean converted = false; private Object convertedValue; /** * 是否需要类型转换 * 这是一个对象默认为NULL,也就是说,默认不知道是否需要类型转换 */ volatile Boolean conversionNecessary = null; /** 缓存解决的属性路径令牌 */ volatile Object resolvedTokens; /** 解析出来的属性注入器 */ volatile Injector resolvedInjector; public PropertyDescriptor resolvedDescriptor; /** * 创建一个新的ropertyValue实例. * @param name 属性名称(不可以为<code>null</code>) * @param value 属性值(可以是类型转换之前的值) */ public PropertyValue(String name, Object value) { this.name = name; this.value = value; } public PropertyValue(PropertyValue original) { Assert.notNull(original, "Original must not be null"); this.name = original.getName(); this.value = original.getValue(); this.source = original.getSource(); this.converted = original.converted; this.convertedValue = original.convertedValue; this.conversionNecessary = original.conversionNecessary; this.resolvedTokens = original.resolvedTokens; this.resolvedInjector = original.resolvedInjector; this.resolvedDescriptor = original.resolvedDescriptor; copyAttributesFrom(original); } public PropertyValue(PropertyValue original, Object newValue) { Assert.notNull(original, "Original must not be null"); this.name = original.getName(); this.value = newValue; this.source = original; this.conversionNecessary = original.conversionNecessary; this.resolvedTokens = original.resolvedTokens; this.resolvedInjector = original.resolvedInjector; this.resolvedDescriptor = original.resolvedDescriptor; copyAttributesFrom(original); } /** * 返回属性的名称. */ public String getName() { return this.name; } /** * 返回属性的值 * <p>需要注意的是,调用此方法时还没有发生类型转换. * 类型转换的工作是BeanWrapper的实现类的职责,而非本类中进行. */ public Object getValue() { return this.value; } /** * 返回当前持有者的原始持有者. * @return 原始PropertyValue(要么是当前持有者的source要么是当前持有者自己). */ public PropertyValue getOriginalPropertyValue() { PropertyValue original = this; while (original.source instanceof PropertyValue && original.source != original) { original = (PropertyValue) original.source; } return original; } /** * 当前如果包含了转换之后的值,则返回(<code>true</code>); * 否则返回(<code>false</code>)代表还需要进行转换工作. */ public synchronized boolean isConverted() { return this.converted; } /** * 处理类型转换之后,设置该property转换之后的值 */ public synchronized void setConvertedValue(Object value) { this.converted = true; this.convertedValue = value; } /** * 处理类型转换之后,返回该property转换之后的值 */ public synchronized Object getConvertedValue() { return this.convertedValue; } @Override public boolean equals(Object other) { if (this == other) { return true; } if (!(other instanceof PropertyValue)) { return false; } PropertyValue otherPv = (PropertyValue) other; return (this.name.equals(otherPv.name) && ObjectUtils.nullSafeEquals(this.value, otherPv.value) && ObjectUtils.nullSafeEquals(this.source, otherPv.source)); } @Override public int hashCode() { return this.name.hashCode() * 29 + ObjectUtils.nullSafeHashCode(this.value); } @Override public String toString() { return "bean property '" + this.name + "'"; } }