21
21
import java .util .Collections ;
22
22
import java .util .LinkedHashMap ;
23
23
import java .util .Map ;
24
+ import java .util .concurrent .ConcurrentHashMap ;
25
+ import java .util .regex .Pattern ;
24
26
25
27
import org .springframework .beans .MutablePropertyValues ;
26
28
import org .springframework .beans .PropertyValue ;
39
41
* used with the latter.
40
42
*
41
43
* @author Dave Syer
44
+ * @author Phillip Webb
42
45
*/
43
46
public class PropertySourcesPropertyValues implements PropertyValues {
44
47
45
- private final Map <String , PropertyValue > propertyValues = new LinkedHashMap <String , PropertyValue >();
46
-
47
- private final PropertySources propertySources ;
48
-
49
48
private static final Collection <String > PATTERN_MATCHED_PROPERTY_SOURCES = Arrays
50
49
.asList (StandardEnvironment .SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME ,
51
50
StandardEnvironment .SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME );
52
51
52
+ private static final Pattern COLLECTION_PROPERTY = Pattern .compile ("\\ [(\\ d+)\\ ]" );
53
+
54
+ private final PropertySources propertySources ;
55
+
56
+ private final Map <String , PropertyValue > propertyValues = new LinkedHashMap <String , PropertyValue >();
57
+
58
+ private final ConcurrentHashMap <String , PropertySource <?>> collectionOwners = new ConcurrentHashMap <String , PropertySource <?>>();
59
+
53
60
/**
54
61
* Create a new PropertyValues from the given PropertySources
55
62
* @param propertySources a PropertySources instance
@@ -122,10 +129,7 @@ private void processEnumerablePropertySource(EnumerablePropertySource<?> source,
122
129
continue ;
123
130
}
124
131
Object value = getEnumerableProperty (source , resolver , propertyName );
125
- if (!this .propertyValues .containsKey (propertyName )) {
126
- this .propertyValues .put (propertyName , new PropertyValue (propertyName ,
127
- value ));
128
- }
132
+ putIfAbsent (propertyName , value , source );
129
133
}
130
134
}
131
135
}
@@ -166,9 +170,7 @@ private void processDefaultPropertySource(PropertySource<?> source,
166
170
if (value == null ) {
167
171
value = source .getProperty (propertyName .toUpperCase ());
168
172
}
169
- if (value != null && !this .propertyValues .containsKey (propertyName )) {
170
- this .propertyValues .put (propertyName , new PropertyValue (propertyName ,
171
- value ));
173
+ if (putIfAbsent (propertyName , value , source ) != null ) {
172
174
continue ;
173
175
}
174
176
}
@@ -188,8 +190,22 @@ public PropertyValue getPropertyValue(String propertyName) {
188
190
}
189
191
for (PropertySource <?> source : this .propertySources ) {
190
192
Object value = source .getProperty (propertyName );
191
- if (value != null ) {
192
- propertyValue = new PropertyValue (propertyName , value );
193
+ propertyValue = putIfAbsent (propertyName , value , source );
194
+ if (propertyValue != null ) {
195
+ return propertyValue ;
196
+ }
197
+ }
198
+ return null ;
199
+ }
200
+
201
+ private PropertyValue putIfAbsent (String propertyName , Object value ,
202
+ PropertySource <?> source ) {
203
+ if (value != null && !this .propertyValues .containsKey (propertyName )) {
204
+ PropertySource <?> collectionOwner = this .collectionOwners .putIfAbsent (
205
+ COLLECTION_PROPERTY .matcher (propertyName ).replaceAll ("[]" ), source );
206
+ if (collectionOwner == null || collectionOwner == source ) {
207
+ this .collectionOwners .get (this .collectionOwners );
208
+ PropertyValue propertyValue = new PropertyValue (propertyName , value );
193
209
this .propertyValues .put (propertyName , propertyValue );
194
210
return propertyValue ;
195
211
}
0 commit comments