下面列出了怎么用com.fasterxml.jackson.databind.jsontype.NamedType的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Method called to create a type information serializer for values of given
* non-container property
* if one is needed. If not needed (no polymorphic handling configured), should
* return null.
*
* @param baseType Declared type to use as the base type for type information serializer
*
* @return Type serializer to use for property values, if one is needed; null if not.
*/
public TypeSerializer findPropertyTypeSerializer(JavaType baseType,
SerializationConfig config, AnnotatedMember accessor)
throws JsonMappingException
{
AnnotationIntrospector ai = config.getAnnotationIntrospector();
TypeResolverBuilder<?> b = ai.findPropertyTypeResolver(config, accessor, baseType);
TypeSerializer typeSer;
// Defaulting: if no annotations on member, check value class
if (b == null) {
typeSer = createTypeSerializer(config, baseType);
} else {
Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(
config, accessor, baseType);
typeSer = b.buildTypeSerializer(config, baseType, subtypes);
}
return typeSer;
}
/**
* Method called to create a type information serializer for values of given
* container property
* if one is needed. If not needed (no polymorphic handling configured), should
* return null.
*
* @param containerType Declared type of the container to use as the base type for type information serializer
*
* @return Type serializer to use for property value contents, if one is needed; null if not.
*/
public TypeSerializer findPropertyContentTypeSerializer(JavaType containerType,
SerializationConfig config, AnnotatedMember accessor)
throws JsonMappingException
{
JavaType contentType = containerType.getContentType();
AnnotationIntrospector ai = config.getAnnotationIntrospector();
TypeResolverBuilder<?> b = ai.findPropertyContentTypeResolver(config, accessor, containerType);
TypeSerializer typeSer;
// Defaulting: if no annotations on member, check value class
if (b == null) {
typeSer = createTypeSerializer(config, contentType);
} else {
Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(config,
accessor, contentType);
typeSer = b.buildTypeSerializer(config, contentType, subtypes);
}
return typeSer;
}
@Override
public List<? extends Module> getJacksonModules()
{
return ImmutableList.of(
new SimpleModule(getClass().getSimpleName()
).registerSubtypes(
new NamedType(
MomentSketchAggregatorFactory.class,
MomentSketchAggregatorFactory.TYPE_NAME),
new NamedType(
MomentSketchMergeAggregatorFactory.class,
MomentSketchMergeAggregatorFactory.TYPE_NAME),
new NamedType(
MomentSketchQuantilePostAggregator.class,
MomentSketchQuantilePostAggregator.TYPE_NAME)
).addSerializer(
MomentSketchWrapper.class, new MomentSketchJsonSerializer()
)
);
}
/**
* {@inheritDoc}
*/
@Override
public ExtensionClientOutput<?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String name = p.getParsingContext().getCurrentName();
if (name == null) {
name = p.getParsingContext().getParent().getCurrentName();
}
DeserializationConfig config = ctxt.getConfig();
AnnotatedClass annotatedClass = AnnotatedClassResolver.resolveWithoutSuperTypes(config, ExtensionClientOutput.class);
Collection<NamedType> namedTypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(config, annotatedClass);
for (NamedType namedType : namedTypes) {
if (Objects.equals(namedType.getName(), name)) {
return (ExtensionClientOutput<?>) ctxt.readValue(p, namedType.getType());
}
}
logger.warn("Unknown extension '{}' is contained.", name);
return ctxt.readValue(p, UnknownExtensionClientOutput.class);
}
/**
* {@inheritDoc}
*/
@Override
public RegistrationExtensionClientInput<?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String name = p.getParsingContext().getCurrentName();
if (name == null) {
name = p.getParsingContext().getParent().getCurrentName();
}
DeserializationConfig config = ctxt.getConfig();
AnnotatedClass annotatedClass = AnnotatedClassResolver.resolveWithoutSuperTypes(config, RegistrationExtensionClientInput.class);
Collection<NamedType> namedTypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(config, annotatedClass);
for (NamedType namedType : namedTypes) {
if (Objects.equals(namedType.getName(), name)) {
return (RegistrationExtensionClientInput<?>) ctxt.readValue(p, namedType.getType());
}
}
logger.warn("Unknown extension '{}' is contained.", name);
return ctxt.readValue(p, UnknownExtensionClientInput.class);
}
/**
* {@inheritDoc}
*/
@Override
public ExtensionAuthenticatorOutput<?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String name = p.getParsingContext().getCurrentName();
if (name == null) {
name = p.getParsingContext().getParent().getCurrentName();
}
DeserializationConfig config = ctxt.getConfig();
AnnotatedClass annotatedClass = AnnotatedClassResolver.resolveWithoutSuperTypes(config, ExtensionAuthenticatorOutput.class);
Collection<NamedType> namedTypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(config, annotatedClass);
for (NamedType namedType : namedTypes) {
if (Objects.equals(namedType.getName(), name)) {
return (ExtensionAuthenticatorOutput<?>) ctxt.readValue(p, namedType.getType());
}
}
logger.warn("Unknown extension '{}' is contained.", name);
return ctxt.readValue(p, UnknownExtensionAuthenticatorOutput.class);
}
public static void registerActions(AnalyticsLoader analyticsLoader, ObjectMapper mapper) throws Exception {
Reflections reflections = new Reflections("com.flipkart.foxtrot", new SubTypesScanner());
Set<Class<? extends Action>> actions = reflections.getSubTypesOf(Action.class);
if(actions.isEmpty()) {
throw new Exception("No analytics actions found!!");
}
List<NamedType> types = new Vector<>();
for(Class<? extends Action> action : actions) {
AnalyticsProvider analyticsProvider = action.getAnnotation(AnalyticsProvider.class);
final String opcode = analyticsProvider.opcode();
if(Strings.isNullOrEmpty(opcode)) {
throw new Exception("Invalid annotation on " + action.getCanonicalName());
}
analyticsLoader.register(
new ActionMetadata(analyticsProvider.request(), action, analyticsProvider.cacheable()), analyticsProvider.opcode());
if(analyticsProvider.cacheable()) {
analyticsLoader.registerCache(opcode);
}
types.add(new NamedType(analyticsProvider.request(), opcode));
types.add(new NamedType(analyticsProvider.response(), opcode));
logger.info("Registered action: " + action.getCanonicalName());
}
mapper.getSubtypeResolver()
.registerSubtypes(types.toArray(new NamedType[types.size()]));
}
/**
* {@inheritDoc}
*/
@Override
public AuthenticationExtensionClientInput<?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String name = p.getParsingContext().getCurrentName();
if (name == null) {
name = p.getParsingContext().getParent().getCurrentName();
}
DeserializationConfig config = ctxt.getConfig();
AnnotatedClass annotatedClass = AnnotatedClassResolver.resolveWithoutSuperTypes(config, AuthenticationExtensionClientInput.class);
Collection<NamedType> namedTypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(config, annotatedClass);
for (NamedType namedType : namedTypes) {
if (Objects.equals(namedType.getName(), name)) {
return (AuthenticationExtensionClientInput<?>) ctxt.readValue(p, namedType.getType());
}
}
logger.warn("Unknown extension '{}' is contained.", name);
return ctxt.readValue(p, UnknownExtensionClientInput.class);
}
@Override
public Collection<NamedType> collectAndResolveSubtypesByClass(MapperConfig<?> config,
AnnotatedClass type)
{
final AnnotationIntrospector ai = config.getAnnotationIntrospector();
HashMap<NamedType, NamedType> subtypes = new HashMap<NamedType, NamedType>();
// then consider registered subtypes (which have precedence over annotations)
if (_registeredSubtypes != null) {
Class<?> rawBase = type.getRawType();
for (NamedType subtype : _registeredSubtypes) {
// is it a subtype of root type?
if (rawBase.isAssignableFrom(subtype.getType())) { // yes
AnnotatedClass curr = AnnotatedClassResolver.resolveWithoutSuperTypes(config,
subtype.getType());
_collectAndResolve(curr, subtype, config, ai, subtypes);
}
}
}
// and then check subtypes via annotations from base type (recursively)
NamedType rootType = new NamedType(type.getRawType(), null);
_collectAndResolve(type, rootType, config, ai, subtypes);
return new ArrayList<NamedType>(subtypes.values());
}
@Override
public Collection<NamedType> collectAndResolveSubtypesByTypeId(MapperConfig<?> config,
AnnotatedClass baseType)
{
final Class<?> rawBase = baseType.getRawType();
Set<Class<?>> typesHandled = new HashSet<Class<?>>();
Map<String,NamedType> byName = new LinkedHashMap<String,NamedType>();
NamedType rootType = new NamedType(rawBase, null);
_collectAndResolveByTypeId(baseType, rootType, config, typesHandled, byName);
if (_registeredSubtypes != null) {
for (NamedType subtype : _registeredSubtypes) {
// is it a subtype of root type?
if (rawBase.isAssignableFrom(subtype.getType())) { // yes
AnnotatedClass curr = AnnotatedClassResolver.resolveWithoutSuperTypes(config,
subtype.getType());
_collectAndResolveByTypeId(curr, subtype, config, typesHandled, byName);
}
}
}
return _combineNamedAndUnnamed(rawBase, typesHandled, byName);
}
/**
* Helper method used for merging explicitly named types and handled classes
* without explicit names.
*/
protected Collection<NamedType> _combineNamedAndUnnamed(Class<?> rawBase,
Set<Class<?>> typesHandled, Map<String,NamedType> byName)
{
ArrayList<NamedType> result = new ArrayList<NamedType>(byName.values());
// Ok, so... we will figure out which classes have no explicitly assigned name,
// by removing Classes from Set. And for remaining classes, add an anonymous
// marker
for (NamedType t : byName.values()) {
typesHandled.remove(t.getType());
}
for (Class<?> cls : typesHandled) {
// 27-Apr-2017, tatu: [databind#1616] Do not add base type itself unless
// it is concrete (or has explicit type name)
if ((cls == rawBase) && Modifier.isAbstract(cls.getModifiers())) {
continue;
}
result.add(new NamedType(cls));
}
return result;
}
/**
* Method called to create a type information serializer for values of given
* non-container property
* if one is needed. If not needed (no polymorphic handling configured), should
* return null.
*
* @param baseType Declared type to use as the base type for type information serializer
*
* @return Type serializer to use for property values, if one is needed; null if not.
*/
public TypeSerializer findPropertyTypeSerializer(JavaType baseType,
SerializationConfig config, AnnotatedMember accessor)
throws JsonMappingException
{
AnnotationIntrospector ai = config.getAnnotationIntrospector();
TypeResolverBuilder<?> b = ai.findPropertyTypeResolver(config, accessor, baseType);
TypeSerializer typeSer;
// Defaulting: if no annotations on member, check value class
if (b == null) {
typeSer = createTypeSerializer(config, baseType);
} else {
Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(
config, accessor, baseType);
typeSer = b.buildTypeSerializer(config, baseType, subtypes);
}
return typeSer;
}
/**
* Method called to create a type information serializer for values of given
* container property
* if one is needed. If not needed (no polymorphic handling configured), should
* return null.
*
* @param containerType Declared type of the container to use as the base type for type information serializer
*
* @return Type serializer to use for property value contents, if one is needed; null if not.
*/
public TypeSerializer findPropertyContentTypeSerializer(JavaType containerType,
SerializationConfig config, AnnotatedMember accessor)
throws JsonMappingException
{
JavaType contentType = containerType.getContentType();
AnnotationIntrospector ai = config.getAnnotationIntrospector();
TypeResolverBuilder<?> b = ai.findPropertyContentTypeResolver(config, accessor, containerType);
TypeSerializer typeSer;
// Defaulting: if no annotations on member, check value class
if (b == null) {
typeSer = createTypeSerializer(config, contentType);
} else {
Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(config,
accessor, contentType);
typeSer = b.buildTypeSerializer(config, contentType, subtypes);
}
return typeSer;
}
/**
* Method called to construct a type serializer for values with given declared
* base type. This is called for values other than those of bean property
* types.
*/
@Override
public TypeSerializer createTypeSerializer(SerializationConfig config,
JavaType baseType)
{
BeanDescription bean = config.introspectClassAnnotations(baseType.getRawClass());
AnnotatedClass ac = bean.getClassInfo();
AnnotationIntrospector ai = config.getAnnotationIntrospector();
TypeResolverBuilder<?> b = ai.findTypeResolver(config, ac, baseType);
/* Ok: if there is no explicit type info handler, we may want to
* use a default. If so, config object knows what to use.
*/
Collection<NamedType> subtypes = null;
if (b == null) {
b = config.getDefaultTyper(baseType);
} else {
subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(config, ac);
}
if (b == null) {
return null;
}
// 10-Jun-2015, tatu: Since not created for Bean Property, no need for post-processing
// wrt EXTERNAL_PROPERTY
return b.buildTypeSerializer(config, baseType, subtypes);
}
private static synchronized void startRealtime() {
if (rn == null) {
final Lifecycle lifecycle = new Lifecycle();
rn = RealtimeNode.builder().build();
lifecycle.addManagedInstance(rn);
rn.registerJacksonSubtype(new NamedType(StormFirehoseFactory.class, "storm"));
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
LOG.info("Running shutdown hook");
lifecycle.stop();
}
}));
try {
lifecycle.start();
} catch (Throwable t) {
LOG.info("Throwable caught at startup, committing seppuku", t);
t.printStackTrace();
System.exit(2);
}
}
}
/**
* Method called to create a type information deserializer for values of
* given non-container property, if one is needed.
* If not needed (no polymorphic handling configured for property), should return null.
*<p>
* Note that this method is only called for non-container bean properties,
* and not for values in container types or root values (or container properties)
*
* @param baseType Declared base type of the value to deserializer (actual
* deserializer type will be this type or its subtype)
*
* @return Type deserializer to use for given base type, if one is needed; null if not.
*/
public TypeDeserializer findPropertyTypeDeserializer(DeserializationConfig config,
JavaType baseType, AnnotatedMember annotated)
throws JsonMappingException
{
AnnotationIntrospector ai = config.getAnnotationIntrospector();
TypeResolverBuilder<?> b = ai.findPropertyTypeResolver(config, annotated, baseType);
// Defaulting: if no annotations on member, check value class
if (b == null) {
return findTypeDeserializer(config, baseType);
}
// but if annotations found, may need to resolve subtypes:
Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByTypeId(
config, annotated, baseType);
return b.buildTypeDeserializer(config, baseType, subtypes);
}
/**
* Method called to find and create a type information deserializer for values of
* given container (list, array, map) property, if one is needed.
* If not needed (no polymorphic handling configured for property), should return null.
*<p>
* Note that this method is only called for container bean properties,
* and not for values in container types or root values (or non-container properties)
*
* @param containerType Type of property; must be a container type
* @param propertyEntity Field or method that contains container property
*/
public TypeDeserializer findPropertyContentTypeDeserializer(DeserializationConfig config,
JavaType containerType, AnnotatedMember propertyEntity)
throws JsonMappingException
{
AnnotationIntrospector ai = config.getAnnotationIntrospector();
TypeResolverBuilder<?> b = ai.findPropertyContentTypeResolver(config, propertyEntity, containerType);
JavaType contentType = containerType.getContentType();
// Defaulting: if no annotations on member, check class
if (b == null) {
return findTypeDeserializer(config, contentType);
}
// but if annotations found, may need to resolve subtypes:
Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByTypeId(
config, propertyEntity, contentType);
return b.buildTypeDeserializer(config, contentType, subtypes);
}
public DynamicConfigApiJsonModule() {
super(DynamicConfigApiJsonModule.class.getSimpleName(), new Version(1, 0, 0, null, null, null));
registerSubtypes(
new NamedType(ClusterActivationNomadChange.class, "ClusterActivationNomadChange"),
new NamedType(MultiSettingNomadChange.class, "MultiSettingNomadChange"),
new NamedType(NodeAdditionNomadChange.class, "NodeAdditionNomadChange"),
new NamedType(ClusterActivationNomadChange.class, "ClusterActivationNomadChange"),
new NamedType(NodeRemovalNomadChange.class, "NodeRemovalNomadChange"),
new NamedType(SettingNomadChange.class, "SettingNomadChange"));
setMixInAnnotation(NodeNomadChange.class, NodeNomadChangeMixin.class);
setMixInAnnotation(Applicability.class, ApplicabilityMixin.class);
setMixInAnnotation(ClusterActivationNomadChange.class, ClusterActivationNomadChangeMixin.class);
setMixInAnnotation(MultiSettingNomadChange.class, MultiSettingNomadChangeMixin.class);
setMixInAnnotation(NodeAdditionNomadChange.class, NodeAdditionNomadChangeMixin.class);
setMixInAnnotation(NodeRemovalNomadChange.class, NodeRemovalNomadChangeMixin.class);
setMixInAnnotation(SettingNomadChange.class, SettingNomadChangeMixin.class);
}
private static synchronized void startRealtime() {
if (rn == null) {
final Lifecycle lifecycle = new Lifecycle();
rn = RealtimeNode.builder().build();
lifecycle.addManagedInstance(rn);
rn.registerJacksonSubtype(new NamedType(StormFirehoseFactory.class, "storm"));
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
LOG.info("Running shutdown hook");
lifecycle.stop();
}
}));
try {
lifecycle.start();
} catch (Throwable t) {
LOG.info("Throwable caught at startup, committing seppuku", t);
t.printStackTrace();
System.exit(2);
}
}
}
@Override
public TypeSerializer buildTypeSerializer(SerializationConfig config, JavaType baseType,
Collection<NamedType> subtypes) {
isAutowiredFiledInitialized = (this.capitalizer != null);
return super.buildTypeSerializer(config, baseType, subtypes);
}
/**
* The following code is necessary for Jackson to understand what implementation class to deserialize item
* properties to. It creates a mapping inside of Jackson between the properties implementation class and the
* id of the collection
*/
@PostConstruct
public void init() {
mapper.addMixIn(Item.class, ItemMixin.class);
collectionMetadataList.forEach(metadata -> {
metadata.setVersion(configProps.getVersion());
NamedType namedType = new NamedType(metadata.getProperties().getClass(), metadata.getId());
mapper.registerSubtypes(namedType);
});
// TODO -- this isn't being set from the main initializer for some reason???
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
@Override
public TypeSerializer buildTypeSerializer(SerializationConfig config, JavaType baseType,
Collection<NamedType> subtypes) {
isAutowiredFiledInitialized = (this.capitalizer != null);
return super.buildTypeSerializer(config, baseType, subtypes);
}
@Bean
public ObjectConverter objectConverter() {
ObjectMapper jsonMapper = new ObjectMapper();
jsonMapper.registerModule(new WebAuthnMetadataJSONModule());
jsonMapper.registerSubtypes(new NamedType(ExampleExtensionClientInput.class, ExampleExtensionClientInput.ID));
ObjectMapper cborMapper = new ObjectMapper(new CBORFactory());
cborMapper.registerSubtypes(new NamedType(ExampleExtensionAuthenticatorOutput.class, ExampleExtensionAuthenticatorOutput.ID));
return new ObjectConverter(jsonMapper, cborMapper);
}
@SuppressWarnings("unused")
public WebAuthnJSONModule(ObjectConverter objectConverter) {
super("WebAuthnJSONModule");
this.addDeserializer(Challenge.class, new ChallengeDeserializer());
this.addDeserializer(ExtensionClientInput.class, new ExtensionClientInputDeserializer());
this.addDeserializer(RegistrationExtensionClientInput.class, new RegistrationExtensionClientInputDeserializer());
this.addDeserializer(AuthenticationExtensionClientInput.class, new AuthenticationExtensionClientInputDeserializer());
this.addDeserializer(ExtensionClientOutput.class, new ExtensionClientOutputDeserializer());
this.addDeserializer(UnknownExtensionClientInput.class, new UnknownExtensionClientInputDeserializer());
this.addDeserializer(UnknownExtensionClientOutput.class, new UnknownExtensionClientOutputDeserializer());
this.addDeserializer(JWS.class, new JWSDeserializer(objectConverter));
this.addDeserializer(X509Certificate.class, new X509CertificateDeserializer());
this.addSerializer(new ChallengeSerializer());
this.addSerializer(new JWSSerializer());
this.addSerializer(new X509CertificateSerializer());
// client extension inputs
this.registerSubtypes(new NamedType(CredentialPropertiesExtensionClientInput.class, CredentialPropertiesExtensionClientInput.ID));
this.registerSubtypes(new NamedType(FIDOAppIDExtensionClientInput.class, FIDOAppIDExtensionClientInput.ID));
// client extension outputs
this.registerSubtypes(new NamedType(CredentialPropertiesExtensionClientOutput.class, CredentialPropertiesExtensionClientOutput.ID));
this.registerSubtypes(new NamedType(FIDOAppIDExtensionClientOutput.class, FIDOAppIDExtensionClientOutput.ID));
}
@SuppressWarnings("unchecked")
public T deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException {
ObjectCodec objectCodec = jsonParser.getCodec();
ObjectNode objectNode = objectCodec.readTree(jsonParser);
String typeValue = null;
JsonNode type = objectNode.get(TYPE_PROPERTY);
if (type != null) {
typeValue = type.asText();
if (STRING_PROPERTY_VALUE.equals(typeValue)) {
if (objectNode.get(ENUM_PROPERTY) != null) {
typeValue = "enum";
}
}
} else {
if (objectNode.get(REF_PROPERTY) != null) {
typeValue = "ref";
}
}
if (typeValue == null) {
throw new JsonParseException(jsonParser, "Unknown object type.");
}
DeserializationConfig config = context.getConfig();
AnnotatedClass annotatedClass =
AnnotatedClassResolver.resolveWithoutSuperTypes(config, handledType());
List<NamedType> subtypes = config.getAnnotationIntrospector().findSubtypes(annotatedClass);
for (NamedType namedType : subtypes) {
if (typeValue.equals(namedType.getName())) {
return (T) objectCodec.treeToValue(objectNode, namedType.getType());
}
}
throw new JsonParseException(jsonParser, "Unknown object type " + typeValue + ".");
}
@Override
public TypeSerializer buildTypeSerializer(SerializationConfig config, JavaType baseType, Collection<NamedType> subtypes) {
//Copied this code from parent class, StdTypeResolverBuilder with same method name
TypeIdResolver idRes = this.idResolver(config, baseType, subtypes, true, false);
// have to escape "." in the middle of the "odata.type" otherwise it will be serialized to "odata": { "type":"Value"} JSON
String escapedString = this._typeProperty.replace(".", "\\.");
return new AsPropertyTypeSerializer(idRes, (BeanProperty) null, escapedString);
}
@Override
public void registerSubtypes(NamedType... types) {
if (_registeredSubtypes == null) {
_registeredSubtypes = new LinkedHashSet<NamedType>();
}
for (NamedType type : types) {
_registeredSubtypes.add(type);
}
}
@Override
public void registerSubtypes(Class<?>... classes) {
NamedType[] types = new NamedType[classes.length];
for (int i = 0, len = classes.length; i < len; ++i) {
types[i] = new NamedType(classes[i]);
}
registerSubtypes(types);
}
@Override // since 2.9
public void registerSubtypes(Collection<Class<?>> subtypes) {
int len = subtypes.size();
NamedType[] types = new NamedType[len];
int i = 0;
for (Class<?> subtype : subtypes) {
types[i++] = new NamedType(subtype);
}
registerSubtypes(types);
}
@Override
public Collection<NamedType> collectAndResolveSubtypesByTypeId(MapperConfig<?> config,
AnnotatedMember property, JavaType baseType)
{
final AnnotationIntrospector ai = config.getAnnotationIntrospector();
Class<?> rawBase = baseType.getRawClass();
// Need to keep track of classes that have been handled already
Set<Class<?>> typesHandled = new HashSet<Class<?>>();
Map<String,NamedType> byName = new LinkedHashMap<String,NamedType>();
// start with lowest-precedence, which is from type hierarchy
NamedType rootType = new NamedType(rawBase, null);
AnnotatedClass ac = AnnotatedClassResolver.resolveWithoutSuperTypes(config,
rawBase);
_collectAndResolveByTypeId(ac, rootType, config, typesHandled, byName);
// then with definitions from property
if (property != null) {
Collection<NamedType> st = ai.findSubtypes(property);
if (st != null) {
for (NamedType nt : st) {
ac = AnnotatedClassResolver.resolveWithoutSuperTypes(config, nt.getType());
_collectAndResolveByTypeId(ac, nt, config, typesHandled, byName);
}
}
}
// and finally explicit type registrations (highest precedence)
if (_registeredSubtypes != null) {
for (NamedType subtype : _registeredSubtypes) {
// is it a subtype of root type?
if (rawBase.isAssignableFrom(subtype.getType())) { // yes
AnnotatedClass curr = AnnotatedClassResolver.resolveWithoutSuperTypes(config,
subtype.getType());
_collectAndResolveByTypeId(curr, subtype, config, typesHandled, byName);
}
}
}
return _combineNamedAndUnnamed(rawBase, typesHandled, byName);
}