2121import java .util .Collections ;
2222import java .util .LinkedHashMap ;
2323import java .util .Map ;
24+ import java .util .concurrent .ConcurrentHashMap ;
25+ import java .util .regex .Pattern ;
2426
2527import org .springframework .beans .MutablePropertyValues ;
2628import org .springframework .beans .PropertyValue ;
3941 * used with the latter.
4042 *
4143 * @author Dave Syer
44+ * @author Phillip Webb
4245 */
4346public class PropertySourcesPropertyValues implements PropertyValues {
4447
45- private final Map <String , PropertyValue > propertyValues = new LinkedHashMap <String , PropertyValue >();
46-
47- private final PropertySources propertySources ;
48-
4948 private static final Collection <String > PATTERN_MATCHED_PROPERTY_SOURCES = Arrays
5049 .asList (StandardEnvironment .SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME ,
5150 StandardEnvironment .SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME );
5251
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+
5360 /**
5461 * Create a new PropertyValues from the given PropertySources
5562 * @param propertySources a PropertySources instance
@@ -122,10 +129,7 @@ private void processEnumerablePropertySource(EnumerablePropertySource<?> source,
122129 continue ;
123130 }
124131 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 );
129133 }
130134 }
131135 }
@@ -166,9 +170,7 @@ private void processDefaultPropertySource(PropertySource<?> source,
166170 if (value == null ) {
167171 value = source .getProperty (propertyName .toUpperCase ());
168172 }
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 ) {
172174 continue ;
173175 }
174176 }
@@ -188,8 +190,22 @@ public PropertyValue getPropertyValue(String propertyName) {
188190 }
189191 for (PropertySource <?> source : this .propertySources ) {
190192 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 );
193209 this .propertyValues .put (propertyName , propertyValue );
194210 return propertyValue ;
195211 }
0 commit comments