package org.theonefx.wcframework.ioc.val;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.theonefx.wcframework.ioc.PropertyValue;
import org.theonefx.wcframework.ioc.PropertyValues;
import org.theonefx.wcframework.utils.StringUtils;
/**
* {@link PropertyValues}接口的默认实现.
* 允许properties的简单操作,同时提供构造函数从map构建以及深度拷贝的支持
*/
public class MutablePropertyValues implements PropertyValues, Serializable {
private static final long serialVersionUID = 1L;
private final List<PropertyValue> propertyValueList;
private volatile boolean converted = false;
/**
* 创建一个新的MutablePropertyValues.
* <p>可以通过<code>addPropertyValues</code>方法添加PropertyValue.
* @see #addPropertyValues(String, Object)
* @see {@link PropertyValue}
*/
public MutablePropertyValues() {
this.propertyValueList = new ArrayList<PropertyValue>(0);
}
/**
* 通过深度拷贝一个旧的MutablePropertyValues来创建一个新的MutablePropertyValues
* 保证 PropertyValue 的引用都是独立的,尽管他不能深度拷贝目前被个别PropertyValue对象引用的对象
* @param 原始PropertyValues,即以这个PropertyValues为模板创建一个新的MutablePropertyValues
* @see #addPropertyValues(PropertyValues)
*/
public MutablePropertyValues(PropertyValues original) {
if (original != null) {
PropertyValue[] pvs = original.getPropertyValues();
this.propertyValueList = new ArrayList<PropertyValue>(pvs.length);
for (PropertyValue pv : pvs) {
this.propertyValueList.add(new PropertyValue(pv));
}
} else {
this.propertyValueList = new ArrayList<PropertyValue>(0);
}
}
/**
* 从一个Map构建一个新的MutablePropertyValues对象
* @param original 存有属性名和属性值的键值对Map
* @see #addPropertyValues(Map)
*/
public MutablePropertyValues(Map<?, ?> original) {
if (original != null) {
this.propertyValueList = new ArrayList<PropertyValue>(original.size());
for (Map.Entry<?, ?> entry : original.entrySet()) {
this.propertyValueList.add(new PropertyValue(entry.getKey().toString(), entry.getValue()));
}
} else {
this.propertyValueList = new ArrayList<PropertyValue>(0);
}
}
/**
* 从一个包含了PropertyValue的列表中构建新的MutablePropertyValues
* <p>该方法应用于一些高级应用场景.
* 它不适合典型的开发使用.
*/
public MutablePropertyValues(List<PropertyValue> propertyValueList) {
this.propertyValueList = (propertyValueList != null ? propertyValueList : new ArrayList<PropertyValue>());
}
/**
* <p>这是访问所有PropertyValue的最优化的访问器.
* 它不适合典型的编程开发使用.
*/
public List<PropertyValue> getPropertyValueList() {
return this.propertyValueList;
}
/**
* 返回PropertyValues中PropertyValue的数量(在list中)
*/
public int size() {
return this.propertyValueList.size();
}
public MutablePropertyValues addPropertyValues(PropertyValues other) {
if (other != null) {
PropertyValue[] pvs = other.getPropertyValues();
for (PropertyValue pv : pvs) {
addPropertyValue(new PropertyValue(pv));
}
}
return this;
}
public MutablePropertyValues addPropertyValues(Map<?, ?> other) {
if (other != null) {
for (Map.Entry<?, ?> entry : other.entrySet()) {
addPropertyValue(new PropertyValue(entry.getKey().toString(), entry.getValue()));
}
}
return this;
}
/**
* 添加一个新的PropertyValue对象, 如果存在同名的PropertyValue,则先尝试合并,不过不能合并(mergeIfRequired)则替换原有PropertyValu.
*/
@Override
public MutablePropertyValues addPropertyValue(PropertyValue pv) {
for (int i = 0; i < this.propertyValueList.size(); i++) {
PropertyValue currentPv = this.propertyValueList.get(i);
if (currentPv.getName().equals(pv.getName())) {
pv = mergeIfRequired(pv, currentPv);
setPropertyValueAt(pv, i);
return this;
}
}
this.propertyValueList.add(pv);
return this;
}
@Override
public void addPropertyValue(String propertyName, Object propertyValue) {
addPropertyValue(new PropertyValue(propertyName, propertyValue));
}
public void setPropertyValueAt(PropertyValue pv, int i) {
this.propertyValueList.set(i, pv);
}
private PropertyValue mergeIfRequired(PropertyValue newPv, PropertyValue currentPv) {
Object value = newPv.getValue();
if (value instanceof Mergeable) {
Mergeable mergeable = (Mergeable) value;
if (mergeable.isMergeEnabled()) {
Object merged = mergeable.merge(currentPv.getValue());
return new PropertyValue(newPv.getName(), merged);
}
}
return newPv;
}
public void removePropertyValue(PropertyValue pv) {
this.propertyValueList.remove(pv);
}
public void removePropertyValue(String propertyName) {
removePropertyValue(getPropertyValue(propertyName));
}
@Override
public PropertyValue[] getPropertyValues() {
return this.propertyValueList.toArray(new PropertyValue[this.propertyValueList.size()]);
}
@Override
public PropertyValue getPropertyValue(String propertyName) {
for (PropertyValue pv : this.propertyValueList) {
if (pv.getName().equals(propertyName)) {
return pv;
}
}
return null;
}
@Override
public boolean contains(String propertyName) {
return getPropertyValue(propertyName) != null;
}
@Override
public boolean isEmpty() {
return this.propertyValueList.isEmpty();
}
/**
* 将当前PropertyValues标记为只包含完成转换之后的值
* (也就是说,不再需要进行运行时的解析).
*/
public void setConverted() {
this.converted = true;
}
/**
* 返回当前PropertyValues是否只包含转换之后的值(<code>true</code>),
* 或者包含的PropertyValue依然需要被转换(<code>false</code>).
*/
public boolean isConverted() {
return this.converted;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof MutablePropertyValues)) {
return false;
}
MutablePropertyValues that = (MutablePropertyValues) other;
return this.propertyValueList.equals(that.propertyValueList);
}
@Override
public int hashCode() {
return this.propertyValueList.hashCode();
}
@Override
public String toString() {
PropertyValue[] pvs = getPropertyValues();
StringBuilder sb = new StringBuilder("PropertyValues: length=").append(pvs.length);
if (pvs.length > 0) {
sb.append("; ").append(StringUtils.arrayToDelimitedString(pvs, "; "));
}
return sb.toString();
}
}