Skip to content

Commit 1b5812d

Browse files
committed
storing type information as specified (SPR-5556, SPR-5562); explicit XML array element in spring-beans-3.0.xsd (SPR-5543)
1 parent 5a561bc commit 1b5812d

File tree

17 files changed

+1567
-201
lines changed

17 files changed

+1567
-201
lines changed

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

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2008 the original author or authors.
2+
* Copyright 2002-2009 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -42,6 +42,8 @@ public class TypedStringValue implements BeanMetadataElement {
4242

4343
private Object source;
4444

45+
private String specifiedTypeName;
46+
4547

4648
/**
4749
* Create a new {@link TypedStringValue} for the given String value.
@@ -169,6 +171,20 @@ public Object getSource() {
169171
return this.source;
170172
}
171173

174+
/**
175+
* Set the type name as actually specified for this particular value, if any.
176+
*/
177+
public void setSpecifiedTypeName(String specifiedTypeName) {
178+
this.specifiedTypeName = specifiedTypeName;
179+
}
180+
181+
/**
182+
* Return the type name as actually specified for this particular value, if any.
183+
*/
184+
public String getSpecifiedTypeName() {
185+
return this.specifiedTypeName;
186+
}
187+
172188

173189
@Override
174190
public boolean equals(Object other) {

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

+45-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2008 the original author or authors.
2+
* Copyright 2002-2009 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.beans.factory.support;
1818

19+
import java.lang.reflect.Array;
1920
import java.util.ArrayList;
2021
import java.util.LinkedHashMap;
2122
import java.util.LinkedHashSet;
@@ -36,6 +37,8 @@
3637
import org.springframework.beans.factory.config.RuntimeBeanNameReference;
3738
import org.springframework.beans.factory.config.RuntimeBeanReference;
3839
import org.springframework.beans.factory.config.TypedStringValue;
40+
import org.springframework.util.ClassUtils;
41+
import org.springframework.util.StringUtils;
3942

4043
/**
4144
* Helper class for use in bean factory implementations,
@@ -121,6 +124,30 @@ else if (value instanceof BeanDefinition) {
121124
BeanDefinition bd = (BeanDefinition) value;
122125
return resolveInnerBean(argName, "(inner bean)", bd);
123126
}
127+
else if (value instanceof ManagedArray) {
128+
// May need to resolve contained runtime references.
129+
ManagedArray array = (ManagedArray) value;
130+
Class elementType = array.resolvedElementType;
131+
if (elementType == null) {
132+
String elementTypeName = array.getElementTypeName();
133+
if (StringUtils.hasText(elementTypeName)) {
134+
try {
135+
elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
136+
array.resolvedElementType = elementType;
137+
}
138+
catch (Throwable ex) {
139+
// Improve the message by showing the context.
140+
throw new BeanCreationException(
141+
this.beanDefinition.getResourceDescription(), this.beanName,
142+
"Error resolving array type for " + argName, ex);
143+
}
144+
}
145+
else {
146+
elementType = Object.class;
147+
}
148+
}
149+
return resolveManagedArray(argName, (List<?>) value, elementType);
150+
}
124151
else if (value instanceof ManagedList) {
125152
// May need to resolve contained runtime references.
126153
return resolveManagedList(argName, (List<?>) value);
@@ -292,7 +319,21 @@ private Object resolveReference(Object argName, RuntimeBeanReference ref) {
292319
}
293320

294321
/**
295-
* For each element in the ManagedList, resolve reference if necessary.
322+
* For each element in the managed array, resolve reference if necessary.
323+
*/
324+
private Object resolveManagedArray(Object argName, List<?> ml, Class elementType) {
325+
Object resolved = Array.newInstance(elementType, ml.size());
326+
for (int i = 0; i < ml.size(); i++) {
327+
Array.set(resolved, i,
328+
resolveValueIfNecessary(
329+
argName + " with key " + BeanWrapper.PROPERTY_KEY_PREFIX + i + BeanWrapper.PROPERTY_KEY_SUFFIX,
330+
ml.get(i)));
331+
}
332+
return resolved;
333+
}
334+
335+
/**
336+
* For each element in the managed list, resolve reference if necessary.
296337
*/
297338
private List resolveManagedList(Object argName, List<?> ml) {
298339
List<Object> resolved = new ArrayList<Object>(ml.size());
@@ -306,7 +347,7 @@ private List resolveManagedList(Object argName, List<?> ml) {
306347
}
307348

308349
/**
309-
* For each element in the ManagedList, resolve reference if necessary.
350+
* For each element in the managed set, resolve reference if necessary.
310351
*/
311352
private Set resolveManagedSet(Object argName, Set<?> ms) {
312353
Set<Object> resolved = new LinkedHashSet<Object>(ms.size());
@@ -320,7 +361,7 @@ private Set resolveManagedSet(Object argName, Set<?> ms) {
320361
}
321362

322363
/**
323-
* For each element in the ManagedMap, resolve reference if necessary.
364+
* For each element in the managed map, resolve reference if necessary.
324365
*/
325366
private Map resolveManagedMap(Object argName, Map<?, ?> mm) {
326367
Map<Object, Object> resolved = new LinkedHashMap<Object, Object>(mm.size());

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ protected Map<String, Object> findAutowireCandidates(
744744
* Determine the primary autowire candidate in the given set of beans.
745745
* @param candidateBeans a Map of candidate names and candidate instances
746746
* that match the required type, as returned by {@link #findAutowireCandidates}
747-
* @param type the required type
747+
* @param descriptor the target dependency to match against
748748
* @return the name of the primary candidate, or <code>null</code> if none found
749749
*/
750750
protected String determinePrimaryCandidate(Map<String, Object> candidateBeans, DependencyDescriptor descriptor) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2002-2009 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.beans.factory.support;
18+
19+
import org.springframework.util.Assert;
20+
21+
/**
22+
* Tag collection class used to hold managed array elements, which may
23+
* include runtime bean references (to be resolved into bean objects).
24+
*
25+
* @author Juergen Hoeller
26+
* @since 3.0
27+
*/
28+
public class ManagedArray extends ManagedList<Object> {
29+
30+
/** Resolved element type for runtime creation of the target array */
31+
volatile Class resolvedElementType;
32+
33+
34+
/**
35+
* Create a new managed array placeholder.
36+
* @param elementTypeName the target element type as a class name
37+
* @param size the size of the array
38+
*/
39+
public ManagedArray(String elementTypeName, int size) {
40+
super(size);
41+
Assert.notNull(elementTypeName, "elementTypeName must not be null");
42+
setElementTypeName(elementTypeName);
43+
}
44+
45+
}

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

+20-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2008 the original author or authors.
2+
* Copyright 2002-2009 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* 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
3535

3636
private Object source;
3737

38+
private String elementTypeName;
39+
3840
private boolean mergeEnabled;
3941

4042

@@ -58,6 +60,20 @@ public Object getSource() {
5860
return this.source;
5961
}
6062

63+
/**
64+
* Set the default element type name (class name) to be used for this list.
65+
*/
66+
public void setElementTypeName(String elementTypeName) {
67+
this.elementTypeName = elementTypeName;
68+
}
69+
70+
/**
71+
* Return the default element type name (class name) to be used for this list.
72+
*/
73+
public String getElementTypeName() {
74+
return this.elementTypeName;
75+
}
76+
6177
/**
6278
* Set whether merging should be enabled for this collection,
6379
* in case of a 'parent' collection value being present.
@@ -70,7 +86,8 @@ public boolean isMergeEnabled() {
7086
return this.mergeEnabled;
7187
}
7288

73-
public Object merge(Object parent) {
89+
@SuppressWarnings("unchecked")
90+
public List<E> merge(Object parent) {
7491
if (!this.mergeEnabled) {
7592
throw new IllegalStateException("Not allowed to merge when the 'mergeEnabled' property is set to 'false'");
7693
}
@@ -80,7 +97,7 @@ public Object merge(Object parent) {
8097
if (!(parent instanceof List)) {
8198
throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]");
8299
}
83-
List merged = new ManagedList();
100+
List<E> merged = new ManagedList<E>();
84101
merged.addAll((List) parent);
85102
merged.addAll(this);
86103
return merged;

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

+35-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2008 the original author or authors.
2+
* Copyright 2002-2009 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* 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,
3434

3535
private Object source;
3636

37+
private String keyTypeName;
38+
39+
private String valueTypeName;
40+
3741
private boolean mergeEnabled;
3842

3943

@@ -57,6 +61,34 @@ public Object getSource() {
5761
return this.source;
5862
}
5963

64+
/**
65+
* Set the default key type name (class name) to be used for this map.
66+
*/
67+
public void setKeyTypeName(String keyTypeName) {
68+
this.keyTypeName = keyTypeName;
69+
}
70+
71+
/**
72+
* Return the default key type name (class name) to be used for this map.
73+
*/
74+
public String getKeyTypeName() {
75+
return this.keyTypeName;
76+
}
77+
78+
/**
79+
* Set the default value type name (class name) to be used for this map.
80+
*/
81+
public void setValueTypeName(String valueTypeName) {
82+
this.valueTypeName = valueTypeName;
83+
}
84+
85+
/**
86+
* Return the default value type name (class name) to be used for this map.
87+
*/
88+
public String getValueTypeName() {
89+
return this.valueTypeName;
90+
}
91+
6092
/**
6193
* Set whether merging should be enabled for this collection,
6294
* in case of a 'parent' collection value being present.
@@ -69,6 +101,7 @@ public boolean isMergeEnabled() {
69101
return this.mergeEnabled;
70102
}
71103

104+
@SuppressWarnings("unchecked")
72105
public Object merge(Object parent) {
73106
if (!this.mergeEnabled) {
74107
throw new IllegalStateException("Not allowed to merge when the 'mergeEnabled' property is set to 'false'");
@@ -79,7 +112,7 @@ public Object merge(Object parent) {
79112
if (!(parent instanceof Map)) {
80113
throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]");
81114
}
82-
Map merged = new ManagedMap();
115+
Map<K, V> merged = new ManagedMap<K, V>();
83116
merged.putAll((Map) parent);
84117
merged.putAll(this);
85118
return merged;

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

+20-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2008 the original author or authors.
2+
* Copyright 2002-2009 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* 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
3434

3535
private Object source;
3636

37+
private String elementTypeName;
38+
3739
private boolean mergeEnabled;
3840

3941

@@ -57,6 +59,20 @@ public Object getSource() {
5759
return this.source;
5860
}
5961

62+
/**
63+
* Set the default element type name (class name) to be used for this set.
64+
*/
65+
public void setElementTypeName(String elementTypeName) {
66+
this.elementTypeName = elementTypeName;
67+
}
68+
69+
/**
70+
* Return the default element type name (class name) to be used for this set.
71+
*/
72+
public String getElementTypeName() {
73+
return this.elementTypeName;
74+
}
75+
6076
/**
6177
* Set whether merging should be enabled for this collection,
6278
* in case of a 'parent' collection value being present.
@@ -69,7 +85,8 @@ public boolean isMergeEnabled() {
6985
return this.mergeEnabled;
7086
}
7187

72-
public Object merge(Object parent) {
88+
@SuppressWarnings("unchecked")
89+
public Set<E> merge(Object parent) {
7390
if (!this.mergeEnabled) {
7491
throw new IllegalStateException("Not allowed to merge when the 'mergeEnabled' property is set to 'false'");
7592
}
@@ -79,7 +96,7 @@ public Object merge(Object parent) {
7996
if (!(parent instanceof Set)) {
8097
throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]");
8198
}
82-
Set merged = new ManagedSet();
99+
Set<E> merged = new ManagedSet<E>();
83100
merged.addAll((Set) parent);
84101
merged.addAll(this);
85102
return merged;

0 commit comments

Comments
 (0)