1
1
/*
2
- * Copyright 2012-2024 the original author or authors.
2
+ * Copyright 2012-2025 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
@@ -55,7 +55,7 @@ class SpringIterableConfigurationPropertySource extends SpringConfigurationPrope
55
55
56
56
private final BiPredicate <ConfigurationPropertyName , ConfigurationPropertyName > ancestorOfCheck ;
57
57
58
- private final SoftReferenceConfigurationPropertyCache <Mappings > cache ;
58
+ private final SoftReferenceConfigurationPropertyCache <Cache > cache ;
59
59
60
60
private volatile ConfigurationPropertyName [] configurationPropertyNames ;
61
61
@@ -101,7 +101,7 @@ public ConfigurationProperty getConfigurationProperty(ConfigurationPropertyName
101
101
if (configurationProperty != null ) {
102
102
return configurationProperty ;
103
103
}
104
- for (String candidate : getMappings ().getMapped (name )) {
104
+ for (String candidate : getCache ().getMapped (name )) {
105
105
Object value = getPropertySource ().getProperty (candidate );
106
106
if (value != null ) {
107
107
Origin origin = PropertySourceOrigin .get (getPropertySource (), candidate );
@@ -129,7 +129,7 @@ public ConfigurationPropertyState containsDescendantOf(ConfigurationPropertyName
129
129
return result ;
130
130
}
131
131
if (this .ancestorOfCheck == PropertyMapper .DEFAULT_ANCESTOR_OF_CHECK ) {
132
- return getMappings ().containsDescendantOf (name , this .ancestorOfCheck );
132
+ return getCache ().containsDescendantOf (name , this .ancestorOfCheck );
133
133
}
134
134
ConfigurationPropertyName [] candidates = getConfigurationPropertyNames ();
135
135
for (ConfigurationPropertyName candidate : candidates ) {
@@ -142,29 +142,29 @@ public ConfigurationPropertyState containsDescendantOf(ConfigurationPropertyName
142
142
143
143
private ConfigurationPropertyName [] getConfigurationPropertyNames () {
144
144
if (!isImmutablePropertySource ()) {
145
- return getMappings ().getConfigurationPropertyNames (getPropertySource ().getPropertyNames ());
145
+ return getCache ().getConfigurationPropertyNames (getPropertySource ().getPropertyNames ());
146
146
}
147
147
ConfigurationPropertyName [] configurationPropertyNames = this .configurationPropertyNames ;
148
148
if (configurationPropertyNames == null ) {
149
- configurationPropertyNames = getMappings ()
149
+ configurationPropertyNames = getCache ()
150
150
.getConfigurationPropertyNames (getPropertySource ().getPropertyNames ());
151
151
this .configurationPropertyNames = configurationPropertyNames ;
152
152
}
153
153
return configurationPropertyNames ;
154
154
}
155
155
156
- private Mappings getMappings () {
157
- return this .cache .get (this ::createMappings , this ::updateMappings );
156
+ private Cache getCache () {
157
+ return this .cache .get (this ::createCache , this ::updateCache );
158
158
}
159
159
160
- private Mappings createMappings () {
161
- return new Mappings (getMappers (), isImmutablePropertySource (),
160
+ private Cache createCache () {
161
+ return new Cache (getMappers (), isImmutablePropertySource (),
162
162
this .ancestorOfCheck == PropertyMapper .DEFAULT_ANCESTOR_OF_CHECK );
163
163
}
164
164
165
- private Mappings updateMappings ( Mappings mappings ) {
166
- mappings . updateMappings (getPropertySource ()::getPropertyNames );
167
- return mappings ;
165
+ private Cache updateCache ( Cache cache ) {
166
+ cache . update (getPropertySource ()::getPropertyNames );
167
+ return cache ;
168
168
}
169
169
170
170
private boolean isImmutablePropertySource () {
@@ -183,38 +183,30 @@ protected EnumerablePropertySource<?> getPropertySource() {
183
183
return (EnumerablePropertySource <?>) super .getPropertySource ();
184
184
}
185
185
186
- private static class Mappings {
186
+ private static class Cache {
187
187
188
188
private static final ConfigurationPropertyName [] EMPTY_NAMES_ARRAY = {};
189
189
190
190
private final PropertyMapper [] mappers ;
191
191
192
192
private final boolean immutable ;
193
193
194
- private final boolean trackDescendants ;
194
+ private final boolean captureDescendants ;
195
195
196
- private volatile Map < ConfigurationPropertyName , Set < String >> mappings ;
196
+ private volatile Data data ;
197
197
198
- private volatile Map <String , ConfigurationPropertyName > reverseMappings ;
199
-
200
- private volatile Map <ConfigurationPropertyName , Set <ConfigurationPropertyName >> descendants ;
201
-
202
- private volatile ConfigurationPropertyName [] configurationPropertyNames ;
203
-
204
- private volatile String [] lastUpdated ;
205
-
206
- Mappings (PropertyMapper [] mappers , boolean immutable , boolean trackDescendants ) {
198
+ Cache (PropertyMapper [] mappers , boolean immutable , boolean captureDescendants ) {
207
199
this .mappers = mappers ;
208
200
this .immutable = immutable ;
209
- this .trackDescendants = trackDescendants ;
201
+ this .captureDescendants = captureDescendants ;
210
202
}
211
203
212
- void updateMappings (Supplier <String []> propertyNames ) {
213
- if (this .mappings == null || !this .immutable ) {
204
+ void update (Supplier <String []> propertyNames ) {
205
+ if (this .data == null || !this .immutable ) {
214
206
int count = 0 ;
215
207
while (true ) {
216
208
try {
217
- updateMappings (propertyNames .get ());
209
+ tryUpdate (propertyNames .get ());
218
210
return ;
219
211
}
220
212
catch (ConcurrentModificationException ex ) {
@@ -226,36 +218,37 @@ void updateMappings(Supplier<String[]> propertyNames) {
226
218
}
227
219
}
228
220
229
- private void updateMappings (String [] propertyNames ) {
230
- String [] lastUpdated = this .lastUpdated ;
221
+ private void tryUpdate (String [] propertyNames ) {
222
+ Data data = this .data ;
223
+ String [] lastUpdated = (data != null ) ? data .lastUpdated () : null ;
231
224
if (lastUpdated != null && Arrays .equals (lastUpdated , propertyNames )) {
232
225
return ;
233
226
}
234
227
int size = propertyNames .length ;
235
- Map <ConfigurationPropertyName , Set <String >> mappings = cloneOrCreate (this .mappings , size );
236
- Map <String , ConfigurationPropertyName > reverseMappings = cloneOrCreate (this .reverseMappings , size );
237
- Map <ConfigurationPropertyName , Set <ConfigurationPropertyName >> descendants = cloneOrCreate (this .descendants ,
238
- size );
228
+ Map <ConfigurationPropertyName , Set <String >> mappings = cloneOrCreate (
229
+ (data != null ) ? data .mappings () : null , size );
230
+ Map <String , ConfigurationPropertyName > reverseMappings = cloneOrCreate (
231
+ (data != null ) ? data .reverseMappings () : null , size );
232
+ Map <ConfigurationPropertyName , Set <ConfigurationPropertyName >> descendants = cloneOrCreate (
233
+ (data != null ) ? data .descendants () : null , size );
239
234
for (PropertyMapper propertyMapper : this .mappers ) {
240
235
for (String propertyName : propertyNames ) {
241
236
if (!reverseMappings .containsKey (propertyName )) {
242
237
ConfigurationPropertyName configurationPropertyName = propertyMapper .map (propertyName );
243
238
if (configurationPropertyName != null && !configurationPropertyName .isEmpty ()) {
244
239
add (mappings , configurationPropertyName , propertyName );
245
240
reverseMappings .put (propertyName , configurationPropertyName );
246
- if (this .trackDescendants ) {
241
+ if (this .captureDescendants ) {
247
242
addParents (descendants , configurationPropertyName );
248
243
}
249
244
}
250
245
}
251
246
}
252
247
}
253
- this .mappings = mappings ;
254
- this .reverseMappings = reverseMappings ;
255
- this .descendants = descendants ;
256
- this .lastUpdated = this .immutable ? null : propertyNames ;
257
- this .configurationPropertyNames = this .immutable
248
+ ConfigurationPropertyName [] configurationPropertyNames = this .immutable
258
249
? reverseMappings .values ().toArray (new ConfigurationPropertyName [0 ]) : null ;
250
+ lastUpdated = this .immutable ? null : propertyNames ;
251
+ this .data = new Data (mappings , reverseMappings , descendants , configurationPropertyNames , lastUpdated );
259
252
}
260
253
261
254
private <K , V > Map <K , V > cloneOrCreate (Map <K , V > source , int size ) {
@@ -276,15 +269,16 @@ private <K, T> void add(Map<K, Set<T>> map, K key, T value) {
276
269
}
277
270
278
271
Set <String > getMapped (ConfigurationPropertyName configurationPropertyName ) {
279
- return this .mappings .getOrDefault (configurationPropertyName , Collections .emptySet ());
272
+ return this .data . mappings () .getOrDefault (configurationPropertyName , Collections .emptySet ());
280
273
}
281
274
282
275
ConfigurationPropertyName [] getConfigurationPropertyNames (String [] propertyNames ) {
283
- ConfigurationPropertyName [] names = this .configurationPropertyNames ;
276
+ Data data = this .data ;
277
+ ConfigurationPropertyName [] names = data .configurationPropertyNames ();
284
278
if (names != null ) {
285
279
return names ;
286
280
}
287
- Map <String , ConfigurationPropertyName > reverseMappings = this .reverseMappings ;
281
+ Map <String , ConfigurationPropertyName > reverseMappings = data .reverseMappings () ;
288
282
if (reverseMappings == null || reverseMappings .isEmpty ()) {
289
283
return EMPTY_NAMES_ARRAY ;
290
284
}
@@ -297,10 +291,11 @@ ConfigurationPropertyName[] getConfigurationPropertyNames(String[] propertyNames
297
291
298
292
ConfigurationPropertyState containsDescendantOf (ConfigurationPropertyName name ,
299
293
BiPredicate <ConfigurationPropertyName , ConfigurationPropertyName > ancestorOfCheck ) {
300
- if (name .isEmpty () && !this .descendants .isEmpty ()) {
294
+ Data data = this .data ;
295
+ if (name .isEmpty () && !data .descendants ().isEmpty ()) {
301
296
return ConfigurationPropertyState .PRESENT ;
302
297
}
303
- Set <ConfigurationPropertyName > candidates = this .descendants .getOrDefault (name , Collections .emptySet ());
298
+ Set <ConfigurationPropertyName > candidates = data .descendants () .getOrDefault (name , Collections .emptySet ());
304
299
for (ConfigurationPropertyName candidate : candidates ) {
305
300
if (ancestorOfCheck .test (name , candidate )) {
306
301
return ConfigurationPropertyState .PRESENT ;
@@ -309,6 +304,13 @@ ConfigurationPropertyState containsDescendantOf(ConfigurationPropertyName name,
309
304
return ConfigurationPropertyState .ABSENT ;
310
305
}
311
306
307
+ private record Data (Map <ConfigurationPropertyName , Set <String >> mappings ,
308
+ Map <String , ConfigurationPropertyName > reverseMappings ,
309
+ Map <ConfigurationPropertyName , Set <ConfigurationPropertyName >> descendants ,
310
+ ConfigurationPropertyName [] configurationPropertyNames , String [] lastUpdated ) {
311
+
312
+ }
313
+
312
314
}
313
315
314
316
/**
0 commit comments