added chaining-capable "add" method to MutablePropertyValues

This commit is contained in:
Juergen Hoeller
2009-11-19 22:30:35 +00:00
parent a300aa19b6
commit 46cd083976
65 changed files with 572 additions and 545 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 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.
@@ -47,9 +47,8 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
/**
* Creates a new empty MutablePropertyValues object.
* Property values can be added with the <code>addPropertyValue</code> methods.
* @see #addPropertyValue(PropertyValue)
* @see #addPropertyValue(String, Object)
* <p>Property values can be added with the <code>add</code> method.
* @see #add(String, Object)
*/
public MutablePropertyValues() {
this.propertyValueList = new ArrayList<PropertyValue>();
@@ -119,13 +118,19 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
return this.propertyValueList;
}
/**
* Return the number of PropertyValue entries in the list.
*/
public int size() {
return this.propertyValueList.size();
}
/**
* Copy all given PropertyValues into this object. Guarantees PropertyValue
* references are independent, although it can't deep copy objects currently
* referenced by individual PropertyValue objects.
* @param other the PropertyValues to copy
* @return this object to allow creating objects, adding multiple PropertyValues
* in a single statement
* @return this in order to allow for adding multiple property values in a chain
*/
public MutablePropertyValues addPropertyValues(PropertyValues other) {
if (other != null) {
@@ -141,8 +146,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
* Add all property values from the given Map.
* @param other Map with property values keyed by property name,
* which must be a String
* @return this object to allow creating objects, adding multiple
* PropertyValues in a single statement
* @return this in order to allow for adding multiple property values in a chain
*/
public MutablePropertyValues addPropertyValues(Map<?, ?> other) {
if (other != null) {
@@ -154,11 +158,10 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
}
/**
* Add a PropertyValue object, replacing any existing one
* for the corresponding property.
* Add a PropertyValue object, replacing any existing one for the
* corresponding property or getting merged with it (if applicable).
* @param pv PropertyValue object to add
* @return this object to allow creating objects, adding multiple
* PropertyValues in a single statement
* @return this in order to allow for adding multiple property values in a chain
*/
public MutablePropertyValues addPropertyValue(PropertyValue pv) {
for (int i = 0; i < this.propertyValueList.size(); i++) {
@@ -179,11 +182,25 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
* @param propertyName name of the property
* @param propertyValue value of the property
* @see #addPropertyValue(PropertyValue)
* @deprecated as of Spring 3.0, in favor of the chaining-capable {@link #add}
*/
@Deprecated
public void addPropertyValue(String propertyName, Object propertyValue) {
addPropertyValue(new PropertyValue(propertyName, propertyValue));
}
/**
* Add a PropertyValue object, replacing any existing one for the
* corresponding property or getting merged with it (if applicable).
* @param propertyName name of the property
* @param propertyValue value of the property
* @return this in order to allow for adding multiple property values in a chain
*/
public MutablePropertyValues add(String propertyName, Object propertyValue) {
addPropertyValue(new PropertyValue(propertyName, propertyValue));
return this;
}
/**
* Modify a PropertyValue object held in this object.
* Indexed from 0.
@@ -209,15 +226,6 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
return newPv;
}
/**
* Overloaded version of <code>removePropertyValue</code> that takes a property name.
* @param propertyName name of the property
* @see #removePropertyValue(PropertyValue)
*/
public void removePropertyValue(String propertyName) {
removePropertyValue(getPropertyValue(propertyName));
}
/**
* Remove the given PropertyValue, if contained.
* @param pv the PropertyValue to remove
@@ -227,10 +235,12 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
}
/**
* Clear this holder, removing all PropertyValues.
* Overloaded version of <code>removePropertyValue</code> that takes a property name.
* @param propertyName name of the property
* @see #removePropertyValue(PropertyValue)
*/
public void clear() {
this.propertyValueList.clear();
public void removePropertyValue(String propertyName) {
this.propertyValueList.remove(getPropertyValue(propertyName));
}
@@ -247,34 +257,6 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
return null;
}
/**
* Register the specified property as "processed" in the sense
* of some processor calling the corresponding setter method
* outside of the PropertyValue(s) mechanism.
* <p>This will lead to <code>true</code> being returned from
* a {@link #contains} call for the specified property.
* @param propertyName the name of the property.
*/
public void registerProcessedProperty(String propertyName) {
if (this.processedProperties == null) {
this.processedProperties = new HashSet<String>();
}
this.processedProperties.add(propertyName);
}
public boolean contains(String propertyName) {
return (getPropertyValue(propertyName) != null ||
(this.processedProperties != null && this.processedProperties.contains(propertyName)));
}
public boolean isEmpty() {
return this.propertyValueList.isEmpty();
}
public int size() {
return this.propertyValueList.size();
}
public PropertyValues changesSince(PropertyValues old) {
MutablePropertyValues changes = new MutablePropertyValues();
if (old == this) {
@@ -296,6 +278,30 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
return changes;
}
public boolean contains(String propertyName) {
return (getPropertyValue(propertyName) != null ||
(this.processedProperties != null && this.processedProperties.contains(propertyName)));
}
public boolean isEmpty() {
return this.propertyValueList.isEmpty();
}
/**
* Register the specified property as "processed" in the sense
* of some processor calling the corresponding setter method
* outside of the PropertyValue(s) mechanism.
* <p>This will lead to <code>true</code> being returned from
* a {@link #contains} call for the specified property.
* @param propertyName the name of the property.
*/
public void registerProcessedProperty(String propertyName) {
if (this.processedProperties == null) {
this.processedProperties = new HashSet<String>();
}
this.processedProperties.add(propertyName);
}
/**
* Mark this holder as containing converted values only

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 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.
@@ -39,6 +39,16 @@ public interface PropertyValues {
*/
PropertyValue getPropertyValue(String propertyName);
/**
* Return the changes since the previous PropertyValues.
* Subclasses should also override <code>equals</code>.
* @param old old property values
* @return PropertyValues updated or new properties.
* Return empty PropertyValues if there are no changes.
* @see java.lang.Object#equals
*/
PropertyValues changesSince(PropertyValues old);
/**
* Is there a property value (or other processing entry) for this property?
* @param propertyName the name of the property we're interested in
@@ -51,14 +61,4 @@ public interface PropertyValues {
*/
boolean isEmpty();
/**
* Return the changes since the previous PropertyValues.
* Subclasses should also override <code>equals</code>.
* @param old old property values
* @return PropertyValues updated or new properties.
* Return empty PropertyValues if there are no changes.
* @see java.lang.Object#equals
*/
PropertyValues changesSince(PropertyValues old);
}

View File

@@ -139,7 +139,7 @@ public class BeanDefinitionVisitor {
for (PropertyValue pv : pvArray) {
Object newVal = resolveValue(pv.getValue());
if (!ObjectUtils.nullSafeEquals(newVal, pv.getValue())) {
pvs.addPropertyValue(pv.getName(), newVal);
pvs.add(pv.getName(), newVal);
}
}
}

View File

@@ -99,12 +99,14 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* <i>load-time weaving</i> is involved, to make sure that actual bean
* classes are loaded as lazily as possible. The temporary loader is
* then removed once the BeanFactory completes its bootstrap phase.
* @since 2.5
*/
void setTempClassLoader(ClassLoader tempClassLoader);
/**
* Return the temporary ClassLoader to use for type matching purposes,
* if any.
* @since 2.5
*/
ClassLoader getTempClassLoader();
@@ -128,22 +130,26 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* <p>There is no expression support active in a BeanFactory by default.
* An ApplicationContext will typically set a standard expression strategy
* here, supporting "#{...}" expressions in a Unified EL compatible style.
* @since 3.0
*/
void setBeanExpressionResolver(BeanExpressionResolver resolver);
/**
* Return the resolution strategy for expressions in bean definition values.
* @since 3.0
*/
BeanExpressionResolver getBeanExpressionResolver();
/**
* Specify a Spring 3.0 ConversionService to use for converting
* property values, as an alternative to JavaBeans PropertyEditors.
* @since 3.0
*/
void setConversionService(ConversionService conversionService);
/**
* Return the associated ConversionService, if any.
* @since 3.0
*/
ConversionService getConversionService();
@@ -183,6 +189,7 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* any custom editors or custom editor registrars irrelevant.
* @see #addPropertyEditorRegistrar
* @see #registerCustomEditor
* @since 2.5
*/
void setTypeConverter(TypeConverter typeConverter);
@@ -191,12 +198,14 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* instance for each call, since TypeConverters are usually <i>not</i> thread-safe.
* <p>If the default PropertyEditor mechanism is active, the returned
* TypeConverter will be aware of all custom editors that have been registered.
* @since 2.5
*/
TypeConverter getTypeConverter();
/**
* Add a String resolver for embedded values such as annotation attributes.
* @param valueResolver the String resolver to apply to embedded values
* @since 3.0
*/
void addEmbeddedValueResolver(StringValueResolver valueResolver);
@@ -204,6 +213,7 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* Resolve the given embedded value, e.g. an annotation attribute.
* @param value the value to resolve
* @return the resolved value (may be the original value as-is)
* @since 3.0
*/
String resolveEmbeddedValue(String value);
@@ -253,6 +263,7 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
/**
* Provides a security access control context relevant to this factory.
* @return the applicable AccessControlContext (never <code>null</code>)
* @since 3.0
*/
AccessControlContext getAccessControlContext();
@@ -284,6 +295,7 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* <p>The value resolver may for example resolve placeholders
* in target bean names and even in alias names.
* @param valueResolver the StringValueResolver to apply
* @since 2.5
*/
void resolveAliases(StringValueResolver valueResolver);
@@ -294,6 +306,7 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* @param beanName the name of the bean to retrieve the merged definition for
* @return a (potentially merged) BeanDefinition for the given bean
* @throws NoSuchBeanDefinitionException if there is no bean definition with the given name
* @since 2.5
*/
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
@@ -303,6 +316,7 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* @return whether the bean is a FactoryBean
* (<code>false</code> means the bean exists but is not a FactoryBean)
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 2.5
*/
boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;
@@ -310,6 +324,7 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* Determine whether the specified bean is currently in creation.
* @param beanName the name of the bean
* @return whether the bean is currently in creation
* @since 2.5
*/
boolean isCurrentlyInCreation(String beanName);
@@ -318,6 +333,7 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* to be destroyed before the given bean is destroyed.
* @param beanName the name of the bean
* @param dependentBeanName the name of the dependent bean
* @since 2.5
*/
void registerDependentBean(String beanName, String dependentBeanName);
@@ -325,6 +341,7 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* Return the names of all beans which depend on the specified bean, if any.
* @param beanName the name of the bean
* @return the array of dependent bean names, or an empty array if none
* @since 2.5
*/
String[] getDependentBeans(String beanName);
@@ -333,6 +350,7 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* @param beanName the name of the bean
* @return the array of names of beans which the bean depends on,
* or an empty array if none
* @since 2.5
*/
String[] getDependenciesForBean(String beanName);

View File

@@ -1083,7 +1083,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
Object bean = getBean(propertyName);
pvs.addPropertyValue(propertyName, bean);
pvs.add(propertyName, bean);
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled()) {
logger.debug(
@@ -1131,7 +1131,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.addPropertyValue(propertyName, autowiredArgument);
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 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.
@@ -16,7 +16,6 @@
package org.springframework.beans.factory.support;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.util.ObjectUtils;
@@ -194,7 +193,8 @@ public class BeanDefinitionBuilder {
* and all additions are at the present point.
*/
public BeanDefinitionBuilder addConstructorArgValue(Object value) {
this.beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(this.constructorArgIndex++, value);
this.beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(
this.constructorArgIndex++, value);
return this;
}
@@ -203,14 +203,16 @@ public class BeanDefinitionBuilder {
* @see #addConstructorArgValue(Object)
*/
public BeanDefinitionBuilder addConstructorArgReference(String beanName) {
return addConstructorArgValue(new RuntimeBeanReference(beanName));
this.beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(
this.constructorArgIndex++, new RuntimeBeanReference(beanName));
return this;
}
/**
* Add the supplied property value under the given name.
*/
public BeanDefinitionBuilder addPropertyValue(String name, Object value) {
this.beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue(name, value));
this.beanDefinition.getPropertyValues().add(name, value);
return this;
}
@@ -220,7 +222,8 @@ public class BeanDefinitionBuilder {
* @param beanName the name of the bean being referenced
*/
public BeanDefinitionBuilder addPropertyReference(String name, String beanName) {
return addPropertyValue(name, new RuntimeBeanReference(beanName));
this.beanDefinition.getPropertyValues().add(name, new RuntimeBeanReference(beanName));
return this;
}
/**

View File

@@ -459,11 +459,11 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader
// It doesn't matter if the referenced bean hasn't yet been registered:
// this will ensure that the reference is resolved at runtime.
Object val = new RuntimeBeanReference(ref);
pvs.addPropertyValue(property, val);
pvs.add(property, val);
}
else {
// It's a normal bean property.
pvs.addPropertyValue(property, readValue(entry));
pvs.add(property, readValue(entry));
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2007 the original author or authors.
* Copyright 2002-2009 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.
@@ -44,7 +44,7 @@ public final class ParserContext {
private BeanDefinition containingBeanDefinition;
private final Stack containingComponents = new Stack();
private final Stack<ComponentDefinition> containingComponents = new Stack<ComponentDefinition>();
public ParserContext(XmlReaderContext readerContext, BeanDefinitionParserDelegate delegate) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2007 the original author or authors.
* Copyright 2002-2009 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.
@@ -44,6 +44,7 @@ import org.springframework.core.Conventions;
* be injected into that property.
*
* @author Rob Harrop
* @author Juergen Hoeller
* @since 2.0
*/
public class SimplePropertyNamespaceHandler implements NamespaceHandler {
@@ -72,11 +73,10 @@ public class SimplePropertyNamespaceHandler implements NamespaceHandler {
}
if (propertyName.endsWith(REF_SUFFIX)) {
propertyName = propertyName.substring(0, propertyName.length() - REF_SUFFIX.length());
pvs.addPropertyValue(
Conventions.attributeNameToPropertyName(propertyName), new RuntimeBeanReference(propertyValue));
pvs.add(Conventions.attributeNameToPropertyName(propertyName), new RuntimeBeanReference(propertyValue));
}
else {
pvs.addPropertyValue(Conventions.attributeNameToPropertyName(propertyName), propertyValue);
pvs.add(Conventions.attributeNameToPropertyName(propertyName), propertyValue);
}
}
return definition;