Search in sources :

Example 1 with BasicBeanDescription

use of com.fasterxml.jackson.databind.introspect.BasicBeanDescription in project dropwizard-guicey by xvik.

the class ConfigTreeBuilder method resolvePaths.

/**
 * Use jackson serialization api to extract all configuration values with paths from configuration object.
 * Always analyze types, even if actual branch is not present at all (null value) in order to always bind
 * nulls and avoid "Schrodinger's binding" case. In short, bindings should not depend on configuration values
 * (presence).
 * <p>
 * Still, bindings may vary: for example, bound implementations may differ (best example is dropwizard server type),
 * as a consequences, parsed type may be different and so different properties paths could be recognized.
 *
 * @param config  jackson serialization config
 * @param content currently parsed paths
 * @param type    analyzed part type
 * @param object  analyzed part instance (may be null)
 * @return all configuration paths values
 */
@SuppressWarnings({ "checkstyle:CyclomaticComplexity", "PMD.AvoidLiteralsInIfCondition" })
private static List<ConfigPath> resolvePaths(final SerializationConfig config, final ConfigPath root, final List<ConfigPath> content, final Class type, final Object object, final GenericsContext genericsContext) {
    final BasicBeanDescription description = config.introspect(config.constructType(type));
    for (BeanPropertyDefinition prop : description.findProperties()) {
        // ignore write-only or groovy special property
        if (!prop.couldSerialize() || "metaClass".equals(prop.getName())) {
            continue;
        }
        final Object value;
        // (like netflix dynamic properties) it should not break app startup
        try {
            value = readValue(prop.getAccessor(), object);
        } catch (Exception ex) {
            LOGGER.warn("Can't bind configuration path '{}' due to {}: {}. Enable debug logs to see " + "complete stack trace or use @JsonIgnore on property getter.", fullPath(root, prop), ex.getClass().getSimpleName(), ex.getMessage());
            LOGGER.debug("Complete error: ", ex);
            continue;
        }
        final ConfigPath item = createItem(root, prop, value, genericsContext);
        content.add(item);
        if (root != null) {
            root.getChildren().add(item);
        }
        if (item.isCustomType() && !detectRecursion(item)) {
            // build generics context for actual value type (if not null)
            final GenericsContext subContext = prop.getGetter() != null ? genericsContext.method(prop.getGetter().getAnnotated()).returnTypeAs(item.getValueType()) : genericsContext.fieldTypeAs(prop.getField().getAnnotated(), item.getValueType());
            resolvePaths(config, item, content, item.getValueType(), item.getValue(), subContext);
        }
    }
    if (root != null) {
        // simple properties goes up and composite objects go lower (both groups sorted alphabetically)
        root.getChildren().sort(Comparator.comparing(o -> (o.isCustomType() ? 'b' : 'a') + o.getPath()));
    }
    return content;
}
Also used : Bootstrap(io.dropwizard.setup.Bootstrap) LoggerFactory(org.slf4j.LoggerFactory) SerializationConfig(com.fasterxml.jackson.databind.SerializationConfig) HashMap(java.util.HashMap) Multimap(com.google.common.collect.Multimap) Duration(io.dropwizard.util.Duration) BasicBeanDescription(com.fasterxml.jackson.databind.introspect.BasicBeanDescription) ArrayList(java.util.ArrayList) Configuration(io.dropwizard.Configuration) Optional(com.google.common.base.Optional) Map(java.util.Map) AnnotatedMember(com.fasterxml.jackson.databind.introspect.AnnotatedMember) GenericsResolver(ru.vyarus.java.generics.resolver.GenericsResolver) GenericsContext(ru.vyarus.java.generics.resolver.context.GenericsContext) ImmutableSet(com.google.common.collect.ImmutableSet) Logger(org.slf4j.Logger) AccessibleObject(java.lang.reflect.AccessibleObject) MoreObjects(com.google.common.base.MoreObjects) Set(java.util.Set) Primitives(com.google.common.primitives.Primitives) List(java.util.List) DataSize(io.dropwizard.util.DataSize) Type(java.lang.reflect.Type) Comparator(java.util.Comparator) BeanPropertyDefinition(com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition) Collections(java.util.Collections) GenericsContext(ru.vyarus.java.generics.resolver.context.GenericsContext) BeanPropertyDefinition(com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition) AccessibleObject(java.lang.reflect.AccessibleObject) BasicBeanDescription(com.fasterxml.jackson.databind.introspect.BasicBeanDescription)

Aggregations

SerializationConfig (com.fasterxml.jackson.databind.SerializationConfig)1 AnnotatedMember (com.fasterxml.jackson.databind.introspect.AnnotatedMember)1 BasicBeanDescription (com.fasterxml.jackson.databind.introspect.BasicBeanDescription)1 BeanPropertyDefinition (com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition)1 MoreObjects (com.google.common.base.MoreObjects)1 Optional (com.google.common.base.Optional)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Multimap (com.google.common.collect.Multimap)1 Primitives (com.google.common.primitives.Primitives)1 Configuration (io.dropwizard.Configuration)1 Bootstrap (io.dropwizard.setup.Bootstrap)1 DataSize (io.dropwizard.util.DataSize)1 Duration (io.dropwizard.util.Duration)1 AccessibleObject (java.lang.reflect.AccessibleObject)1 Type (java.lang.reflect.Type)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 Comparator (java.util.Comparator)1 HashMap (java.util.HashMap)1 List (java.util.List)1