private static String buildMessage(ConfigurationPropertyName name, Bindable<?> target) { StringBuilder message = new StringBuilder(); message.append("Failed to bind properties"); message.append((name != null) ? " under '" + name + "'" : ""); message.append(" to ").append(target.getType()); return message.toString(); }
private Bindable<?> resolveTarget(Bindable<?> target) { Class<?> type = target.getType().resolve(Object.class); if (Properties.class.isAssignableFrom(type)) { return STRING_STRING_MAP; } return target; }
private boolean isUnbindableBean(ConfigurationPropertyName name, Bindable<?> target, Context context) { for (ConfigurationPropertySource source : context.getSources()) { if (source.containsDescendantOf(name) == ConfigurationPropertyState.PRESENT) { // We know there are properties to bind so we can't bypass anything return false; } } Class<?> resolved = target.getType().resolve(Object.class); if (resolved.isPrimitive() || NON_BEAN_CLASSES.contains(resolved)) { return true; } return resolved.getName().startsWith("java."); }
private AggregateBinder<?> getAggregateBinder(Bindable<?> target, Context context) { Class<?> resolvedType = target.getType().resolve(Object.class); if (Map.class.isAssignableFrom(resolvedType)) { return new MapBinder(context); } if (Collection.class.isAssignableFrom(resolvedType)) { return new CollectionBinder(context); } if (target.getType().isArray()) { return new ArrayBinder(context); } return null; }
@Override protected Object bindAggregate(ConfigurationPropertyName name, Bindable<?> target, AggregateElementBinder elementBinder) { IndexedCollectionSupplier result = new IndexedCollectionSupplier(ArrayList::new); ResolvableType aggregateType = target.getType(); ResolvableType elementType = target.getType().getComponentType(); bindIndexed(name, target, elementBinder, aggregateType, elementType, result); if (result.wasSupplied()) { List<Object> list = (List<Object>) result.get(); Object array = Array.newInstance(elementType.resolve(), list.size()); for (int i = 0; i < list.size(); i++) { Array.set(array, i, list.get(i)); } return array; } return null; }
public <T> T convert(Object result, Bindable<T> target) { return convert(result, target.getType(), target.getAnnotations()); }
@SuppressWarnings("unchecked") public static <T> Bean<T> get(Bindable<T> bindable, boolean canCallGetValue) { Class<?> type = bindable.getType().resolve(Object.class); Supplier<T> value = bindable.getValue(); T instance = null; if (canCallGetValue && value != null) { instance = value.get(); type = (instance != null) ? instance.getClass() : type; } if (instance == null && !isInstantiable(type)) { return null; } Bean<?> bean = Bean.cached; if (bean == null || !type.equals(bean.getType())) { bean = new Bean<>(bindable.getType(), type); cached = bean; } return (Bean<T>) bean; }
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); }
private Object bindBean(ConfigurationPropertyName name, Bindable<?> target, BindHandler handler, Context context, boolean allowRecursiveBinding) { if (containsNoDescendantOf(context.getSources(), name) || isUnbindableBean(name, target, context)) { return null; } BeanPropertyBinder propertyBinder = (propertyName, propertyTarget) -> bind( name.append(propertyName), propertyTarget, handler, context, false); Class<?> type = target.getType().resolve(Object.class); if (!allowRecursiveBinding && context.hasBoundBean(type)) { return null; } return context.withBean(type, () -> { Stream<?> boundBeans = BEAN_BINDERS.stream() .map((b) -> b.bind(name, target, context, propertyBinder)); return boundBeans.filter(Objects::nonNull).findFirst().orElse(null); }); }
@Override protected Object bindAggregate(ConfigurationPropertyName name, Bindable<?> target, AggregateElementBinder elementBinder) { Class<?> collectionType = (target.getValue() != null) ? List.class : target.getType().resolve(Object.class); ResolvableType aggregateType = ResolvableType.forClassWithGenerics(List.class, target.getType().asCollection().getGenerics()); ResolvableType elementType = target.getType().asCollection().getGeneric(); IndexedCollectionSupplier result = new IndexedCollectionSupplier( () -> CollectionFactory.createCollection(collectionType, elementType.resolve(), 0)); bindIndexed(name, target, elementBinder, aggregateType, elementType, result); if (result.wasSupplied()) { return result.get(); } return null; }
@Override protected Object bindAggregate(ConfigurationPropertyName name, Bindable<?> target, AggregateElementBinder elementBinder) { Map<Object, Object> map = CollectionFactory.createMap((target.getValue() != null) ? Map.class : target.getType().resolve(Object.class), 0); Bindable<?> resolvedTarget = resolveTarget(target); boolean hasDescendants = hasDescendants(name); for (ConfigurationPropertySource source : getContext().getSources()) { if (!ConfigurationPropertyName.EMPTY.equals(name)) { ConfigurationProperty property = source.getConfigurationProperty(name); if (property != null && !hasDescendants) { return getContext().getConverter().convert(property.getValue(), target); } source = source.filter(name::isAncestorOf); } new EntryBinder(name, resolvedTarget, elementBinder).bindEntries(source, map); } return map.isEmpty() ? null : map; }
private static void echo(Bindable<?> bindable) { System.out.printf("Bindable type = %s , boxedType = %s , value = %s , annotations = %s\n", bindable.getType(), bindable.getBoxedType(), bindable.getValue().get(), Arrays.asList(bindable.getAnnotations())); } }