package sh.calaba.org.codehaus.jackson.map.jsontype.impl; import java.util.Collection; import sh.calaba.org.codehaus.jackson.annotate.JsonTypeInfo; import sh.calaba.org.codehaus.jackson.map.*; import sh.calaba.org.codehaus.jackson.map.jsontype.NamedType; import sh.calaba.org.codehaus.jackson.map.jsontype.TypeIdResolver; import sh.calaba.org.codehaus.jackson.map.jsontype.TypeResolverBuilder; import sh.calaba.org.codehaus.jackson.type.JavaType; /** * Default {@link TypeResolverBuilder} implementation. * * @author tatu * @since 1.5 */ public class StdTypeResolverBuilder implements TypeResolverBuilder { // Configuration settings: protected JsonTypeInfo.Id _idType; protected JsonTypeInfo.As _includeAs; protected String _typeProperty; /** * @since 1.9 */ protected Class _defaultImpl; // Objects protected TypeIdResolver _customIdResolver; /* /********************************************************** /* Accessors /********************************************************** */ @Override public Class getDefaultImpl() { return _defaultImpl; } /* /********************************************************** /* Construction, initialization, actual building /********************************************************** */ public StdTypeResolverBuilder() { } public static StdTypeResolverBuilder noTypeInfoBuilder() { return new StdTypeResolverBuilder().init(JsonTypeInfo.Id.NONE, null); } @Override public StdTypeResolverBuilder init(JsonTypeInfo.Id idType, TypeIdResolver idRes) { // sanity checks if (idType == null) { throw new IllegalArgumentException("idType can not be null"); } _idType = idType; _customIdResolver = idRes; // Let's also initialize property name as per idType default _typeProperty = idType.getDefaultPropertyName(); return this; } @Override public TypeSerializer buildTypeSerializer(SerializationConfig config, JavaType baseType, Collection subtypes, BeanProperty property) { if (_idType == JsonTypeInfo.Id.NONE) { return null; } TypeIdResolver idRes = idResolver(config, baseType, subtypes, true, false); switch (_includeAs) { case WRAPPER_ARRAY: return new AsArrayTypeSerializer(idRes, property); case PROPERTY: return new AsPropertyTypeSerializer(idRes, property, _typeProperty); case WRAPPER_OBJECT: return new AsWrapperTypeSerializer(idRes, property); case EXTERNAL_PROPERTY: return new AsExternalTypeSerializer(idRes, property, _typeProperty); } throw new IllegalStateException("Do not know how to construct standard type serializer for inclusion type: "+_includeAs); } @Override public TypeDeserializer buildTypeDeserializer(DeserializationConfig config, JavaType baseType, Collection subtypes, BeanProperty property) { if (_idType == JsonTypeInfo.Id.NONE) { return null; } TypeIdResolver idRes = idResolver(config, baseType, subtypes, false, true); // First, method for converting type info to type id: switch (_includeAs) { case WRAPPER_ARRAY: return new AsArrayTypeDeserializer(baseType, idRes, property, _defaultImpl); case PROPERTY: return new AsPropertyTypeDeserializer(baseType, idRes, property, _defaultImpl, _typeProperty); case WRAPPER_OBJECT: return new AsWrapperTypeDeserializer(baseType, idRes, property, _defaultImpl); case EXTERNAL_PROPERTY: return new AsExternalTypeDeserializer(baseType, idRes, property, _defaultImpl, _typeProperty); } throw new IllegalStateException("Do not know how to construct standard type serializer for inclusion type: "+_includeAs); } /* /********************************************************** /* Construction, configuration /********************************************************** */ @Override public StdTypeResolverBuilder inclusion(JsonTypeInfo.As includeAs) { if (includeAs == null) { throw new IllegalArgumentException("includeAs can not be null"); } _includeAs = includeAs; return this; } /** * Method for constructing an instance with specified type property name * (property name to use for type id when using "as-property" inclusion). */ @Override public StdTypeResolverBuilder typeProperty(String typeIdPropName) { // ok to have null/empty; will restore to use defaults if (typeIdPropName == null || typeIdPropName.length() == 0) { typeIdPropName = _idType.getDefaultPropertyName(); } _typeProperty = typeIdPropName; return this; } @Override public StdTypeResolverBuilder defaultImpl(Class defaultImpl) { _defaultImpl = defaultImpl; return this; } /* /********************************************************** /* Accessors /********************************************************** */ public String getTypeProperty() { return _typeProperty; } /* /********************************************************** /* Internal methods /********************************************************** */ /** * Helper method that will either return configured custom * type id resolver, or construct a standard resolver * given configuration. */ protected TypeIdResolver idResolver(MapperConfig config, JavaType baseType, Collection subtypes, boolean forSer, boolean forDeser) { // Custom id resolver? if (_customIdResolver != null) { return _customIdResolver; } if (_idType == null) { throw new IllegalStateException("Can not build, 'init()' not yet called"); } switch (_idType) { case CLASS: return new ClassNameIdResolver(baseType, config.getTypeFactory()); case MINIMAL_CLASS: return new MinimalClassNameIdResolver(baseType, config.getTypeFactory()); case NAME: return TypeNameIdResolver.construct(config, baseType, subtypes, forSer, forDeser); case NONE: // hmmh. should never get this far with 'none' return null; case CUSTOM: // need custom resolver... } throw new IllegalStateException("Do not know how to construct standard type id resolver for idType: "+_idType); } }