diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/TypedStringValue.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/TypedStringValue.java index 0e60d9f9d3..587cab16f5 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/TypedStringValue.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/TypedStringValue.java @@ -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 { 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 { 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) { diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java index 4e0d9b6b54..d8527cf236 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java @@ -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 @@ 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; 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 { 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 { } /** - * 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 resolved = new ArrayList(ml.size()); @@ -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 resolved = new LinkedHashSet(ms.size()); @@ -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 resolved = new LinkedHashMap(mm.size()); diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 399f11a9a7..2155342a99 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -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 null if none found */ protected String determinePrimaryCandidate(Map candidateBeans, DependencyDescriptor descriptor) { diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedArray.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedArray.java new file mode 100644 index 0000000000..63492ea7f3 --- /dev/null +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedArray.java @@ -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 { + + /** 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); + } + +} diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedList.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedList.java index c95430fd63..682e2a9548 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedList.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedList.java @@ -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 extends ArrayList implements Mergeable, BeanMetad private Object source; + private String elementTypeName; + private boolean mergeEnabled; @@ -58,6 +60,20 @@ public class ManagedList extends ArrayList 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 extends ArrayList implements Mergeable, BeanMetad return this.mergeEnabled; } - public Object merge(Object parent) { + @SuppressWarnings("unchecked") + public List 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 extends ArrayList implements Mergeable, BeanMetad if (!(parent instanceof List)) { throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]"); } - List merged = new ManagedList(); + List merged = new ManagedList(); merged.addAll((List) parent); merged.addAll(this); return merged; diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedMap.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedMap.java index 5e9fd4571c..ccf1e1641d 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedMap.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedMap.java @@ -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 extends LinkedHashMap implements Mergeable, private Object source; + private String keyTypeName; + + private String valueTypeName; + private boolean mergeEnabled; @@ -57,6 +61,34 @@ public class ManagedMap extends LinkedHashMap 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 extends LinkedHashMap 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 extends LinkedHashMap implements Mergeable, if (!(parent instanceof Map)) { throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]"); } - Map merged = new ManagedMap(); + Map merged = new ManagedMap(); merged.putAll((Map) parent); merged.putAll(this); return merged; diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedSet.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedSet.java index e5ec0e0afb..70f53f05a8 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedSet.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedSet.java @@ -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 extends LinkedHashSet implements Mergeable, BeanMe private Object source; + private String elementTypeName; + private boolean mergeEnabled; @@ -57,6 +59,20 @@ public class ManagedSet extends LinkedHashSet 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 extends LinkedHashSet implements Mergeable, BeanMe return this.mergeEnabled; } - public Object merge(Object parent) { + @SuppressWarnings("unchecked") + public Set 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 extends LinkedHashSet implements Mergeable, BeanMe if (!(parent instanceof Set)) { throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]"); } - Set merged = new ManagedSet(); + Set merged = new ManagedSet(); merged.addAll((Set) parent); merged.addAll(this); return merged; diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java index 057b36a2c8..0e858e4680 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java @@ -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; 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; 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; 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; 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 { 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 { /** * 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 aliases, Element beanElement) { String foundName = null; if (StringUtils.hasText(beanName) && this.usedNames.contains(beanName)) { @@ -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; - } - else if (DEPENDENCY_CHECK_SIMPLE_ATTRIBUTE_VALUE.equals(att)) { - dependencyCheckCode = AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE; + return AbstractBeanDefinition.DEPENDENCY_CHECK_ALL; } else if (DEPENDENCY_CHECK_OBJECTS_ATTRIBUTE_VALUE.equals(att)) { - dependencyCheckCode = AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS; + return AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS; + } + else if (DEPENDENCY_CHECK_SIMPLE_ATTRIBUTE_VALUE.equals(att)) { + return AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE; + } + else { + return AbstractBeanDefinition.DEPENDENCY_CHECK_NONE; } - // Else leave default value. - return dependencyCheckCode; } /** @@ -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 * <value> 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 { 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 { 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 { /** * 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 element", ele, ex); + error("Type class [" + typeName + "] not found for element", ele, ex); return value; } } @@ -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 { 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 target = new ManagedList(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 target = new ManagedSet(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 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 entryEles = DomUtils.getChildElementsByTagName(mapEle, ENTRY_ELEMENT); - ManagedMap map = new ManagedMap(entryEles.size()); - map.setMergeEnabled(parseMergeAttribute(mapEle)); + ManagedMap map = new ManagedMap(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 { "a 'key' attribute OR a 'key-ref' attribute OR a 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 { key = ref; } else if (keyEle != null) { - key = parseKeyElement(keyEle, bd, defaultKeyTypeClassName); + key = parseKeyElement(keyEle, bd, defaultKeyType); } else { error(" element must specify a key", entryEle); @@ -1180,8 +1209,7 @@ public class BeanDefinitionParserDelegate { "'value' attribute OR 'value-ref' attribute OR 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 { value = ref; } else if (valueEle != null) { - value = parsePropertySubElement(valueEle, bd, defaultValueTypeClassName); + value = parsePropertySubElement(valueEle, bd, defaultValueType); } else { error(" element must specify a value", entryEle); @@ -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 { /** * 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 { } } } - return parsePropertySubElement(subElement, bd, defaultKeyTypeClassName); + return parsePropertySubElement(subElement, bd, defaultKeyTypeName); } /** diff --git a/org.springframework.beans/src/main/resources/META-INF/spring.schemas b/org.springframework.beans/src/main/resources/META-INF/spring.schemas index e17a59aec6..49efa335e8 100644 --- a/org.springframework.beans/src/main/resources/META-INF/spring.schemas +++ b/org.springframework.beans/src/main/resources/META-INF/spring.schemas @@ -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 diff --git a/org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-2.0.xsd b/org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-2.0.xsd index 60d002f563..3bceb75aac 100644 --- a/org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-2.0.xsd +++ b/org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-2.0.xsd @@ -78,7 +78,7 @@ /' element. + 'lazy-init' attribute of the '' element. ]]> @@ -94,7 +94,7 @@ /' element. + 'autowire' attribute of the '' element. ]]> @@ -111,7 +111,7 @@ /' element. + 'dependency-check' attribute of the '' element. ]]> @@ -127,7 +127,7 @@ /' element. + 'init-method' attribute of the '' element. ]]> @@ -135,7 +135,7 @@ /' element. + 'destroy-method' attribute of the '' element. ]]> @@ -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 diff --git a/org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-2.5.xsd b/org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-2.5.xsd index 769830c69d..eb01556e2e 100644 --- a/org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-2.5.xsd +++ b/org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-2.5.xsd @@ -78,7 +78,7 @@ /' element. + 'lazy-init' attribute of the '' element. ]]> @@ -94,7 +94,7 @@ /' element. + 'autowire' attribute of the '' element. ]]> @@ -111,7 +111,7 @@ /' element. + 'dependency-check' attribute of the '' element. ]]> @@ -138,7 +138,7 @@ /' element. + 'init-method' attribute of the '' element. ]]> @@ -146,7 +146,7 @@ /' element. + 'destroy-method' attribute of the '' element. ]]> @@ -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 diff --git a/org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-3.0.xsd b/org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-3.0.xsd new file mode 100644 index 0000000000..f5c5ff7d87 --- /dev/null +++ b/org.springframework.beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-3.0.xsd @@ -0,0 +1,1141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ' element. + ]]> + + + + + + + + + + ' element. + ]]> + + + + + + + + + + + + + ' element for the semantic details of autowire candidate beans. + ]]> + + + + + ' element. + ]]> + + + + + ' element. + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + element (or "ref" + attribute). We recommend this in most cases as it makes documentation + more explicit. + + Note that this default mode also allows for annotation-driven autowiring, + if activated. "no" refers to externally driven autowiring only, not + affecting any autowiring demands that the bean class itself expresses. + + 2. "byName" + 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. + + 3. "byType" + Autowiring if there is exactly one bean of the property type in the + container. If there is more than one, a fatal error is raised, and + you cannot use byType autowiring for that bean. If there is none, + nothing special happens. + + 4. "constructor" + Analogous to "byType" for constructor arguments. If there is not exactly + one bean of the constructor argument type in the bean factory, a fatal + error is raised. + + Note that explicit dependencies, i.e. "property" and "constructor-arg" + elements, always override autowiring. + + Note: This attribute will not be inherited by child bean definitions. + Hence, it needs to be specified per concrete bean definition. + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + " element. + ]]> + + + + + ..." element. + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ". + ]]> + + + + + ..." element. + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ". + ]]> + + + + + ..." + element. + ]]> + + + + + ". + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/CollectionsWithDefaultTypesTests.java b/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/CollectionsWithDefaultTypesTests.java index d4458a894c..0f3be3b006 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/CollectionsWithDefaultTypesTests.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/CollectionsWithDefaultTypesTests.java @@ -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); + } + } diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/XmlBeanCollectionTests.java b/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/XmlBeanCollectionTests.java index be56c3a7da..53dfea9073 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/XmlBeanCollectionTests.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/XmlBeanCollectionTests.java @@ -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 @@ 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; 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; 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; */ 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 { @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 { @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 { 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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { } } - diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/collections.xml b/org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/collections.xml similarity index 98% rename from org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/collections.xml rename to org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/collections.xml index d4b78b5c35..da5a046946 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/collections.xml +++ b/org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/collections.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> Jenny @@ -74,13 +74,17 @@ - + literal + + + literal2 + diff --git a/org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/collectionsWithDefaultTypes.xml b/org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/collectionsWithDefaultTypes.xml index a32de67715..7cd04cc145 100644 --- a/org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/collectionsWithDefaultTypes.xml +++ b/org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/collectionsWithDefaultTypes.xml @@ -1,8 +1,8 @@ - + - @@ -58,4 +58,21 @@ - \ No newline at end of file + + + + + literal + + 2 + 4 + + + 3 + 5 + + + + + + diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/factory-methods.xml b/org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/factory-methods.xml similarity index 100% rename from org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/factory-methods.xml rename to org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/factory-methods.xml