下面列出了com.fasterxml.jackson.databind.deser.ValueInstantiators#com.fasterxml.jackson.databind.introspect.AnnotatedClassResolver 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* {@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);
}
/**
* {@inheritDoc}
*/
@Override
public ExtensionClientInput<?> 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, ExtensionClientInput.class);
Collection<NamedType> namedTypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(config, annotatedClass);
for (NamedType namedType : namedTypes) {
if (Objects.equals(namedType.getName(), name)) {
return (ExtensionClientInput<?>) ctxt.readValue(p, namedType.getType());
}
}
logger.warn("Unknown extension '{}' is contained.", name);
return ctxt.readValue(p, UnknownExtensionClientInput.class);
}
/**
* {@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);
}
public void testRootNameAccess() throws Exception
{
final TypeFactory tf = MAPPER.getTypeFactory();
AnnotationIntrospector ai = new JaxbAnnotationIntrospector();
// If no @XmlRootElement, should get null (unless pkg has etc)
assertNull(ai.findRootName(MAPPER.serializationConfig(),
AnnotatedClassResolver.resolve(MAPPER.serializationConfig(),
tf.constructType(SimpleBean.class), null)));
// With @XmlRootElement, but no name, empty String
PropertyName rootName = ai.findRootName(MAPPER.serializationConfig(),
AnnotatedClassResolver.resolve(MAPPER.serializationConfig(),
tf.constructType(NamespaceBean.class), null));
assertNotNull(rootName);
assertEquals("", rootName.getSimpleName());
assertEquals("urn:class", rootName.getNamespace());
// and otherwise explicit name
rootName = ai.findRootName(MAPPER.serializationConfig(),
AnnotatedClassResolver.resolve(MAPPER.serializationConfig(),
tf.constructType(RootNameBean.class), null));
assertNotNull(rootName);
assertEquals("test", rootName.getSimpleName());
assertNull(rootName.getNamespace());
}
/**
* Additional simple tests to ensure we will retain basic namespace information
* now that it can be included
*/
public void testNamespaces() throws Exception
{
final TypeFactory tf = MAPPER.getTypeFactory();
JaxbAnnotationIntrospector ai = new JaxbAnnotationIntrospector();
AnnotatedClass ac = AnnotatedClassResolver.resolve(MAPPER.serializationConfig(),
tf.constructType(NamespaceBean.class), null);
AnnotatedField af = _findField(ac, "string");
assertNotNull(af);
PropertyName pn = ai.findNameForDeserialization(MAPPER.serializationConfig(), af);
assertNotNull(pn);
// JAXB seems to assert field name instead of giving "use default"...
assertEquals("", pn.getSimpleName());
assertEquals("urn:method", pn.getNamespace());
}
@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 + ".");
}
private AnnotatedClass createTestAnnotatedClass(SerializationConfig config, JavaType javaType) {
return AnnotatedClassResolver.resolve(
config,
javaType,
null
);
}
public Class<?> materializeGenericType(MapperConfig<?> config, JavaType type)
{
Class<?> cls = type.getRawClass();
// Two-phase processing here; first construct concrete intermediate type:
String abstractName = _defaultPackage+"abstract." +cls.getName()+"_TYPE_RESOLVE";
byte[] code = buildAbstractBase(type, abstractName);
Class<?> raw = _classLoader.loadAndResolve(abstractName, code, cls);
// and only with that intermediate non-generic type, do actual materialization
AnnotatedClass ac = AnnotatedClassResolver.resolve(config,
config.getTypeFactory().constructType(raw), config);
return materializeRawType(config, ac);
}
private Class<?> _materializeRawType(AbstractTypeMaterializer mat,
DeserializationConfig config, Class<?> cls)
{
JavaType type = config.constructType(cls);
return mat.materializeRawType(config,
AnnotatedClassResolver.resolve(config, type, config));
}
@Override
public void setupModule(SetupContext context) {
super.setupModule(context);
context.addValueInstantiators(new ValueInstantiators.Base() {
@Override
public ValueInstantiator findValueInstantiator(DeserializationConfig config,
BeanDescription beanDesc, ValueInstantiator defaultInstantiator) {
JavaType type = beanDesc.getType();
Class<?> raw = type.getRawClass();
// 15-May-2015, tatu: In theory not safe, but in practice we do need to do "fuzzy" matching
// because we will (for now) be getting a subtype, but in future may want to downgrade
// to the common base type. Even more, serializer may purposefully force use of base type.
// So... in practice it really should always work, in the end. :)
if (ZoneId.class.isAssignableFrom(raw)) {
// let's assume we should be getting "empty" StdValueInstantiator here:
if (defaultInstantiator instanceof StdValueInstantiator) {
StdValueInstantiator inst = (StdValueInstantiator) defaultInstantiator;
// one further complication: we need ZoneId info, not sub-class
AnnotatedClass ac;
if (raw == ZoneId.class) {
ac = beanDesc.getClassInfo();
} else {
// we don't need Annotations, so constructing directly is fine here
// even if it's not generally recommended
ac = AnnotatedClassResolver.resolve(config,
config.constructType(ZoneId.class), config);
}
if (!inst.canCreateFromString()) {
AnnotatedMethod factory = _findFactory(ac, "of", String.class);
if (factory != null) {
inst.configureFromStringCreator(factory);
}
// otherwise... should we indicate an error?
}
// return ZoneIdInstantiator.construct(config, beanDesc, defaultInstantiator);
}
}
return defaultInstantiator;
}
});
}
private String getTypeName(JsonTypeInfo parentJsonTypeInfo, final Class<?> cls) {
// Id.CLASS
if (parentJsonTypeInfo.use() == JsonTypeInfo.Id.CLASS) {
return cls.getName();
}
// find custom name registered with `registerSubtypes`
AnnotatedClass annotatedClass = AnnotatedClassResolver
.resolveWithoutSuperTypes(objectMapper.getSerializationConfig(), cls);
Collection<NamedType> subtypes = objectMapper.getSubtypeResolver()
.collectAndResolveSubtypesByClass(objectMapper.getSerializationConfig(),
annotatedClass);
if (subtypes.size() == 1) {
NamedType subtype = subtypes.iterator().next();
if (subtype.getName() != null) {
return subtype.getName();
}
}
// find @JsonTypeName recursively
final JsonTypeName jsonTypeName = getAnnotationRecursive(cls, JsonTypeName.class);
if (jsonTypeName != null && !jsonTypeName.value().isEmpty()) {
return jsonTypeName.value();
}
// find @JsonSubTypes.Type recursively
final JsonSubTypes jsonSubTypes = getAnnotationRecursive(cls, JsonSubTypes.class, new Predicate<JsonSubTypes>() {
@Override
public boolean test(JsonSubTypes types) {
return getJsonSubTypeForClass(types, cls) != null;
}
});
if (jsonSubTypes != null) {
final JsonSubTypes.Type jsonSubType = getJsonSubTypeForClass(jsonSubTypes, cls);
if (!jsonSubType.name().isEmpty()) {
return jsonSubType.name();
}
}
// use simplified class name if it's not an interface or abstract
if(!cls.isInterface() && !Modifier.isAbstract(cls.getModifiers())) {
return cls.getName().substring(cls.getName().lastIndexOf(".") + 1);
}
return null;
}