All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.jackson.map.introspect.BasicClassIntrospector Maven / Gradle / Ivy

Go to download

Data Mapper package is a high-performance data binding package built on Jackson JSON processor

There is a newer version: 1.9.13
Show newest version
package org.codehaus.jackson.map.introspect;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;

import org.codehaus.jackson.map.AnnotationIntrospector;
import org.codehaus.jackson.map.ClassIntrospector;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.MapperConfig;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.type.SimpleType;
import org.codehaus.jackson.map.util.ClassUtil;
import org.codehaus.jackson.type.JavaType;

public class BasicClassIntrospector
    extends ClassIntrospector
{
    /* We keep a small set of pre-constructed descriptions to use for
     * common non-structured values, such as Numbers and Strings.
     * This is strictly performance optimization to reduce what is
     * usually one-time cost, but seems useful for some cases considering
     * simplicity.
     */
    
    protected final static BasicBeanDescription STRING_DESC;
    static {
        AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(String.class, null, null);
        STRING_DESC = BasicBeanDescription.forOtherUse(null, SimpleType.constructUnsafe(String.class), ac);
    }
    protected final static BasicBeanDescription BOOLEAN_DESC;
    static {
        AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(Boolean.TYPE, null, null);
        BOOLEAN_DESC = BasicBeanDescription.forOtherUse(null, SimpleType.constructUnsafe(Boolean.TYPE), ac);
    }
    protected final static BasicBeanDescription INT_DESC;
    static {
        AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(Integer.TYPE, null, null);
        INT_DESC = BasicBeanDescription.forOtherUse(null, SimpleType.constructUnsafe(Integer.TYPE), ac);
    }
    protected final static BasicBeanDescription LONG_DESC;
    static {
        AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(Long.TYPE, null, null);
        LONG_DESC = BasicBeanDescription.forOtherUse(null, SimpleType.constructUnsafe(Long.TYPE), ac);
    }

    
    // // // Then static filter singletons
    
    /**
     * @since 1.8
     * @deprecated Since 1.9 just don't use
     */
    @Deprecated
    public final static GetterMethodFilter DEFAULT_GETTER_FILTER = new GetterMethodFilter();

    /**
     * @since 1.8
     * @deprecated Since 1.9 just don't use
     */
    @Deprecated
    public final static SetterMethodFilter DEFAULT_SETTER_FILTER = new SetterMethodFilter();

    /**
     * @since 1.8
     * @deprecated Since 1.9 just don't use
     */
    @Deprecated
    public final static SetterAndGetterMethodFilter DEFAULT_SETTER_AND_GETTER_FILTER = new SetterAndGetterMethodFilter();

    protected final static MethodFilter MINIMAL_FILTER = new MinimalMethodFilter();
    
    /*
    /**********************************************************
    /* Life cycle
    /**********************************************************
     */

    public final static BasicClassIntrospector instance = new BasicClassIntrospector();

    public BasicClassIntrospector() { }
    
    /*
    /**********************************************************
    /* Factory method impls
    /**********************************************************
     */

    @Override
    public BasicBeanDescription forSerialization(SerializationConfig cfg,
            JavaType type, MixInResolver r)
    {
        // minor optimization: for JDK types do minimal introspection
        BasicBeanDescription desc = _findCachedDesc(type);
        if (desc == null) {
            desc = BasicBeanDescription.forSerialization(collectProperties(cfg, type, r, true));
        }
        return desc;
    }

    @Override
    public BasicBeanDescription forDeserialization(DeserializationConfig cfg,
            JavaType type, MixInResolver r)
    {
        // minor optimization: for JDK types do minimal introspection
        BasicBeanDescription desc = _findCachedDesc(type);
        if (desc == null) {
            desc = BasicBeanDescription.forDeserialization(collectProperties(cfg, type, r, false));
        }
        return desc;
    }

    @Override
    public BasicBeanDescription forCreation(DeserializationConfig cfg,
            JavaType type, MixInResolver r)
    {
        BasicBeanDescription desc = _findCachedDesc(type);
        if (desc == null) {
            desc = BasicBeanDescription.forDeserialization(collectProperties(cfg, type, r, false));
        }
        return desc;
    }

    @Override
    public BasicBeanDescription forClassAnnotations(MapperConfig cfg,
            JavaType type, MixInResolver r)
    {
        boolean useAnnotations = cfg.isAnnotationProcessingEnabled();
        AnnotationIntrospector ai =  cfg.getAnnotationIntrospector();
        AnnotatedClass ac = AnnotatedClass.construct(type.getRawClass(), (useAnnotations ? ai : null), r);
        return BasicBeanDescription.forOtherUse(cfg, type, ac);
    }

    @Override
    public BasicBeanDescription forDirectClassAnnotations(MapperConfig cfg,
            JavaType type, MixInResolver r)
    {
        boolean useAnnotations = cfg.isAnnotationProcessingEnabled();
        AnnotationIntrospector ai =  cfg.getAnnotationIntrospector();
        AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(type.getRawClass(),
                (useAnnotations ? ai : null), r);
        return BasicBeanDescription.forOtherUse(cfg, type, ac);
    }
    
    /*
    /**********************************************************
    /* Overridable helper methods
    /**********************************************************
     */

    /**
     * @since 1.9
     */
    public POJOPropertiesCollector collectProperties(MapperConfig config,
            JavaType type, MixInResolver r, boolean forSerialization)
    {
        AnnotatedClass ac = classWithCreators(config, type, r);
        ac.resolveMemberMethods(MINIMAL_FILTER);
        ac.resolveFields();
        return constructPropertyCollector(config, ac, type, forSerialization).collect();
    }

    /**
     * Overridable method called for creating {@link POJOPropertiesCollector} instance
     * to use; override is needed if a custom sub-class is to be used.
     * 
     * @since 1.9
     */
    protected POJOPropertiesCollector constructPropertyCollector(MapperConfig config,
            AnnotatedClass ac, JavaType type,
            boolean forSerialization)
    {
        return new POJOPropertiesCollector(config, forSerialization, type, ac);
    }
    
    /**
     * @since 1.9
     */
    public AnnotatedClass classWithCreators(MapperConfig config,
            JavaType type, MixInResolver r)
    {
        boolean useAnnotations = config.isAnnotationProcessingEnabled();
        AnnotationIntrospector ai = config.getAnnotationIntrospector();
        AnnotatedClass ac = AnnotatedClass.construct(type.getRawClass(), (useAnnotations ? ai : null), r);
        ac.resolveMemberMethods(MINIMAL_FILTER);
        // true -> include all creators, not just default constructor
        ac.resolveCreators(true);
        return ac;
    }
    
    /**
     * Method called to see if type is one of core JDK types
     * that we have cached for efficiency.
     * 
     * @since 1.9
     */
    protected BasicBeanDescription _findCachedDesc(JavaType type)
    {
        Class cls = type.getRawClass();
        if (cls == String.class) {
            return STRING_DESC;
        }
        if (cls == Boolean.TYPE) {
            return BOOLEAN_DESC;
        }
        if (cls == Integer.TYPE) {
            return INT_DESC;
        }
        if (cls == Long.TYPE) {
            return LONG_DESC;
        }
        return null;
    }
    
    /**
     * Helper method for getting access to filter that only guarantees
     * that methods used for serialization are to be included.
     * 
     * @deprecated Since 1.9 just don't use
     */
    @Deprecated
    protected MethodFilter getSerializationMethodFilter(SerializationConfig cfg)
    {
    	return DEFAULT_GETTER_FILTER;
    }

    /**
     * Helper method for getting access to filter that only guarantees
     * that methods used for deserialization are to be included.
     * 
     * @deprecated Since 1.9 just don't use
     */
    @Deprecated
    protected MethodFilter getDeserializationMethodFilter(DeserializationConfig cfg)
    {
        /* [JACKSON-88]: may also need to include getters (at least for
         * Collection and Map types)
         */
        if (cfg.isEnabled(DeserializationConfig.Feature.USE_GETTERS_AS_SETTERS)) {
            return DEFAULT_SETTER_AND_GETTER_FILTER;
            
        }
    	return DEFAULT_SETTER_FILTER;
    }

    /*
    /**********************************************************
    /* Helper classes
    /**********************************************************
     */

    /**
     * Going forward, we will only do very minimal filtering;
     * mostly just gets rid of static methods really.
     * 
     * @since 1.9
     */
    private static class MinimalMethodFilter
        implements MethodFilter
    {
        @Override
        public boolean includeMethod(Method m)
        {
            if (Modifier.isStatic(m.getModifiers())) {
                return false;
            }
            int pcount = m.getParameterTypes().length;
            return (pcount <= 2);
        }
    }
    
    /**
     * Filter used to only include methods that have signature that is
     * compatible with "getters": take no arguments, are non-static,
     * and return something.
     * 
     * @deprecated Since 1.9 just don't use
     */
    @Deprecated
    public static class GetterMethodFilter
        implements MethodFilter
    {
        private GetterMethodFilter() { }
    
        @Override
        public boolean includeMethod(Method m)
        {
            return ClassUtil.hasGetterSignature(m);
        }
    }

    /**
     * Filter used to only include methods that have signature that is
     * compatible with "setters": take one and only argument and
     * are non-static.
     *

* Actually, also need to include 2-arg methods to support * "any setters"; as well as 0-arg getters as long as they * return Collection or Map type. * * @deprecated Since 1.9 just don't use */ @Deprecated public static class SetterMethodFilter implements MethodFilter { @Override public boolean includeMethod(Method m) { // First: we can't use static methods if (Modifier.isStatic(m.getModifiers())) { return false; } int pcount = m.getParameterTypes().length; // Ok; multiple acceptable parameter counts: switch (pcount) { case 1: // Regular setters take just one param, so include: return true; case 2: /* 2-arg version only for "AnySetters"; they are not * auto-detected, and need to have an annotation. * However, due to annotation inheritance we do, we * don't yet know if sub-classes might have annotations... * so shouldn't leave out any methods quite yet. */ //if (m.getAnnotation(JsonAnySetter.class) != null) { ... } return true; } return false; } } /** * Filter used if some getters (namely, once needed for "setterless * collection injection") are also needed, not just setters. * * @deprecated Since 1.9 just don't use */ @Deprecated public final static class SetterAndGetterMethodFilter extends SetterMethodFilter { @SuppressWarnings("deprecation") @Override public boolean includeMethod(Method m) { if (super.includeMethod(m)) { return true; } if (!ClassUtil.hasGetterSignature(m)) { return false; } // but furthermore, only accept Collections & Maps, for now Class rt = m.getReturnType(); if (Collection.class.isAssignableFrom(rt) || Map.class.isAssignableFrom(rt)) { return true; } return false; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy