Browse Source

storing type information as specified (SPR-5556, SPR-5562); explicit XML array element in spring-beans-3.0.xsd (SPR-5543)

conversation
Juergen Hoeller 16 years ago
parent
commit
1b5812da20
  1. 18
      org.springframework.beans/src/main/java/org/springframework/beans/factory/config/TypedStringValue.java
  2. 49
      org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java
  3. 2
      org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java
  4. 45
      org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedArray.java
  5. 23
      org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedList.java
  6. 37
      org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedMap.java
  7. 23
      org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedSet.java
  8. 150
      org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java
  9. 3
      org.springframework.beans/src/main/resources/META-INF/spring.schemas
  10. 12
      org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-2.0.xsd
  11. 12
      org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-2.5.xsd
  12. 1141
      org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-3.0.xsd
  13. 68
      org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/CollectionsWithDefaultTypesTests.java
  14. 152
      org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/XmlBeanCollectionTests.java
  15. 8
      org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/collections.xml
  16. 25
      org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/collectionsWithDefaultTypes.xml
  17. 0
      org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/factory-methods.xml

18
org.springframework.beans/src/main/java/org/springframework/beans/factory/config/TypedStringValue.java

@ -1,5 +1,5 @@ @@ -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.
@ -42,6 +42,8 @@ public class TypedStringValue implements BeanMetadataElement { @@ -42,6 +42,8 @@ public class TypedStringValue implements BeanMetadataElement {
private Object source;
private String specifiedTypeName;
/**
* Create a new {@link TypedStringValue} for the given String value.
@ -169,6 +171,20 @@ public class TypedStringValue implements BeanMetadataElement { @@ -169,6 +171,20 @@ public class TypedStringValue implements BeanMetadataElement {
return this.source;
}
/**
* Set the type name as actually specified for this particular value, if any.
*/
public void setSpecifiedTypeName(String specifiedTypeName) {
this.specifiedTypeName = specifiedTypeName;
}
/**
* Return the type name as actually specified for this particular value, if any.
*/
public String getSpecifiedTypeName() {
return this.specifiedTypeName;
}
@Override
public boolean equals(Object other) {

49
org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java

@ -1,5 +1,5 @@ @@ -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,6 +16,7 @@ @@ -16,6 +16,7 @@
package org.springframework.beans.factory.support;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@ -36,6 +37,8 @@ import org.springframework.beans.factory.config.BeanDefinitionHolder; @@ -36,6 +37,8 @@ import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.RuntimeBeanNameReference;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* Helper class for use in bean factory implementations,
@ -121,6 +124,30 @@ class BeanDefinitionValueResolver { @@ -121,6 +124,30 @@ class BeanDefinitionValueResolver {
BeanDefinition bd = (BeanDefinition) value;
return resolveInnerBean(argName, "(inner bean)", bd);
}
else if (value instanceof ManagedArray) {
// May need to resolve contained runtime references.
ManagedArray array = (ManagedArray) value;
Class elementType = array.resolvedElementType;
if (elementType == null) {
String elementTypeName = array.getElementTypeName();
if (StringUtils.hasText(elementTypeName)) {
try {
elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
array.resolvedElementType = elementType;
}
catch (Throwable ex) {
// Improve the message by showing the context.
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Error resolving array type for " + argName, ex);
}
}
else {
elementType = Object.class;
}
}
return resolveManagedArray(argName, (List<?>) value, elementType);
}
else if (value instanceof ManagedList) {
// May need to resolve contained runtime references.
return resolveManagedList(argName, (List<?>) value);
@ -292,7 +319,21 @@ class BeanDefinitionValueResolver { @@ -292,7 +319,21 @@ class BeanDefinitionValueResolver {
}
/**
* For each element in the ManagedList, resolve reference if necessary.
* For each element in the managed array, resolve reference if necessary.
*/
private Object resolveManagedArray(Object argName, List<?> ml, Class elementType) {
Object resolved = Array.newInstance(elementType, ml.size());
for (int i = 0; i < ml.size(); i++) {
Array.set(resolved, i,
resolveValueIfNecessary(
argName + " with key " + BeanWrapper.PROPERTY_KEY_PREFIX + i + BeanWrapper.PROPERTY_KEY_SUFFIX,
ml.get(i)));
}
return resolved;
}
/**
* For each element in the managed list, resolve reference if necessary.
*/
private List resolveManagedList(Object argName, List<?> ml) {
List<Object> resolved = new ArrayList<Object>(ml.size());
@ -306,7 +347,7 @@ class BeanDefinitionValueResolver { @@ -306,7 +347,7 @@ class BeanDefinitionValueResolver {
}
/**
* For each element in the ManagedList, resolve reference if necessary.
* For each element in the managed set, resolve reference if necessary.
*/
private Set resolveManagedSet(Object argName, Set<?> ms) {
Set<Object> resolved = new LinkedHashSet<Object>(ms.size());
@ -320,7 +361,7 @@ class BeanDefinitionValueResolver { @@ -320,7 +361,7 @@ class BeanDefinitionValueResolver {
}
/**
* For each element in the ManagedMap, resolve reference if necessary.
* For each element in the managed map, resolve reference if necessary.
*/
private Map resolveManagedMap(Object argName, Map<?, ?> mm) {
Map<Object, Object> resolved = new LinkedHashMap<Object, Object>(mm.size());

2
org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

@ -744,7 +744,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -744,7 +744,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
* Determine the primary autowire candidate in the given set of beans.
* @param candidateBeans a Map of candidate names and candidate instances
* that match the required type, as returned by {@link #findAutowireCandidates}
* @param type the required type
* @param descriptor the target dependency to match against
* @return the name of the primary candidate, or <code>null</code> if none found
*/
protected String determinePrimaryCandidate(Map<String, Object> candidateBeans, DependencyDescriptor descriptor) {

45
org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedArray.java

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
/*
* 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.
* 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.support;
import org.springframework.util.Assert;
/**
* Tag collection class used to hold managed array elements, which may
* include runtime bean references (to be resolved into bean objects).
*
* @author Juergen Hoeller
* @since 3.0
*/
public class ManagedArray extends ManagedList<Object> {
/** Resolved element type for runtime creation of the target array */
volatile Class resolvedElementType;
/**
* Create a new managed array placeholder.
* @param elementTypeName the target element type as a class name
* @param size the size of the array
*/
public ManagedArray(String elementTypeName, int size) {
super(size);
Assert.notNull(elementTypeName, "elementTypeName must not be null");
setElementTypeName(elementTypeName);
}
}

23
org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedList.java

@ -1,5 +1,5 @@ @@ -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.
@ -35,6 +35,8 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad @@ -35,6 +35,8 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad
private Object source;
private String elementTypeName;
private boolean mergeEnabled;
@ -58,6 +60,20 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad @@ -58,6 +60,20 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad
return this.source;
}
/**
* Set the default element type name (class name) to be used for this list.
*/
public void setElementTypeName(String elementTypeName) {
this.elementTypeName = elementTypeName;
}
/**
* Return the default element type name (class name) to be used for this list.
*/
public String getElementTypeName() {
return this.elementTypeName;
}
/**
* Set whether merging should be enabled for this collection,
* in case of a 'parent' collection value being present.
@ -70,7 +86,8 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad @@ -70,7 +86,8 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad
return this.mergeEnabled;
}
public Object merge(Object parent) {
@SuppressWarnings("unchecked")
public List<E> merge(Object parent) {
if (!this.mergeEnabled) {
throw new IllegalStateException("Not allowed to merge when the 'mergeEnabled' property is set to 'false'");
}
@ -80,7 +97,7 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad @@ -80,7 +97,7 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad
if (!(parent instanceof List)) {
throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]");
}
List merged = new ManagedList();
List<E> merged = new ManagedList<E>();
merged.addAll((List) parent);
merged.addAll(this);
return merged;

37
org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedMap.java

@ -1,5 +1,5 @@ @@ -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.
@ -34,6 +34,10 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable, @@ -34,6 +34,10 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable,
private Object source;
private String keyTypeName;
private String valueTypeName;
private boolean mergeEnabled;
@ -57,6 +61,34 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable, @@ -57,6 +61,34 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable,
return this.source;
}
/**
* Set the default key type name (class name) to be used for this map.
*/
public void setKeyTypeName(String keyTypeName) {
this.keyTypeName = keyTypeName;
}
/**
* Return the default key type name (class name) to be used for this map.
*/
public String getKeyTypeName() {
return this.keyTypeName;
}
/**
* Set the default value type name (class name) to be used for this map.
*/
public void setValueTypeName(String valueTypeName) {
this.valueTypeName = valueTypeName;
}
/**
* Return the default value type name (class name) to be used for this map.
*/
public String getValueTypeName() {
return this.valueTypeName;
}
/**
* Set whether merging should be enabled for this collection,
* in case of a 'parent' collection value being present.
@ -69,6 +101,7 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable, @@ -69,6 +101,7 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable,
return this.mergeEnabled;
}
@SuppressWarnings("unchecked")
public Object merge(Object parent) {
if (!this.mergeEnabled) {
throw new IllegalStateException("Not allowed to merge when the 'mergeEnabled' property is set to 'false'");
@ -79,7 +112,7 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable, @@ -79,7 +112,7 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable,
if (!(parent instanceof Map)) {
throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]");
}
Map merged = new ManagedMap();
Map<K, V> merged = new ManagedMap<K, V>();
merged.putAll((Map) parent);
merged.putAll(this);
return merged;

23
org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedSet.java

@ -1,5 +1,5 @@ @@ -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.
@ -34,6 +34,8 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe @@ -34,6 +34,8 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe
private Object source;
private String elementTypeName;
private boolean mergeEnabled;
@ -57,6 +59,20 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe @@ -57,6 +59,20 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe
return this.source;
}
/**
* Set the default element type name (class name) to be used for this set.
*/
public void setElementTypeName(String elementTypeName) {
this.elementTypeName = elementTypeName;
}
/**
* Return the default element type name (class name) to be used for this set.
*/
public String getElementTypeName() {
return this.elementTypeName;
}
/**
* Set whether merging should be enabled for this collection,
* in case of a 'parent' collection value being present.
@ -69,7 +85,8 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe @@ -69,7 +85,8 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe
return this.mergeEnabled;
}
public Object merge(Object parent) {
@SuppressWarnings("unchecked")
public Set<E> merge(Object parent) {
if (!this.mergeEnabled) {
throw new IllegalStateException("Not allowed to merge when the 'mergeEnabled' property is set to 'false'");
}
@ -79,7 +96,7 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe @@ -79,7 +96,7 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe
if (!(parent instanceof Set)) {
throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]");
}
Set merged = new ManagedSet();
Set<E> merged = new ManagedSet<E>();
merged.addAll((Set) parent);
merged.addAll(this);
return merged;

150
org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java

@ -1,5 +1,5 @@ @@ -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.
@ -18,6 +18,7 @@ package org.springframework.beans.factory.xml; @@ -18,6 +18,7 @@ package org.springframework.beans.factory.xml;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -26,6 +27,11 @@ import java.util.Set; @@ -26,6 +27,11 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.springframework.beans.BeanMetadataAttribute;
import org.springframework.beans.BeanMetadataAttributeAccessor;
import org.springframework.beans.PropertyValue;
@ -45,6 +51,7 @@ import org.springframework.beans.factory.support.AutowireCandidateQualifier; @@ -45,6 +51,7 @@ import org.springframework.beans.factory.support.AutowireCandidateQualifier;
import org.springframework.beans.factory.support.BeanDefinitionDefaults;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.LookupOverride;
import org.springframework.beans.factory.support.ManagedArray;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.support.ManagedProperties;
@ -58,10 +65,6 @@ import org.springframework.util.ObjectUtils; @@ -58,10 +65,6 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.PatternMatchUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Stateful delegate class used to parse XML bean definitions.
@ -185,6 +188,8 @@ public class BeanDefinitionParserDelegate { @@ -185,6 +188,8 @@ public class BeanDefinitionParserDelegate {
public static final String NULL_ELEMENT = "null";
public static final String ARRAY_ELEMENT = "array";
public static final String LIST_ELEMENT = "list";
public static final String SET_ELEMENT = "set";
@ -424,7 +429,7 @@ public class BeanDefinitionParserDelegate { @@ -424,7 +429,7 @@ public class BeanDefinitionParserDelegate {
/**
* Validate that the specified bean name and aliases have not been used already.
*/
protected void checkNameUniqueness(String beanName, List aliases, Element beanElement) {
protected void checkNameUniqueness(String beanName, List<String> aliases, Element beanElement) {
String foundName = null;
if (StringUtils.hasText(beanName) && this.usedNames.contains(beanName)) {
@ -651,18 +656,18 @@ public class BeanDefinitionParserDelegate { @@ -651,18 +656,18 @@ public class BeanDefinitionParserDelegate {
if (DEFAULT_VALUE.equals(att)) {
att = this.defaults.getDependencyCheck();
}
int dependencyCheckCode = AbstractBeanDefinition.DEPENDENCY_CHECK_NONE;
if (DEPENDENCY_CHECK_ALL_ATTRIBUTE_VALUE.equals(att)) {
dependencyCheckCode = AbstractBeanDefinition.DEPENDENCY_CHECK_ALL;
return AbstractBeanDefinition.DEPENDENCY_CHECK_ALL;
}
else if (DEPENDENCY_CHECK_OBJECTS_ATTRIBUTE_VALUE.equals(att)) {
return AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS;
}
else if (DEPENDENCY_CHECK_SIMPLE_ATTRIBUTE_VALUE.equals(att)) {
dependencyCheckCode = AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE;
return AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE;
}
else if (DEPENDENCY_CHECK_OBJECTS_ATTRIBUTE_VALUE.equals(att)) {
dependencyCheckCode = AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS;
else {
return AbstractBeanDefinition.DEPENDENCY_CHECK_NONE;
}
// Else leave default value.
return dependencyCheckCode;
}
/**
@ -928,10 +933,10 @@ public class BeanDefinitionParserDelegate { @@ -928,10 +933,10 @@ public class BeanDefinitionParserDelegate {
* Parse a value, ref or collection sub-element of a property or
* constructor-arg element.
* @param ele subelement of property element; we don't know which yet
* @param defaultTypeClassName the default type (class name) for any
* @param defaultValueType the default type (class name) for any
* <code>&lt;value&gt;</code> tag that might be created
*/
public Object parsePropertySubElement(Element ele, BeanDefinition bd, String defaultTypeClassName) {
public Object parsePropertySubElement(Element ele, BeanDefinition bd, String defaultValueType) {
if (!isDefaultNamespace(ele.getNamespaceURI())) {
return parseNestedCustomElement(ele, bd);
}
@ -971,7 +976,7 @@ public class BeanDefinitionParserDelegate { @@ -971,7 +976,7 @@ public class BeanDefinitionParserDelegate {
return parseIdRefElement(ele);
}
else if (DomUtils.nodeNameEquals(ele, VALUE_ELEMENT)) {
return parseValueElement(ele, defaultTypeClassName);
return parseValueElement(ele, defaultValueType);
}
else if (DomUtils.nodeNameEquals(ele, NULL_ELEMENT)) {
// It's a distinguished null value. Let's wrap it in a TypedStringValue
@ -980,6 +985,9 @@ public class BeanDefinitionParserDelegate { @@ -980,6 +985,9 @@ public class BeanDefinitionParserDelegate {
nullHolder.setSource(extractSource(ele));
return nullHolder;
}
else if (DomUtils.nodeNameEquals(ele, ARRAY_ELEMENT)) {
return parseArrayElement(ele, bd);
}
else if (DomUtils.nodeNameEquals(ele, LIST_ELEMENT)) {
return parseListElement(ele, bd);
}
@ -1024,18 +1032,22 @@ public class BeanDefinitionParserDelegate { @@ -1024,18 +1032,22 @@ public class BeanDefinitionParserDelegate {
/**
* Return a typed String value Object for the given value element.
*/
public Object parseValueElement(Element ele, String defaultTypeClassName) {
public Object parseValueElement(Element ele, String defaultTypeName) {
// It's a literal value.
String value = DomUtils.getTextValue(ele);
String typeClassName = ele.getAttribute(TYPE_ATTRIBUTE);
if (!StringUtils.hasText(typeClassName)) {
typeClassName = defaultTypeClassName;
String specifiedTypeName = ele.getAttribute(TYPE_ATTRIBUTE);
String typeName = specifiedTypeName;
if (!StringUtils.hasText(typeName)) {
typeName = defaultTypeName;
}
try {
return buildTypedStringValue(value, typeClassName, ele);
TypedStringValue typedValue = buildTypedStringValue(value, typeName);
typedValue.setSource(extractSource(ele));
typedValue.setSpecifiedTypeName(specifiedTypeName);
return typedValue;
}
catch (ClassNotFoundException ex) {
error("Type class [" + typeClassName + "] not found for <value> element", ele, ex);
error("Type class [" + typeName + "] not found for <value> element", ele, ex);
return value;
}
}
@ -1044,11 +1056,11 @@ public class BeanDefinitionParserDelegate { @@ -1044,11 +1056,11 @@ public class BeanDefinitionParserDelegate {
* Build a typed String value Object for the given raw value.
* @see org.springframework.beans.factory.config.TypedStringValue
*/
protected Object buildTypedStringValue(String value, String targetTypeName, Element ele)
protected TypedStringValue buildTypedStringValue(String value, String targetTypeName)
throws ClassNotFoundException {
ClassLoader classLoader = this.readerContext.getBeanClassLoader();
TypedStringValue typedValue = null;
TypedStringValue typedValue;
if (!StringUtils.hasText(targetTypeName)) {
typedValue = new TypedStringValue(value);
}
@ -1059,57 +1071,75 @@ public class BeanDefinitionParserDelegate { @@ -1059,57 +1071,75 @@ public class BeanDefinitionParserDelegate {
else {
typedValue = new TypedStringValue(value, targetTypeName);
}
typedValue.setSource(extractSource(ele));
return typedValue;
}
/**
* Parse an array element.
*/
public Object parseArrayElement(Element arrayEle, BeanDefinition bd) {
String elementType = arrayEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
NodeList nl = arrayEle.getChildNodes();
ManagedArray target = new ManagedArray(elementType, nl.getLength());
target.setSource(extractSource(arrayEle));
target.setElementTypeName(elementType);
target.setMergeEnabled(parseMergeAttribute(arrayEle));
parseCollectionElements(nl, target, bd, elementType);
return target;
}
/**
* Parse a list element.
*/
public List<?> parseListElement(Element collectionEle, BeanDefinition bd) {
String defaultTypeClassName = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
public List parseListElement(Element collectionEle, BeanDefinition bd) {
String defaultElementType = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
NodeList nl = collectionEle.getChildNodes();
ManagedList list = new ManagedList(nl.getLength());
list.setSource(extractSource(collectionEle));
list.setMergeEnabled(parseMergeAttribute(collectionEle));
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element && !DomUtils.nodeNameEquals(node, DESCRIPTION_ELEMENT)) {
list.add(parsePropertySubElement((Element) node, bd, defaultTypeClassName));
}
}
return list;
ManagedList<Object> target = new ManagedList<Object>(nl.getLength());
target.setSource(extractSource(collectionEle));
target.setElementTypeName(defaultElementType);
target.setMergeEnabled(parseMergeAttribute(collectionEle));
parseCollectionElements(nl, target, bd, defaultElementType);
return target;
}
/**
* Parse a set element.
*/
public Set parseSetElement(Element collectionEle, BeanDefinition bd) {
String defaultTypeClassName = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
String defaultElementType = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
NodeList nl = collectionEle.getChildNodes();
ManagedSet set = new ManagedSet(nl.getLength());
set.setSource(extractSource(collectionEle));
set.setMergeEnabled(parseMergeAttribute(collectionEle));
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
ManagedSet<Object> target = new ManagedSet<Object>(nl.getLength());
target.setSource(extractSource(collectionEle));
target.setElementTypeName(defaultElementType);
target.setMergeEnabled(parseMergeAttribute(collectionEle));
parseCollectionElements(nl, target, bd, defaultElementType);
return target;
}
protected void parseCollectionElements(
NodeList elementNodes, Collection<Object> target, BeanDefinition bd, String defaultElementType) {
for (int i = 0; i < elementNodes.getLength(); i++) {
Node node = elementNodes.item(i);
if (node instanceof Element && !DomUtils.nodeNameEquals(node, DESCRIPTION_ELEMENT)) {
set.add(parsePropertySubElement((Element) node, bd, defaultTypeClassName));
target.add(parsePropertySubElement((Element) node, bd, defaultElementType));
}
}
return set;
}
/**
* Parse a map element.
*/
public Map parseMapElement(Element mapEle, BeanDefinition bd) {
String defaultKeyTypeClassName = mapEle.getAttribute(KEY_TYPE_ATTRIBUTE);
String defaultValueTypeClassName = mapEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
String defaultKeyType = mapEle.getAttribute(KEY_TYPE_ATTRIBUTE);
String defaultValueType = mapEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
List<Element> entryEles = DomUtils.getChildElementsByTagName(mapEle, ENTRY_ELEMENT);
ManagedMap map = new ManagedMap(entryEles.size());
map.setMergeEnabled(parseMergeAttribute(mapEle));
ManagedMap<Object, Object> map = new ManagedMap<Object, Object>(entryEles.size());
map.setSource(extractSource(mapEle));
map.setKeyTypeName(defaultKeyType);
map.setValueTypeName(defaultValueType);
map.setMergeEnabled(parseMergeAttribute(mapEle));
for (Element entryEle : entryEles) {
// Should only have one value child element: ref, value, list, etc.
@ -1151,8 +1181,7 @@ public class BeanDefinitionParserDelegate { @@ -1151,8 +1181,7 @@ public class BeanDefinitionParserDelegate {
"a 'key' attribute OR a 'key-ref' attribute OR a <key> sub-element", entryEle);
}
if (hasKeyAttribute) {
key = buildTypedStringValueForMap(
entryEle.getAttribute(KEY_ATTRIBUTE), defaultKeyTypeClassName, entryEle);
key = buildTypedStringValueForMap(entryEle.getAttribute(KEY_ATTRIBUTE), defaultKeyType, entryEle);
}
else if (hasKeyRefAttribute) {
String refName = entryEle.getAttribute(KEY_REF_ATTRIBUTE);
@ -1164,7 +1193,7 @@ public class BeanDefinitionParserDelegate { @@ -1164,7 +1193,7 @@ public class BeanDefinitionParserDelegate {
key = ref;
}
else if (keyEle != null) {
key = parseKeyElement(keyEle, bd, defaultKeyTypeClassName);
key = parseKeyElement(keyEle, bd, defaultKeyType);
}
else {
error("<entry> element must specify a key", entryEle);
@ -1180,8 +1209,7 @@ public class BeanDefinitionParserDelegate { @@ -1180,8 +1209,7 @@ public class BeanDefinitionParserDelegate {
"'value' attribute OR 'value-ref' attribute OR <value> sub-element", entryEle);
}
if (hasValueAttribute) {
value = buildTypedStringValueForMap(
entryEle.getAttribute(VALUE_ATTRIBUTE), defaultValueTypeClassName, entryEle);
value = buildTypedStringValueForMap(entryEle.getAttribute(VALUE_ATTRIBUTE), defaultValueType, entryEle);
}
else if (hasValueRefAttribute) {
String refName = entryEle.getAttribute(VALUE_REF_ATTRIBUTE);
@ -1193,7 +1221,7 @@ public class BeanDefinitionParserDelegate { @@ -1193,7 +1221,7 @@ public class BeanDefinitionParserDelegate {
value = ref;
}
else if (valueEle != null) {
value = parsePropertySubElement(valueEle, bd, defaultValueTypeClassName);
value = parsePropertySubElement(valueEle, bd, defaultValueType);
}
else {
error("<entry> element must specify a value", entryEle);
@ -1210,12 +1238,14 @@ public class BeanDefinitionParserDelegate { @@ -1210,12 +1238,14 @@ public class BeanDefinitionParserDelegate {
* Build a typed String value Object for the given raw value.
* @see org.springframework.beans.factory.config.TypedStringValue
*/
protected final Object buildTypedStringValueForMap(String value, String defaultTypeClassName, Element entryEle) {
protected final Object buildTypedStringValueForMap(String value, String defaultTypeName, Element entryEle) {
try {
return buildTypedStringValue(value, defaultTypeClassName, entryEle);
TypedStringValue typedValue = buildTypedStringValue(value, defaultTypeName);
typedValue.setSource(extractSource(entryEle));
return typedValue;
}
catch (ClassNotFoundException ex) {
error("Type class [" + defaultTypeClassName + "] not found for Map key/value type", entryEle, ex);
error("Type class [" + defaultTypeName + "] not found for Map key/value type", entryEle, ex);
return value;
}
}
@ -1223,7 +1253,7 @@ public class BeanDefinitionParserDelegate { @@ -1223,7 +1253,7 @@ public class BeanDefinitionParserDelegate {
/**
* Parse a key sub-element of a map element.
*/
public Object parseKeyElement(Element keyEle, BeanDefinition bd, String defaultKeyTypeClassName) {
protected Object parseKeyElement(Element keyEle, BeanDefinition bd, String defaultKeyTypeName) {
NodeList nl = keyEle.getChildNodes();
Element subElement = null;
for (int i = 0; i < nl.getLength(); i++) {
@ -1238,7 +1268,7 @@ public class BeanDefinitionParserDelegate { @@ -1238,7 +1268,7 @@ public class BeanDefinitionParserDelegate {
}
}
}
return parsePropertySubElement(subElement, bd, defaultKeyTypeClassName);
return parsePropertySubElement(subElement, bd, defaultKeyTypeName);
}
/**

3
org.springframework.beans/src/main/resources/META-INF/spring.schemas

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
http\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd
http\://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd
http\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd
http\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.0.xsd=org/springframework/beans/factory/xml/spring-tool-2.0.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.5.xsd=org/springframework/beans/factory/xml/spring-tool-2.5.xsd
http\://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool-2.5.xsd

12
org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-2.0.xsd

@ -78,7 +78,7 @@ @@ -78,7 +78,7 @@
<xsd:annotation>
<xsd:documentation><![CDATA[
The default 'lazy-init' value; see the documentation for the
'lazy-init' attribute of the '<bean>/' element.
'lazy-init' attribute of the '<bean>' element.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@ -94,7 +94,7 @@ @@ -94,7 +94,7 @@
<xsd:annotation>
<xsd:documentation><![CDATA[
The default 'autowire' value; see the documentation for the
'autowire' attribute of the '<bean>/' element.
'autowire' attribute of the '<bean>' element.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
@ -111,7 +111,7 @@ @@ -111,7 +111,7 @@
<xsd:annotation>
<xsd:documentation><![CDATA[
The default 'dependency-check' value; see the documentation for the
'dependency-check' attribute of the '<bean>/' element.
'dependency-check' attribute of the '<bean>' element.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
@ -127,7 +127,7 @@ @@ -127,7 +127,7 @@
<xsd:annotation>
<xsd:documentation><![CDATA[
The default 'init-method' value; see the documentation for the
'init-method' attribute of the '<bean>/' element.
'init-method' attribute of the '<bean>' element.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@ -135,7 +135,7 @@ @@ -135,7 +135,7 @@
<xsd:annotation>
<xsd:documentation><![CDATA[
The default 'destroy-method' value; see the documentation for the
'destroy-method' attribute of the '<bean>/' element.
'destroy-method' attribute of the '<bean>' element.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@ -323,7 +323,7 @@ @@ -323,7 +323,7 @@
more explicit.
2. "byName"
Autowiring by property name. If a bean of class Cat exposes a dog
Autowiring by property name. If a bean of class Cat exposes a "dog"
property, Spring will try to set this to the value of the bean "dog"
in the current container. If there is no matching bean by name, nothing
special happens; use dependency-check="objects" to raise an error in

12
org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-2.5.xsd

@ -78,7 +78,7 @@ @@ -78,7 +78,7 @@
<xsd:annotation>
<xsd:documentation><![CDATA[
The default 'lazy-init' value; see the documentation for the
'lazy-init' attribute of the '<bean>/' element.
'lazy-init' attribute of the '<bean>' element.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@ -94,7 +94,7 @@ @@ -94,7 +94,7 @@
<xsd:annotation>
<xsd:documentation><![CDATA[
The default 'autowire' value; see the documentation for the
'autowire' attribute of the '<bean>/' element.
'autowire' attribute of the '<bean>' element.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
@ -111,7 +111,7 @@ @@ -111,7 +111,7 @@
<xsd:annotation>
<xsd:documentation><![CDATA[
The default 'dependency-check' value; see the documentation for the
'dependency-check' attribute of the '<bean>/' element.
'dependency-check' attribute of the '<bean>' element.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
@ -138,7 +138,7 @@ @@ -138,7 +138,7 @@
<xsd:annotation>
<xsd:documentation><![CDATA[
The default 'init-method' value; see the documentation for the
'init-method' attribute of the '<bean>/' element.
'init-method' attribute of the '<bean>' element.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@ -146,7 +146,7 @@ @@ -146,7 +146,7 @@
<xsd:annotation>
<xsd:documentation><![CDATA[
The default 'destroy-method' value; see the documentation for the
'destroy-method' attribute of the '<bean>/' element.
'destroy-method' attribute of the '<bean>' element.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@ -336,7 +336,7 @@ @@ -336,7 +336,7 @@
more explicit.
2. "byName"
Autowiring by property name. If a bean of class Cat exposes a dog
Autowiring by property name. If a bean of class Cat exposes a "dog"
property, Spring will try to set this to the value of the bean "dog"
in the current container. If there is no matching bean by name, nothing
special happens; use dependency-check="objects" to raise an error in

1141
org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-3.0.xsd

File diff suppressed because it is too large Load Diff

68
org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/CollectionsWithDefaultTypesTests.java

@ -1,60 +1,90 @@ @@ -1,60 +1,90 @@
/*
* 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.
* 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.xml;
import junit.framework.TestCase;
import org.springframework.core.io.ClassPathResource;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
import org.junit.Test;
import test.beans.TestBean;
import java.util.List;
import java.util.Set;
import java.util.Iterator;
import java.util.Map;
import org.springframework.core.io.ClassPathResource;
/**
* @author Rob Harrop
* @author Juergen Hoeller
*/
public class CollectionsWithDefaultTypesTests extends TestCase {
public class CollectionsWithDefaultTypesTests {
private XmlBeanFactory beanFactory;
private final XmlBeanFactory beanFactory;
protected void setUp() throws Exception {
public CollectionsWithDefaultTypesTests() {
this.beanFactory = new XmlBeanFactory(new ClassPathResource("collectionsWithDefaultTypes.xml", getClass()));
}
@Test
public void testListHasDefaultType() throws Exception {
TestBean bean = (TestBean) this.beanFactory.getBean("testBean");
List list = bean.getSomeList();
for (int i = 0; i < list.size(); i++) {
Object o = list.get(i);
for (Object o : bean.getSomeList()) {
assertEquals("Value type is incorrect", Integer.class, o.getClass());
}
}
@Test
public void testSetHasDefaultType() throws Exception {
TestBean bean = (TestBean) this.beanFactory.getBean("testBean");
Set set = bean.getSomeSet();
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object o = iterator.next();
for (Object o : bean.getSomeSet()) {
assertEquals("Value type is incorrect", Integer.class, o.getClass());
}
}
@Test
public void testMapHasDefaultKeyAndValueType() throws Exception {
TestBean bean = (TestBean) this.beanFactory.getBean("testBean");
assertMap(bean.getSomeMap());
}
@Test
public void testMapWithNestedElementsHasDefaultKeyAndValueType() throws Exception {
TestBean bean = (TestBean) this.beanFactory.getBean("testBean2");
assertMap(bean.getSomeMap());
}
private void assertMap(Map map) {
for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
private void assertMap(Map<?,?> map) {
for (Map.Entry entry : map.entrySet()) {
assertEquals("Key type is incorrect", Integer.class, entry.getKey().getClass());
assertEquals("Value type is incorrect", Boolean.class, entry.getValue().getClass());
}
}
@Test
public void testBuildCollectionFromMixtureOfReferencesAndValues() throws Exception {
MixedCollectionBean jumble = (MixedCollectionBean) this.beanFactory.getBean("jumble");
assertTrue("Expected 3 elements, not " + jumble.getJumble().size(),
jumble.getJumble().size() == 3);
List l = (List) jumble.getJumble();
assertTrue(l.get(0).equals("literal"));
Integer[] array1 = (Integer[]) l.get(1);
assertTrue(array1[0].equals(new Integer(2)));
assertTrue(array1[1].equals(new Integer(4)));
int[] array2 = (int[]) l.get(2);
assertTrue(array2[0] == 3);
assertTrue(array2[1] == 5);
}
}

152
org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/XmlBeanCollectionTests.java

@ -1,5 +1,5 @@ @@ -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.
@ -16,8 +16,6 @@ @@ -16,8 +16,6 @@
package org.springframework.beans.factory.xml;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
@ -30,7 +28,10 @@ import java.util.Set; @@ -30,7 +28,10 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import static org.junit.Assert.*;
import org.junit.Test;
import test.beans.TestBean;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.ListFactoryBean;
@ -38,8 +39,6 @@ import org.springframework.beans.factory.config.MapFactoryBean; @@ -38,8 +39,6 @@ import org.springframework.beans.factory.config.MapFactoryBean;
import org.springframework.beans.factory.config.SetFactoryBean;
import org.springframework.core.io.ClassPathResource;
import test.beans.TestBean;
/**
* Tests for collections in XML bean definitions.
*
@ -49,6 +48,12 @@ import test.beans.TestBean; @@ -49,6 +48,12 @@ import test.beans.TestBean;
*/
public class XmlBeanCollectionTests {
private final XmlBeanFactory beanFactory;
public XmlBeanCollectionTests() {
this.beanFactory = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
}
@Test
public void testCollectionFactoryDefaults() throws Exception {
ListFactoryBean listFactory = new ListFactoryBean();
@ -69,40 +74,35 @@ public class XmlBeanCollectionTests { @@ -69,40 +74,35 @@ public class XmlBeanCollectionTests {
@Test
public void testRefSubelement() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
//assertTrue("5 beans in reftypes, not " + xbf.getBeanDefinitionCount(), xbf.getBeanDefinitionCount() == 5);
TestBean jen = (TestBean) xbf.getBean("jenny");
TestBean dave = (TestBean) xbf.getBean("david");
//assertTrue("5 beans in reftypes, not " + this.beanFactory.getBeanDefinitionCount(), this.beanFactory.getBeanDefinitionCount() == 5);
TestBean jen = (TestBean) this.beanFactory.getBean("jenny");
TestBean dave = (TestBean) this.beanFactory.getBean("david");
assertTrue(jen.getSpouse() == dave);
}
@Test
public void testPropertyWithLiteralValueSubelement() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
TestBean verbose = (TestBean) xbf.getBean("verbose");
TestBean verbose = (TestBean) this.beanFactory.getBean("verbose");
assertTrue(verbose.getName().equals("verbose"));
}
@Test
public void testPropertyWithIdRefLocalAttrSubelement() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
TestBean verbose = (TestBean) xbf.getBean("verbose2");
TestBean verbose = (TestBean) this.beanFactory.getBean("verbose2");
assertTrue(verbose.getName().equals("verbose"));
}
@Test
public void testPropertyWithIdRefBeanAttrSubelement() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
TestBean verbose = (TestBean) xbf.getBean("verbose3");
TestBean verbose = (TestBean) this.beanFactory.getBean("verbose3");
assertTrue(verbose.getName().equals("verbose"));
}
@Test
public void testRefSubelementsBuildCollection() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
TestBean jen = (TestBean) xbf.getBean("jenny");
TestBean dave = (TestBean) xbf.getBean("david");
TestBean rod = (TestBean) xbf.getBean("rod");
TestBean jen = (TestBean) this.beanFactory.getBean("jenny");
TestBean dave = (TestBean) this.beanFactory.getBean("david");
TestBean rod = (TestBean) this.beanFactory.getBean("rod");
// Must be a list to support ordering
// Our bean doesn't modify the collection:
@ -117,11 +117,9 @@ public class XmlBeanCollectionTests { @@ -117,11 +117,9 @@ public class XmlBeanCollectionTests {
@Test
public void testRefSubelementsBuildCollectionWithPrototypes() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
TestBean jen = (TestBean) xbf.getBean("pJenny");
TestBean dave = (TestBean) xbf.getBean("pDavid");
TestBean rod = (TestBean) xbf.getBean("pRod");
TestBean jen = (TestBean) this.beanFactory.getBean("pJenny");
TestBean dave = (TestBean) this.beanFactory.getBean("pDavid");
TestBean rod = (TestBean) this.beanFactory.getBean("pRod");
Object[] friends = rod.getFriends().toArray();
assertTrue(friends.length == 2);
assertTrue("First friend must be jen, not " + friends[0],
@ -130,7 +128,7 @@ public class XmlBeanCollectionTests { @@ -130,7 +128,7 @@ public class XmlBeanCollectionTests {
assertTrue(friends[1].toString().equals(dave.toString()));
assertTrue("Dave not same instance", friends[1] != dave);
TestBean rod2 = (TestBean) xbf.getBean("pRod");
TestBean rod2 = (TestBean) this.beanFactory.getBean("pRod");
Object[] friends2 = rod2.getFriends().toArray();
assertTrue(friends2.length == 2);
assertTrue("First friend must be jen, not " + friends2[0],
@ -142,50 +140,48 @@ public class XmlBeanCollectionTests { @@ -142,50 +140,48 @@ public class XmlBeanCollectionTests {
@Test
public void testRefSubelementsBuildCollectionFromSingleElement() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
TestBean loner = (TestBean) xbf.getBean("loner");
TestBean dave = (TestBean) xbf.getBean("david");
TestBean loner = (TestBean) this.beanFactory.getBean("loner");
TestBean dave = (TestBean) this.beanFactory.getBean("david");
assertTrue(loner.getFriends().size() == 1);
assertTrue(loner.getFriends().contains(dave));
}
@Test
public void testBuildCollectionFromMixtureOfReferencesAndValues() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
MixedCollectionBean jumble = (MixedCollectionBean) xbf.getBean("jumble");
assertTrue("Expected 4 elements, not " + jumble.getJumble().size(),
jumble.getJumble().size() == 4);
MixedCollectionBean jumble = (MixedCollectionBean) this.beanFactory.getBean("jumble");
assertTrue("Expected 5 elements, not " + jumble.getJumble().size(),
jumble.getJumble().size() == 5);
List l = (List) jumble.getJumble();
assertTrue(l.get(0).equals(xbf.getBean("david")));
assertTrue(l.get(0).equals(this.beanFactory.getBean("david")));
assertTrue(l.get(1).equals("literal"));
assertTrue(l.get(2).equals(xbf.getBean("jenny")));
assertTrue(l.get(2).equals(this.beanFactory.getBean("jenny")));
assertTrue(l.get(3).equals("rod"));
Object[] array = (Object[]) l.get(4);
assertTrue(array[0].equals(this.beanFactory.getBean("david")));
assertTrue(array[1].equals("literal2"));
}
@Test
public void testInvalidBeanNameReference() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
try {
xbf.getBean("jumble2");
this.beanFactory.getBean("jumble2");
fail("Should have thrown BeanCreationException");
}
catch (BeanCreationException ex) {
assertTrue(ex.getCause() instanceof BeanDefinitionStoreException);
assertTrue(ex.getCause().getMessage().indexOf("rod2") != -1);
assertTrue(ex.getCause().getMessage().contains("rod2"));
}
}
@Test
public void testEmptyMap() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
HasMap hasMap = (HasMap) xbf.getBean("emptyMap");
HasMap hasMap = (HasMap) this.beanFactory.getBean("emptyMap");
assertTrue(hasMap.getMap().size() == 0);
}
@Test
public void testMapWithLiteralsOnly() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
HasMap hasMap = (HasMap) xbf.getBean("literalMap");
HasMap hasMap = (HasMap) this.beanFactory.getBean("literalMap");
assertTrue(hasMap.getMap().size() == 3);
assertTrue(hasMap.getMap().get("foo").equals("bar"));
assertTrue(hasMap.getMap().get("fi").equals("fum"));
@ -194,27 +190,24 @@ public class XmlBeanCollectionTests { @@ -194,27 +190,24 @@ public class XmlBeanCollectionTests {
@Test
public void testMapWithLiteralsAndReferences() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
HasMap hasMap = (HasMap) xbf.getBean("mixedMap");
HasMap hasMap = (HasMap) this.beanFactory.getBean("mixedMap");
assertTrue(hasMap.getMap().size() == 3);
assertTrue(hasMap.getMap().get("foo").equals(new Integer(10)));
TestBean jenny = (TestBean) xbf.getBean("jenny");
TestBean jenny = (TestBean) this.beanFactory.getBean("jenny");
assertTrue(hasMap.getMap().get("jenny") == jenny);
assertTrue(hasMap.getMap().get(new Integer(5)).equals("david"));
}
@Test
public void testMapWithLiteralsAndPrototypeReferences() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
TestBean jenny = (TestBean) xbf.getBean("pJenny");
HasMap hasMap = (HasMap) xbf.getBean("pMixedMap");
TestBean jenny = (TestBean) this.beanFactory.getBean("pJenny");
HasMap hasMap = (HasMap) this.beanFactory.getBean("pMixedMap");
assertTrue(hasMap.getMap().size() == 2);
assertTrue(hasMap.getMap().get("foo").equals("bar"));
assertTrue(hasMap.getMap().get("jenny").toString().equals(jenny.toString()));
assertTrue("Not same instance", hasMap.getMap().get("jenny") != jenny);
HasMap hasMap2 = (HasMap) xbf.getBean("pMixedMap");
HasMap hasMap2 = (HasMap) this.beanFactory.getBean("pMixedMap");
assertTrue(hasMap2.getMap().size() == 2);
assertTrue(hasMap2.getMap().get("foo").equals("bar"));
assertTrue(hasMap2.getMap().get("jenny").toString().equals(jenny.toString()));
@ -223,11 +216,10 @@ public class XmlBeanCollectionTests { @@ -223,11 +216,10 @@ public class XmlBeanCollectionTests {
@Test
public void testMapWithLiteralsReferencesAndList() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
HasMap hasMap = (HasMap) xbf.getBean("mixedMapWithList");
HasMap hasMap = (HasMap) this.beanFactory.getBean("mixedMapWithList");
assertTrue(hasMap.getMap().size() == 4);
assertTrue(hasMap.getMap().get(null).equals("bar"));
TestBean jenny = (TestBean) xbf.getBean("jenny");
TestBean jenny = (TestBean) this.beanFactory.getBean("jenny");
assertTrue(hasMap.getMap().get("jenny").equals(jenny));
// Check list
@ -263,18 +255,16 @@ public class XmlBeanCollectionTests { @@ -263,18 +255,16 @@ public class XmlBeanCollectionTests {
@Test
public void testEmptySet() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
HasMap hasMap = (HasMap) xbf.getBean("emptySet");
HasMap hasMap = (HasMap) this.beanFactory.getBean("emptySet");
assertTrue(hasMap.getSet().size() == 0);
}
@Test
public void testPopulatedSet() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
HasMap hasMap = (HasMap) xbf.getBean("set");
HasMap hasMap = (HasMap) this.beanFactory.getBean("set");
assertTrue(hasMap.getSet().size() == 3);
assertTrue(hasMap.getSet().contains("bar"));
TestBean jenny = (TestBean) xbf.getBean("jenny");
TestBean jenny = (TestBean) this.beanFactory.getBean("jenny");
assertTrue(hasMap.getSet().contains(jenny));
assertTrue(hasMap.getSet().contains(null));
Iterator it = hasMap.getSet().iterator();
@ -285,16 +275,14 @@ public class XmlBeanCollectionTests { @@ -285,16 +275,14 @@ public class XmlBeanCollectionTests {
@Test
public void testEmptyProps() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
HasMap hasMap = (HasMap) xbf.getBean("emptyProps");
HasMap hasMap = (HasMap) this.beanFactory.getBean("emptyProps");
assertTrue(hasMap.getProps().size() == 0);
assertEquals(hasMap.getProps().getClass(), Properties.class);
}
@Test
public void testPopulatedProps() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
HasMap hasMap = (HasMap) xbf.getBean("props");
HasMap hasMap = (HasMap) this.beanFactory.getBean("props");
assertTrue(hasMap.getProps().size() == 2);
assertTrue(hasMap.getProps().get("foo").equals("bar"));
assertTrue(hasMap.getProps().get("2").equals("TWO"));
@ -302,17 +290,15 @@ public class XmlBeanCollectionTests { @@ -302,17 +290,15 @@ public class XmlBeanCollectionTests {
@Test
public void testObjectArray() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
HasMap hasMap = (HasMap) xbf.getBean("objectArray");
HasMap hasMap = (HasMap) this.beanFactory.getBean("objectArray");
assertTrue(hasMap.getObjectArray().length == 2);
assertTrue(hasMap.getObjectArray()[0].equals("one"));
assertTrue(hasMap.getObjectArray()[1].equals(xbf.getBean("jenny")));
assertTrue(hasMap.getObjectArray()[1].equals(this.beanFactory.getBean("jenny")));
}
@Test
public void testClassArray() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
HasMap hasMap = (HasMap) xbf.getBean("classArray");
HasMap hasMap = (HasMap) this.beanFactory.getBean("classArray");
assertTrue(hasMap.getClassArray().length == 2);
assertTrue(hasMap.getClassArray()[0].equals(String.class));
assertTrue(hasMap.getClassArray()[1].equals(Exception.class));
@ -320,8 +306,7 @@ public class XmlBeanCollectionTests { @@ -320,8 +306,7 @@ public class XmlBeanCollectionTests {
@Test
public void testIntegerArray() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
HasMap hasMap = (HasMap) xbf.getBean("integerArray");
HasMap hasMap = (HasMap) this.beanFactory.getBean("integerArray");
assertTrue(hasMap.getIntegerArray().length == 3);
assertTrue(hasMap.getIntegerArray()[0].intValue() == 0);
assertTrue(hasMap.getIntegerArray()[1].intValue() == 1);
@ -330,14 +315,12 @@ public class XmlBeanCollectionTests { @@ -330,14 +315,12 @@ public class XmlBeanCollectionTests {
@Test
public void testProps() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
HasMap hasMap = (HasMap) xbf.getBean("props");
HasMap hasMap = (HasMap) this.beanFactory.getBean("props");
assertEquals(2, hasMap.getProps().size());
assertEquals("bar", hasMap.getProps().getProperty("foo"));
assertEquals("TWO", hasMap.getProps().getProperty("2"));
HasMap hasMap2 = (HasMap) xbf.getBean("propsViaMap");
HasMap hasMap2 = (HasMap) this.beanFactory.getBean("propsViaMap");
assertEquals(2, hasMap2.getProps().size());
assertEquals("bar", hasMap2.getProps().getProperty("foo"));
assertEquals("TWO", hasMap2.getProps().getProperty("2"));
@ -345,8 +328,7 @@ public class XmlBeanCollectionTests { @@ -345,8 +328,7 @@ public class XmlBeanCollectionTests {
@Test
public void testListFactory() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
List list = (List) xbf.getBean("listFactory");
List list = (List) this.beanFactory.getBean("listFactory");
assertTrue(list instanceof LinkedList);
assertTrue(list.size() == 2);
assertEquals("bar", list.get(0));
@ -355,8 +337,7 @@ public class XmlBeanCollectionTests { @@ -355,8 +337,7 @@ public class XmlBeanCollectionTests {
@Test
public void testPrototypeListFactory() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
List list = (List) xbf.getBean("pListFactory");
List list = (List) this.beanFactory.getBean("pListFactory");
assertTrue(list instanceof LinkedList);
assertTrue(list.size() == 2);
assertEquals("bar", list.get(0));
@ -365,8 +346,7 @@ public class XmlBeanCollectionTests { @@ -365,8 +346,7 @@ public class XmlBeanCollectionTests {
@Test
public void testSetFactory() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
Set set = (Set) xbf.getBean("setFactory");
Set set = (Set) this.beanFactory.getBean("setFactory");
assertTrue(set instanceof TreeSet);
assertTrue(set.size() == 2);
assertTrue(set.contains("bar"));
@ -375,8 +355,7 @@ public class XmlBeanCollectionTests { @@ -375,8 +355,7 @@ public class XmlBeanCollectionTests {
@Test
public void testPrototypeSetFactory() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
Set set = (Set) xbf.getBean("pSetFactory");
Set set = (Set) this.beanFactory.getBean("pSetFactory");
assertTrue(set instanceof TreeSet);
assertTrue(set.size() == 2);
assertTrue(set.contains("bar"));
@ -385,8 +364,7 @@ public class XmlBeanCollectionTests { @@ -385,8 +364,7 @@ public class XmlBeanCollectionTests {
@Test
public void testMapFactory() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
Map map = (Map) xbf.getBean("mapFactory");
Map map = (Map) this.beanFactory.getBean("mapFactory");
assertTrue(map instanceof TreeMap);
assertTrue(map.size() == 2);
assertEquals("bar", map.get("foo"));
@ -395,8 +373,7 @@ public class XmlBeanCollectionTests { @@ -395,8 +373,7 @@ public class XmlBeanCollectionTests {
@Test
public void testPrototypeMapFactory() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
Map map = (Map) xbf.getBean("pMapFactory");
Map map = (Map) this.beanFactory.getBean("pMapFactory");
assertTrue(map instanceof TreeMap);
assertTrue(map.size() == 2);
assertEquals("bar", map.get("foo"));
@ -405,8 +382,7 @@ public class XmlBeanCollectionTests { @@ -405,8 +382,7 @@ public class XmlBeanCollectionTests {
@Test
public void testChoiceBetweenSetAndMap() {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
MapAndSet sam = (MapAndSet) xbf.getBean("setAndMap");
MapAndSet sam = (MapAndSet) this.beanFactory.getBean("setAndMap");
assertTrue("Didn't choose constructor with Map argument", sam.getObject() instanceof Map);
Map map = (Map) sam.getObject();
assertEquals(3, map.size());
@ -417,8 +393,7 @@ public class XmlBeanCollectionTests { @@ -417,8 +393,7 @@ public class XmlBeanCollectionTests {
@Test
public void testEnumSetFactory() throws Exception {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("collections.xml", getClass()));
Set set = (Set) xbf.getBean("enumSetFactory");
Set set = (Set) this.beanFactory.getBean("enumSetFactory");
assertTrue(set.size() == 2);
assertTrue(set.contains("ONE"));
assertTrue(set.contains("TWO"));
@ -516,4 +491,3 @@ class HasMap { @@ -516,4 +491,3 @@ class HasMap {
}
}

8
org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/collections.xml → org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/collections.xml

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="jenny" class="test.beans.TestBean">
<property name="name"><value>Jenny</value></property>
@ -74,13 +74,17 @@ @@ -74,13 +74,17 @@
</property>
</bean>
<bean id="jumble" class="org.springframework.beans.factory.xml.MixedCollectionBean">
<bean id="jumble" class="org.springframework.beans.factory.xml.MixedCollectionBean">
<property name="jumble">
<list>
<ref local="david"/>
<value>literal</value>
<ref local="jenny"/>
<idref local="rod"/>
<array>
<ref local="david"/>
<value>literal2</value>
</array>
</list>
</property>
</bean>

25
org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/collectionsWithDefaultTypes.xml

@ -1,8 +1,8 @@ @@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<beans>
<bean id="testBean" class="test.beans.TestBean">
<property name="someList">
<list value-type="java.lang.Integer">
@ -58,4 +58,21 @@ @@ -58,4 +58,21 @@
</map>
</property>
</bean>
</beans>
<bean id="jumble" class="org.springframework.beans.factory.xml.MixedCollectionBean">
<property name="jumble">
<list value-type="java.lang.String">
<value>literal</value>
<array value-type="java.lang.Integer">
<value>2</value>
<value>4</value>
</array>
<array value-type="int">
<value>3</value>
<value>5</value>
</array>
</list>
</property>
</bean>
</beans>

0
org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/factory-methods.xml → org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/factory-methods.xml

Loading…
Cancel
Save