📄 constructorargumentvalues.java
字号:
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.config;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.Mergeable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
/**
* Holder for constructor argument values, typically as part of a bean definition.
*
* <p>Supports values for a specific index in the constructor argument list
* as well as for generic argument matches by type.
*
* @author Juergen Hoeller
* @since 09.11.2003
* @see BeanDefinition#getConstructorArgumentValues
*/
public class ConstructorArgumentValues {
private final Map indexedArgumentValues = new HashMap();
private final List genericArgumentValues = new LinkedList();
/**
* Create a new empty ConstructorArgumentValues object.
*/
public ConstructorArgumentValues() {
}
/**
* Deep copy constructor.
* @param original the ConstructorArgumentValues to copy
*/
public ConstructorArgumentValues(ConstructorArgumentValues original) {
addArgumentValues(original);
}
/**
* Copy all given argument values into this object, using separate holder
* instances to keep the values independent from the original object.
* <p>Note: Identical ValueHolder instances will only be registered once,
* to allow for merging and re-merging of argument value definitions. Distinct
* ValueHolder instances carrying the same content are of course allowed.
*/
public void addArgumentValues(ConstructorArgumentValues other) {
if (other != null) {
for (Iterator it = other.indexedArgumentValues.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
ValueHolder valueHolder = (ValueHolder) entry.getValue();
addOrMergeIndexedArgumentValue(entry.getKey(), valueHolder.copy());
}
for (Iterator it = other.genericArgumentValues.iterator(); it.hasNext();) {
ValueHolder valueHolder = (ValueHolder) it.next();
if (!this.genericArgumentValues.contains(valueHolder)) {
this.genericArgumentValues.add(valueHolder.copy());
}
}
}
}
/**
* Add argument value for the given index in the constructor argument list.
* @param index the index in the constructor argument list
* @param value the argument value
*/
public void addIndexedArgumentValue(int index, Object value) {
addIndexedArgumentValue(index, new ValueHolder(value));
}
/**
* Add argument value for the given index in the constructor argument list.
* @param index the index in the constructor argument list
* @param value the argument value
* @param type the type of the constructor argument
*/
public void addIndexedArgumentValue(int index, Object value, String type) {
addIndexedArgumentValue(index, new ValueHolder(value, type));
}
/**
* Add argument value for the given index in the constructor argument list.
* @param index the index in the constructor argument list
* @param newValue the argument value in the form of a ValueHolder
*/
public void addIndexedArgumentValue(int index, ValueHolder newValue) {
Assert.isTrue(index >= 0, "Index must not be negative");
Assert.notNull(newValue, "ValueHolder must not be null");
addOrMergeIndexedArgumentValue(new Integer(index), newValue);
}
/**
* Add argument value for the given index in the constructor argument list,
* merging the new value (typically a collection) with the current value
* if demanded: see {@link org.springframework.beans.Mergeable}.
* @param key the index in the constructor argument list
* @param newValue the argument value in the form of a ValueHolder
*/
private void addOrMergeIndexedArgumentValue(Object key, ValueHolder newValue) {
ValueHolder currentValue = (ValueHolder) this.indexedArgumentValues.get(key);
if (currentValue != null && newValue.getValue() instanceof Mergeable) {
Mergeable mergeable = (Mergeable) newValue.getValue();
if (mergeable.isMergeEnabled()) {
newValue.setValue(mergeable.merge(currentValue.getValue()));
}
}
this.indexedArgumentValues.put(key, newValue);
}
/**
* Get argument value for the given index in the constructor argument list.
* @param index the index in the constructor argument list
* @param requiredType the type to match (can be <code>null</code> to match
* untyped values only)
* @return the ValueHolder for the argument, or <code>null</code> if none set
*/
public ValueHolder getIndexedArgumentValue(int index, Class requiredType) {
Assert.isTrue(index >= 0, "Index must not be negative");
ValueHolder valueHolder = (ValueHolder) this.indexedArgumentValues.get(new Integer(index));
if (valueHolder != null) {
if (valueHolder.getType() == null ||
(requiredType != null && requiredType.getName().equals(valueHolder.getType()))) {
return valueHolder;
}
}
return null;
}
/**
* Return the map of indexed argument values.
* @return unmodifiable Map with Integer index as key and ValueHolder as value
* @see ValueHolder
*/
public Map getIndexedArgumentValues() {
return Collections.unmodifiableMap(this.indexedArgumentValues);
}
/**
* Add generic argument value to be matched by type.
* <p>Note: A single generic argument value will just be used once,
* rather than matched multiple times (as of Spring 1.1).
* @param value the argument value
*/
public void addGenericArgumentValue(Object value) {
this.genericArgumentValues.add(new ValueHolder(value));
}
/**
* Add generic argument value to be matched by type.
* <p>Note: A single generic argument value will just be used once,
* rather than matched multiple times (as of Spring 1.1).
* @param value the argument value
* @param type the type of the constructor argument
*/
public void addGenericArgumentValue(Object value, String type) {
this.genericArgumentValues.add(new ValueHolder(value, type));
}
/**
* Add generic argument value to be matched by type.
* <p>Note: A single generic argument value will just be used once,
* rather than matched multiple times (as of Spring 1.1).
* @param newValue the argument value in the form of a ValueHolder
* <p>Note: Identical ValueHolder instances will only be registered once,
* to allow for merging and re-merging of argument value definitions. Distinct
* ValueHolder instances carrying the same content are of course allowed.
*/
public void addGenericArgumentValue(ValueHolder newValue) {
Assert.notNull(newValue, "ValueHolder must not be null");
if (!this.genericArgumentValues.contains(newValue)) {
this.genericArgumentValues.add(newValue);
}
}
/**
* Look for a generic argument value that matches the given type.
* @param requiredType the type to match (can be <code>null</code> to find
* an arbitrary next generic argument value)
* @return the ValueHolder for the argument, or <code>null</code> if none set
*/
public ValueHolder getGenericArgumentValue(Class requiredType) {
return getGenericArgumentValue(requiredType, null);
}
/**
* Look for the next generic argument value that matches the given type,
* ignoring argument values that have already been used in the current
* resolution process.
* @param requiredType the type to match (can be <code>null</code> to find
* an arbitrary next generic argument value)
* @param usedValueHolders a Set of ValueHolder objects that have already been used
* in the current resolution process and should therefore not be returned again
* @return the ValueHolder for the argument, or <code>null</code> if none found
*/
public ValueHolder getGenericArgumentValue(Class requiredType, Set usedValueHolders) {
for (Iterator it = this.genericArgumentValues.iterator(); it.hasNext();) {
ValueHolder valueHolder = (ValueHolder) it.next();
if (usedValueHolders == null || !usedValueHolders.contains(valueHolder)) {
if (requiredType != null) {
// Check matching type.
if (valueHolder.getType() != null) {
if (valueHolder.getType().equals(requiredType.getName())) {
return valueHolder;
}
}
else if (ClassUtils.isAssignableValue(requiredType, valueHolder.getValue())) {
return valueHolder;
}
}
else {
// No required type specified -> consider untyped values only.
if (valueHolder.getType() == null) {
return valueHolder;
}
}
}
}
return null;
}
/**
* Return the list of generic argument values.
* @return unmodifiable List of ValueHolders
* @see ValueHolder
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -