Home / Class/ EntryBinder Class — spring-boot Architecture

EntryBinder Class — spring-boot Architecture

Architecture documentation for the EntryBinder class in MapBinder.java from the spring-boot codebase.

Entity Profile

Relationship Graph

Source Code

core/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/MapBinder.java lines 148–246

	private class EntryBinder {

		private final ConfigurationPropertyName root;

		private final AggregateElementBinder elementBinder;

		private final ResolvableType mapType;

		private final ResolvableType keyType;

		private final ResolvableType valueType;

		private final Class<?> resolvedValueType;

		private final boolean valueTreatedAsNestedMap;

		private final Bindable<Object> bindableMapType;

		private final Bindable<Object> bindableValueType;

		EntryBinder(ConfigurationPropertyName root, Bindable<?> target, AggregateElementBinder elementBinder) {
			this.root = root;
			this.elementBinder = elementBinder;
			this.mapType = target.getType().asMap();
			this.keyType = this.mapType.getGeneric(0);
			this.valueType = this.mapType.getGeneric(1);
			this.resolvedValueType = this.valueType.resolve(Object.class);
			this.valueTreatedAsNestedMap = Object.class.equals(this.resolvedValueType);
			this.bindableMapType = Bindable.of(this.mapType);
			this.bindableValueType = Bindable.of(this.valueType);
		}

		void bindEntries(ConfigurationPropertySource source, Map<Object, Object> map) {
			if (source instanceof IterableConfigurationPropertySource iterableSource) {
				for (ConfigurationPropertyName name : iterableSource) {
					ConfigurationPropertyName entryName = getEntryName(source, name);
					Object key = getContext().getConverter().convert(getKeyName(entryName), this.keyType);
					Bindable<?> valueBindable = getValueBindable(name);
					map.computeIfAbsent(key, (k) -> this.elementBinder.bind(entryName, valueBindable));
				}
			}
		}

		private Bindable<?> getValueBindable(ConfigurationPropertyName name) {
			return (!isParentOf(name) && this.valueTreatedAsNestedMap) ? this.bindableMapType : this.bindableValueType;
		}

		private ConfigurationPropertyName getEntryName(ConfigurationPropertySource source,
				ConfigurationPropertyName name) {
			if (Collection.class.isAssignableFrom(this.resolvedValueType) || this.valueType.isArray()) {
				return chopNameAtNumericIndex(name);
			}
			if (!isParentOf(name) && (this.valueTreatedAsNestedMap || !isScalarValue(source, name))) {
				return name.chop(this.root.getNumberOfElements() + 1);
			}
			return name;
		}

		private boolean isParentOf(ConfigurationPropertyName name) {
			return this.root.isParentOf(name);
		}

		private ConfigurationPropertyName chopNameAtNumericIndex(ConfigurationPropertyName name) {
			int start = this.root.getNumberOfElements() + 1;
			int size = name.getNumberOfElements();
			for (int i = start; i < size; i++) {
				if (name.isNumericIndex(i)) {
					return name.chop(i);
				}
			}
			return name;
		}

		private boolean isScalarValue(ConfigurationPropertySource source, ConfigurationPropertyName name) {
			Class<?> resolved = this.valueType.resolve(Object.class);
			if (!resolved.getName().startsWith("java.lang") && !resolved.isEnum()) {
				return false;
			}
			ConfigurationProperty property = source.getConfigurationProperty(name);
			if (property == null) {
				return false;
			}
			Object value = property.getValue();
			value = getContext().getPlaceholdersResolver().resolvePlaceholders(value);
			return getContext().getConverter().canConvert(value, this.valueType);
		}

		private String getKeyName(ConfigurationPropertyName name) {
			StringBuilder result = new StringBuilder();
			for (int i = this.root.getNumberOfElements(); i < name.getNumberOfElements(); i++) {
				if (!result.isEmpty()) {
					result.append('.');
				}
				result.append(name.getElement(i, Form.ORIGINAL));
			}
			return result.toString();
		}

	}

Domain

Analyze Your Own Codebase

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

Try Supermodel Free