Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jackson views/ignored properties: fix view names, in-line custom schemas #2063

Merged
merged 1 commit into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
Expand Down Expand Up @@ -65,6 +66,9 @@ public Map<String, T> readMap(Collection<AnnotationInstance> annotations,

protected Map<String, T> readMap(Collection<AnnotationInstance> annotations,
Function<AnnotationInstance, Optional<String>> nameFn, BiFunction<String, AnnotationInstance, T> reader) {
if (annotations.isEmpty()) {
return new LinkedHashMap<>(0);
}
IoLogging.logger.annotationsMap('@' + annotationName.local());
return annotations.stream()
.map(annotation -> nameFn.apply(annotation).map(name -> entry(name, reader.apply(name, annotation))))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ public DiscriminatorIO(IOContext<V, A, O, AB, OB> context) {
*/
@Override
public Discriminator read(AnnotationInstance annotation) {
IoLogging.logger.singleAnnotationAs("@Schema", "Discriminator");
String propertyName = value(annotation, SchemaConstant.PROP_DISCRIMINATOR_PROPERTY);
AnnotationInstance[] mapping = value(annotation, SchemaConstant.PROP_DISCRIMINATOR_MAPPING);

if (propertyName == null && mapping == null) {
return null;
}

IoLogging.logger.singleAnnotationAs("@Schema", "Discriminator");
Discriminator discriminator = OASFactory.createDiscriminator();

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ public List<Server> readList(AnnotationInstance[] annotations) {
}

public List<Server> readList(Collection<AnnotationInstance> annotations) {
if (annotations.isEmpty()) {
return new ArrayList<>(0);
}
IoLogging.logger.annotationsArray("@Server");
return annotations.stream()
.map(this::read)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public class SchemaRegistry {
*
* @param type
* the {@link Type} the {@link Schema} applies to
* @param views types applied to the currently-active JsonView (Jackson annotation)
* @param resolver
* a {@link TypeResolver} that will be used to resolve
* parameterized and wildcard types
Expand All @@ -73,7 +74,7 @@ public class SchemaRegistry {
* @return the same schema if not eligible for registration, or a reference
* to the schema registered for the given Type
*/
public Schema checkRegistration(Type type, Set<Type> views, TypeResolver resolver, Schema schema) {
public Schema checkRegistration(Type type, Map<Type, Boolean> views, TypeResolver resolver, Schema schema) {
return register(type, views, resolver, schema, (reg, key) -> reg.register(key, schema, null));
}

Expand All @@ -99,6 +100,7 @@ public Schema checkRegistration(Type type, Set<Type> views, TypeResolver resolve
*
* @param type
* the {@link Type} the {@link Schema} applies to
* @param views types applied to the currently-active JsonView (Jackson annotation)
* @param resolver
* a {@link TypeResolver} that will be used to resolve
* parameterized and wildcard types
Expand All @@ -107,11 +109,11 @@ public Schema checkRegistration(Type type, Set<Type> views, TypeResolver resolve
* @return the same schema if not eligible for registration, or a reference
* to the schema registered for the given Type
*/
public Schema registerReference(Type type, Set<Type> views, TypeResolver resolver, Schema schema) {
public Schema registerReference(Type type, Map<Type, Boolean> views, TypeResolver resolver, Schema schema) {
return register(type, views, resolver, schema, SchemaRegistry::registerReference);
}

public Schema register(Type type, Set<Type> views, TypeResolver resolver, Schema schema,
public Schema register(Type type, Map<Type, Boolean> views, TypeResolver resolver, Schema schema,
BiFunction<SchemaRegistry, TypeKey, Schema> registrationAction) {

final Type resolvedType = TypeResolver.resolve(type, resolver);
Expand All @@ -130,7 +132,7 @@ public Schema register(Type type, Set<Type> views, TypeResolver resolver, Schema
return schema;
}

TypeKey key = new TypeKey(resolvedType, views);
TypeKey key = keyFor(resolvedType, views);

if (hasRef(key)) {
schema = lookupRef(key);
Expand All @@ -153,7 +155,7 @@ public Schema register(Type type, Set<Type> views, TypeResolver resolver, Schema
* @param resolver resolver for type parameter
* @return true when schema references are enabled and the type is present in the registry, otherwise false
*/
public boolean hasSchema(Type type, Set<Type> views, TypeResolver resolver) {
public boolean hasSchema(Type type, Map<Type, Boolean> views, TypeResolver resolver) {
if (disabled) {
return false;
}
Expand Down Expand Up @@ -235,11 +237,20 @@ public SchemaRegistry(AnnotationScannerContext context) {
return;
}

this.register(new TypeKey(type, Collections.emptySet()), schema, Extensions.getName(schema));
this.register(keyFor(type, Collections.emptyMap()), schema, Extensions.getName(schema));
ScannerLogging.logger.configSchemaRegistered(typeSignature);
});
}

private static TypeKey keyFor(Type type, Map<Type, Boolean> views) {
if (TypeUtil.knownJavaType(type.name())) {
// do not apply views for JDK types
return new TypeKey(type, Collections.emptyMap());
}

return new TypeKey(type, views);
}

/**
* Register the provided {@link Schema} for the provided {@link Type}. If an
* existing schema has already been registered for the type, it will be
Expand All @@ -253,8 +264,8 @@ public SchemaRegistry(AnnotationScannerContext context) {
* {@link Schema} to add to the registry
* @return a reference to the newly registered {@link Schema}
*/
public Schema register(Type entityType, Set<Type> views, Schema schema) {
TypeKey key = new TypeKey(entityType, views);
public Schema register(Type entityType, Map<Type, Boolean> views, Schema schema) {
TypeKey key = keyFor(entityType, views);

if (hasRef(key)) {
// This is a replacement registration
Expand Down Expand Up @@ -324,20 +335,20 @@ String deriveName(TypeKey key, String schemaName) {
return name;
}

public Schema lookupRef(Type instanceType, Set<Type> views) {
return lookupRef(new TypeKey(instanceType, views));
public Schema lookupRef(Type instanceType, Map<Type, Boolean> views) {
return lookupRef(keyFor(instanceType, views));
}

public boolean hasRef(Type instanceType, Set<Type> views) {
return hasRef(new TypeKey(instanceType, views));
public boolean hasRef(Type instanceType, Map<Type, Boolean> views) {
return hasRef(keyFor(instanceType, views));
}

public Schema lookupSchema(Type instanceType, Set<Type> views) {
return lookupSchema(new TypeKey(instanceType, views));
public Schema lookupSchema(Type instanceType, Map<Type, Boolean> views) {
return lookupSchema(keyFor(instanceType, views));
}

public boolean hasSchema(Type instanceType, Set<Type> views) {
return hasSchema(new TypeKey(instanceType, views));
public boolean hasSchema(Type instanceType, Map<Type, Boolean> views) {
return hasSchema(keyFor(instanceType, views));
}

public boolean isTypeRegistrationSupported(Type type, Schema schema) {
Expand Down Expand Up @@ -398,20 +409,14 @@ private void remove(TypeKey key) {
*/
public static final class TypeKey {
private final Type type;
private final Set<Type> views;
private final Map<Type, Boolean> views;
private int hashCode = 0;

TypeKey(Type type, Set<Type> views) {
TypeKey(Type type, Map<Type, Boolean> views) {
this.type = type;
this.views = new LinkedHashSet<>(views);
this.views = new LinkedHashMap<>(views);
}

/*
* TypeKey(Type type) {
* this(type, Collections.emptySet());
* }
*/

public String defaultName() {
StringBuilder name = new StringBuilder(type.name().local());

Expand All @@ -436,9 +441,12 @@ public String viewSuffix() {

StringBuilder suffix = new StringBuilder();

for (Type view : views) {
suffix.append('_');
suffix.append(view.name().local());
for (Map.Entry<Type, Boolean> view : views.entrySet()) {
if (Boolean.TRUE.equals(view.getValue())) {
// Only views that are directly specified contribute to the schema's name
suffix.append('_');
suffix.append(view.getKey().name().local());
}
}

return suffix.toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ Schema processField() {
// The registeredTypeSchema will be a reference to typeSchema if registration occurs
registrationType = TypeUtil.isWrappedType(entityType) ? fieldType : entityType;
registrationCandidate = !JandexUtil.isRef(schemaAnnotation) &&
typeProcessor.allowRegistration() &&
schemaRegistry.register(registrationType, context.getJsonViews(), typeResolver,
initTypeSchema,
(reg, key) -> null) != initTypeSchema;
Expand Down
Loading