下面列出了com.fasterxml.jackson.annotation.JsonTypeInfo#use ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Determine the appropriate type identifier according to {@link JsonTypeInfo#use()}.
*
* @param javaType specific subtype to identify
* @param typeInfoAnnotation annotation for determining what kind of identifier to use
* @return type identifier (or {@code null} if no supported value could be found)
*/
private String getTypeIdentifier(ResolvedType javaType, JsonTypeInfo typeInfoAnnotation) {
Class<?> erasedTargetType = javaType.getErasedType();
final String typeIdentifier;
switch (typeInfoAnnotation.use()) {
case NAME:
typeIdentifier = Optional.ofNullable(erasedTargetType.getAnnotation(JsonTypeName.class))
.map(JsonTypeName::value)
.filter(name -> !name.isEmpty())
.orElseGet(() -> getUnqualifiedClassName(erasedTargetType));
break;
case CLASS:
typeIdentifier = erasedTargetType.getName();
break;
default:
typeIdentifier = null;
}
return typeIdentifier;
}
private static void handleJsonSubTypes(Class<?> clazz, ComposedSchema schema, Map<String, Class<?>> referencedClasses) {
final JsonTypeInfo typeInfo = clazz.getAnnotation(JsonTypeInfo.class);
final JsonSubTypes subTypes = clazz.getAnnotation(JsonSubTypes.class);
if (typeInfo != null && subTypes != null) {
final Discriminator discriminator = new Discriminator().propertyName(typeInfo.property().equals("") ? typeInfo.use().getDefaultPropertyName() : typeInfo.property());
for (JsonSubTypes.Type type : subTypes.value()) {
final Schema<?> reference = createReference(type.value(), clazz, referencedClasses);
schema.addOneOfItem(reference);
if (StringUtils.isNotEmpty(type.name()) || typeInfo.use() == JsonTypeInfo.Id.CLASS) {
// TODO: 2019-06-24 fix this once mappings are correctly handled elsewhere
// discriminator.mapping(type.name(), reference.get$ref());
discriminator.mapping(typeInfo.use() == JsonTypeInfo.Id.CLASS ? type.value().getName() : type.name(), "#/components/schemas/" + type.value().getSimpleName());
}
}
schema.discriminator(discriminator);
}
}
private String getJsonType(Class<?> clazz, JsonTypeInfo typeInfo) {
String value;
JsonTypeInfo.Id use = typeInfo.use();
switch (use) {
case CLASS:
value = clazz.getName();
break;
case NAME: {
JsonSubTypes.Type needed = null;
JsonSubTypes subTypes = AnnotationUtils.findAnnotation(clazz, JsonSubTypes.class);
if(subTypes != null) {
for(JsonSubTypes.Type type: subTypes.value()) {
if(type.value().equals(clazz)) {
needed = type;
break;
}
}
}
if(needed == null) {
throw new IllegalArgumentException("On " + clazz + " can not find 'JsonSubTypes' record for current type.");
}
value = needed.name();
break;
}
default:
throw new IllegalArgumentException("On " + clazz + " find unexpected 'JsonTypeInfo.use' value: " + use);
}
return value;
}
private String getPropertyName(JsonTypeInfo typeInfo) {
String property = typeInfo.property();
if (property.isEmpty()) {
JsonTypeInfo.Id use = typeInfo.use();
property = use.getDefaultPropertyName();
}
return property;
}
@Override
public void emitElements(Writer writer, Settings settings, boolean exportKeyword, TsModel model) {
for (TsBeanModel tsBean : model.getBeans()) {
final Class<?> beanClass = tsBean.getOrigin();
if (beanClass != null) {
final JsonSubTypes jsonSubTypes = beanClass.getAnnotation(JsonSubTypes.class);
final JsonTypeInfo jsonTypeInfo = beanClass.getAnnotation(JsonTypeInfo.class);
if (jsonSubTypes != null && jsonTypeInfo != null && jsonTypeInfo.include() == JsonTypeInfo.As.PROPERTY) {
final String propertyName = jsonTypeInfo.property();
for (JsonSubTypes.Type subType : jsonSubTypes.value()) {
String propertyValue = null;
if (jsonTypeInfo.use() == JsonTypeInfo.Id.NAME) {
if (subType.name().equals("")) {
final JsonTypeName jsonTypeName = subType.value().getAnnotation(JsonTypeName.class);
if (jsonTypeName != null) {
propertyValue = jsonTypeName.value();
}
} else {
propertyValue = subType.name();
}
}
if (propertyValue != null) {
final String baseTypeName = tsBean.getName().getSimpleName();
final String subTypeName = findTypeName(subType.value(), model);
if (baseTypeName != null && subTypeName != null) {
writer.writeIndentedLine("");
emitTypeGuard(writer, settings, exportKeyword, baseTypeName, subTypeName, propertyName, propertyValue);
}
}
}
}
}
}
}
private static String extractTypeMetadata( TreeLogger logger, RebindConfiguration configuration, JClassType baseType, JClassType
subtype, JsonTypeInfo typeInfo, Optional<JsonSubTypes> propertySubTypes, Optional<JsonSubTypes> baseSubTypes,
ImmutableList<JClassType> allSubtypes ) throws UnableToCompleteException {
switch ( typeInfo.use() ) {
case NAME:
// we first look the name on JsonSubTypes annotations. Top ones override the bottom ones.
String name = findNameOnJsonSubTypes( baseType, subtype, allSubtypes, propertySubTypes, baseSubTypes );
if ( null != name && !"".equals( name ) ) {
return name;
}
// we look if the name is defined on the type with JsonTypeName
Optional<JsonTypeName> typeName = findFirstEncounteredAnnotationsOnAllHierarchy( configuration, subtype, JsonTypeName
.class );
if ( typeName.isPresent() && !Strings.isNullOrEmpty( typeName.get().value() ) ) {
return typeName.get().value();
}
// we use the default name (ie simple name of the class)
String simpleBinaryName = subtype.getQualifiedBinaryName();
int indexLastDot = simpleBinaryName.lastIndexOf( '.' );
if ( indexLastDot != -1 ) {
simpleBinaryName = simpleBinaryName.substring( indexLastDot + 1 );
}
return simpleBinaryName;
case MINIMAL_CLASS:
if ( !baseType.getPackage().isDefault() ) {
String basePackage = baseType.getPackage().getName();
if ( subtype.getQualifiedBinaryName().startsWith( basePackage + "." ) ) {
return subtype.getQualifiedBinaryName().substring( basePackage.length() );
}
}
case CLASS:
return subtype.getQualifiedBinaryName();
default:
logger.log( TreeLogger.Type.ERROR, "JsonTypeInfo.Id." + typeInfo.use() + " is not supported" );
throw new UnableToCompleteException();
}
}
private static boolean isSupported(JsonTypeInfo jsonTypeInfo) {
return jsonTypeInfo != null &&
jsonTypeInfo.include() == JsonTypeInfo.As.PROPERTY &&
(jsonTypeInfo.use() == JsonTypeInfo.Id.NAME || jsonTypeInfo.use() == JsonTypeInfo.Id.CLASS);
}
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;
}