Home / Class/ Cache Class — spring-boot Architecture

Cache Class — spring-boot Architecture

Architecture documentation for the Cache class in SpringIterableConfigurationPropertySource.java from the spring-boot codebase.

Entity Profile

Relationship Graph

Source Code

core/spring-boot/src/main/java/org/springframework/boot/context/properties/source/SpringIterableConfigurationPropertySource.java lines 219–367

	private static class Cache {

		private static final ConfigurationPropertyName[] EMPTY_NAMES_ARRAY = {};

		private final PropertyMapper[] mappers;

		private final boolean immutable;

		private final boolean captureDescendants;

		private final boolean systemEnvironmentSource;

		private volatile @Nullable Data data;

		Cache(PropertyMapper[] mappers, boolean immutable, boolean captureDescendants,
				boolean systemEnvironmentSource) {
			this.mappers = mappers;
			this.immutable = immutable;
			this.captureDescendants = captureDescendants;
			this.systemEnvironmentSource = systemEnvironmentSource;
		}

		void update(EnumerablePropertySource<?> propertySource) {
			if (this.data == null || !this.immutable) {
				int count = 0;
				while (true) {
					try {
						tryUpdate(propertySource);
						return;
					}
					catch (ConcurrentModificationException ex) {
						if (count++ > 10) {
							throw ex;
						}
					}
				}
			}
		}

		private void tryUpdate(EnumerablePropertySource<?> propertySource) {
			Data data = this.data;
			String[] lastUpdated = (data != null) ? data.lastUpdated() : null;
			String[] propertyNames = propertySource.getPropertyNames();
			if (lastUpdated != null && Arrays.equals(lastUpdated, propertyNames)) {
				return;
			}
			int size = propertyNames.length;
			Map<ConfigurationPropertyName, Set<String>> mappings = cloneOrCreate(
					(data != null) ? data.mappings() : null, size);
			Map<String, ConfigurationPropertyName> reverseMappings = cloneOrCreate(
					(data != null) ? data.reverseMappings() : null, size);
			Set<ConfigurationPropertyName> descendants = (!this.captureDescendants) ? null : new HashSet<>();
			Map<String, Object> systemEnvironmentCopy = (!this.systemEnvironmentSource) ? null
					: copySource(propertySource);
			for (PropertyMapper propertyMapper : this.mappers) {
				for (String propertyName : propertyNames) {
					if (!reverseMappings.containsKey(propertyName)) {
						ConfigurationPropertyName configurationPropertyName = propertyMapper.map(propertyName);
						if (configurationPropertyName != null && !configurationPropertyName.isEmpty()) {
							add(mappings, configurationPropertyName, propertyName);
							reverseMappings.put(propertyName, configurationPropertyName);
						}
					}
				}
			}
			for (String propertyName : propertyNames) {
				addParents(descendants, reverseMappings.get(propertyName));
			}
			ConfigurationPropertyName[] configurationPropertyNames = this.immutable
					? reverseMappings.values().toArray(new ConfigurationPropertyName[0]) : null;
			lastUpdated = this.immutable ? null : propertyNames;
			this.data = new Data(mappings, reverseMappings, descendants, configurationPropertyNames,
					systemEnvironmentCopy, lastUpdated);
		}

		@SuppressWarnings("unchecked")
		private HashMap<String, Object> copySource(EnumerablePropertySource<?> propertySource) {
			return new HashMap<>((Map<String, Object>) propertySource.getSource());
		}

		private <K, V> Map<K, V> cloneOrCreate(@Nullable Map<K, V> source, int size) {
			return (source != null) ? new LinkedHashMap<>(source) : new LinkedHashMap<>(size);
		}

		private void addParents(@Nullable Set<ConfigurationPropertyName> descendants,
				@Nullable ConfigurationPropertyName name) {
			if (descendants == null || name == null || name.isEmpty()) {
				return;
			}
			ConfigurationPropertyName parent = name.getParent();
			while (!parent.isEmpty()) {
				if (!descendants.add(parent)) {
					return;
				}
				parent = parent.getParent();
			}
		}

		private <K, T> void add(Map<K, Set<T>> map, K key, T value) {
			map.computeIfAbsent(key, (k) -> new HashSet<>()).add(value);
		}

		Set<String> getMapped(ConfigurationPropertyName configurationPropertyName) {
			Data data = this.data;
			Assert.state(data != null, "'data' must not be null");
			return data.mappings().getOrDefault(configurationPropertyName, Collections.emptySet());
		}

		@Nullable ConfigurationPropertyName[] getConfigurationPropertyNames(String[] propertyNames) {
			Data data = this.data;
			Assert.state(data != null, "'data' must not be null");
			@Nullable ConfigurationPropertyName[] names = data.configurationPropertyNames();
			if (names != null) {
				return names;
			}
			Map<String, ConfigurationPropertyName> reverseMappings = data.reverseMappings();
			if (reverseMappings == null || reverseMappings.isEmpty()) {
				return EMPTY_NAMES_ARRAY;
			}
			names = new ConfigurationPropertyName[propertyNames.length];
			for (int i = 0; i < propertyNames.length; i++) {
				names[i] = reverseMappings.get(propertyNames[i]);
			}
			return names;
		}

		@Nullable Set<ConfigurationPropertyName> getDescendants() {
			Data data = this.data;
			Assert.state(data != null, "'data' must not be null");
			return data.descendants();
		}

		@Nullable Object getSystemEnvironmentProperty(String name) {
			Data data = this.data;
			Assert.state(data != null, "'data' must not be null");
			Map<String, Object> systemEnvironmentCopy = data.systemEnvironmentCopy();
			Assert.state(systemEnvironmentCopy != null, "'systemEnvironmentCopy' must not be null");
			return systemEnvironmentCopy.get(name);
		}

		private record Data(Map<ConfigurationPropertyName, Set<String>> mappings,
				Map<String, ConfigurationPropertyName> reverseMappings,
				@Nullable Set<ConfigurationPropertyName> descendants,
				ConfigurationPropertyName @Nullable [] configurationPropertyNames,
				@Nullable Map<String, Object> systemEnvironmentCopy, String @Nullable [] lastUpdated) {

		}

	}

Domain

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free