Skip to content
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
22 changes: 13 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>de.rub.nds</groupId>
<artifactId>protocol-toolkit-bom</artifactId>
<version>6.2.4</version>
<version>7.1.1</version>
</parent>

<artifactId>modifiable-variable</artifactId>
Expand Down Expand Up @@ -64,6 +64,8 @@
<skipTests>false</skipTests>
<skip.surefire.tests>${skipTests}</skip.surefire.tests>
<skip.failsafe.tests>${skipTests}</skip.failsafe.tests>
<!-- Jackson 3 is required by victools jsonschema-generator 5 -->
<deps.jackson3.version>3.0.3</deps.jackson3.version>
</properties>

<dependencies>
Expand All @@ -76,14 +78,6 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.github.victools</groupId>
<artifactId>jsonschema-generator</artifactId>
Expand Down Expand Up @@ -112,6 +106,16 @@
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
</dependency>
<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${deps.jackson3.version}</version>
</dependency>
<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${deps.jackson3.version}</version>
</dependency>
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-annotations</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
*/
package de.rub.nds.modifiablevariable.json;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.victools.jsonschema.generator.*;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import tools.jackson.databind.JacksonModule;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.json.JsonMapper;

public class JsonSchemaCliGenerator {

Expand All @@ -24,14 +25,16 @@ public class JsonSchemaCliGenerator {
* additional Jackson modules to register.
*/
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(ModifiableVariableModule.getFieldVisibilityChecker());
JsonMapper.Builder mapperBuilder =
JsonMapper.builder()
.changeDefaultVisibility(
vc -> ModifiableVariableModule.getFieldVisibilityChecker());

// Register additional modules (if any) passed as command line arguments
for (int i = 2; i < args.length; i++) {
try {
mapper.registerModule(
(Module) Class.forName(args[i]).getConstructor().newInstance());
mapperBuilder.addModule(
(JacksonModule) Class.forName(args[i]).getConstructor().newInstance());
} catch (InstantiationException
| IllegalAccessException
| InvocationTargetException
Expand All @@ -40,6 +43,7 @@ public static void main(String[] args) {
throw new RuntimeException(e);
}
}
ObjectMapper mapper = mapperBuilder.build();

// Prepare the schema generator
SchemaGeneratorConfigBuilder builder =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,24 @@
package de.rub.nds.modifiablevariable.json;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import de.rub.nds.modifiablevariable.ModifiableVariable;
import de.rub.nds.modifiablevariable.VariableModification;
import de.rub.nds.modifiablevariable.util.DataConverter;
import java.io.IOException;
import org.reflections.Reflections;
import tools.jackson.core.JsonGenerator;
import tools.jackson.core.JsonParser;
import tools.jackson.databind.DeserializationContext;
import tools.jackson.databind.SerializationContext;
import tools.jackson.databind.deser.std.StdDeserializer;
import tools.jackson.databind.introspect.VisibilityChecker;
import tools.jackson.databind.module.SimpleModule;
import tools.jackson.databind.ser.std.StdSerializer;

/**
* A Jackson module for the ModifiableVariable library. It registers serializers and deserializers
* required for modifiable variables. Make sure to include it using {@code
* ObjectMapper.registerModule(new ModifiableVariableModule())} in your Jackson configuration before
* serializing or deserializing modifiable variables.
* JsonMapper.builder().addModule(new ModifiableVariableModule())} in your Jackson configuration
* before serializing or deserializing modifiable variables.
*/
public class ModifiableVariableModule extends SimpleModule {

Expand All @@ -51,8 +50,7 @@ public UnformattedByteArraySerializer() {
}

@Override
public void serialize(byte[] value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
public void serialize(byte[] value, JsonGenerator gen, SerializationContext serializers) {
gen.writeString(DataConverter.bytesToRawHexString(value));
}
}
Expand All @@ -63,13 +61,13 @@ public UnformattedByteArrayDeserializer() {
}

@Override
public byte[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return DataConverter.hexStringToByteArray(p.getText());
public byte[] deserialize(JsonParser p, DeserializationContext ctxt) {
return DataConverter.hexStringToByteArray(p.getString());
}
}

public static VisibilityChecker<?> getFieldVisibilityChecker() {
return VisibilityChecker.Std.defaultInstance()
public static VisibilityChecker getFieldVisibilityChecker() {
return VisibilityChecker.defaultInstance()
.withFieldVisibility(JsonAutoDetect.Visibility.ANY)
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@

import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
import com.fasterxml.jackson.databind.introspect.AnnotatedClassResolver;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.victools.jsonschema.generator.CustomDefinition;
import com.github.victools.jsonschema.generator.CustomDefinitionProviderV2;
import com.github.victools.jsonschema.generator.FieldScope;
Expand All @@ -32,6 +26,12 @@
import java.util.*;
import java.util.stream.Collectors;
import org.apache.commons.lang3.NotImplementedException;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.introspect.AnnotatedClass;
import tools.jackson.databind.introspect.AnnotatedClassResolver;
import tools.jackson.databind.jsontype.NamedType;
import tools.jackson.databind.node.ArrayNode;
import tools.jackson.databind.node.ObjectNode;

/**
* Look-up of subtypes from a {@link ObjectMapper} instance. Based on {@link
Expand Down Expand Up @@ -108,12 +108,13 @@ public List<ResolvedType> findSubtypes(

AnnotatedClass annotatedClass =
AnnotatedClassResolver.resolveWithoutSuperTypes(
objectMapper.getDeserializationConfig(), declaredType.getErasedType());
objectMapper.deserializationConfig(), declaredType.getErasedType());
Collection<NamedType> registeredSubtypes =
objectMapper
.deserializationConfig()
.getSubtypeResolver()
.collectAndResolveSubtypesByTypeId(
objectMapper.getDeserializationConfig(), annotatedClass);
objectMapper.deserializationConfig(), annotatedClass);

return registeredSubtypes.stream()
.map(NamedType::getType)
Expand All @@ -136,11 +137,14 @@ public List<ResolvedType> findSubtypes(
}

/**
* Filter subtypes to ensure that they have the same type bindings as the declared type.
* Filter subtypes to ensure that their type bindings are compatible with the declared type,
* i.e. each type parameter of the subtype is assignable to the corresponding type parameter of
* the declared type. Unbound type variables of the declared type are resolved to their bound
* (e.g. {@link Object}) and therefore match any subtype.
*
* @param declaredType the supertype for which subtypes are being resolved
* @param resolvedType the resolved subtype to check against the declared type
* @return true if the subtype has the same type bindings as the declared type, false otherwise
* @return true if the subtype has compatible type bindings, false otherwise
*/
public boolean filterSubtypesWithMatchingTypeBindings(
ResolvedType declaredType, ResolvedType resolvedType) {
Expand All @@ -150,9 +154,23 @@ public boolean filterSubtypesWithMatchingTypeBindings(
// If the resolved type does not have the declared type as a parent, return false
return false;
}
return declaredType.getTypeBindings().isEmpty()
|| resolvedTypeParameters.equals(
declaredType.getTypeBindings().getTypeParameters());
List<ResolvedType> declaredTypeParameters =
declaredType.getTypeBindings().getTypeParameters();
if (declaredTypeParameters.isEmpty()) {
return true;
}
if (declaredTypeParameters.size() != resolvedTypeParameters.size()) {
return false;
}
for (int i = 0; i < declaredTypeParameters.size(); i++) {
if (!declaredTypeParameters
.get(i)
.getErasedType()
.isAssignableFrom(resolvedTypeParameters.get(i).getErasedType())) {
return false;
}
}
return true;
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import com.github.victools.jsonschema.generator.AnnotationHelper;
import com.github.victools.jsonschema.generator.FieldScope;
import com.github.victools.jsonschema.generator.MemberScope;
Expand All @@ -37,6 +33,12 @@
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import tools.jackson.databind.BeanDescription;
import tools.jackson.databind.JavaType;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.PropertyNamingStrategy;
import tools.jackson.databind.annotation.JsonNaming;
import tools.jackson.databind.introspect.ClassIntrospector;

/**
* Module for setting up schema generation aspects based on {@code jackson-annotations}. Supports
Expand Down Expand Up @@ -302,13 +304,13 @@ protected final BeanDescription getBeanDescriptionForClass(ResolvedType targetTy
synchronized (this.beanDescriptions) {
return this.beanDescriptions.computeIfAbsent(
targetType.getErasedType(),
type ->
this.objectMapper
.getSerializationConfig()
.introspect(
this.objectMapper
.getTypeFactory()
.constructType(type)));
type -> {
ClassIntrospector classIntrospector =
this.objectMapper.serializationConfig().classIntrospectorInstance();
JavaType javaType = this.objectMapper.getTypeFactory().constructType(type);
return classIntrospector.introspectForSerialization(
javaType, classIntrospector.introspectClassAnnotations(javaType));
});
}
}

Expand Down Expand Up @@ -345,7 +347,7 @@ protected boolean shouldIgnoreField(FieldScope field) {
// some kinds of field ignorals are only available via an annotation introspector
Set<String> ignoredProperties =
this.objectMapper
.getSerializationConfig()
.serializationConfig()
.getAnnotationIntrospector()
.findPropertyIgnoralByName(null, beanDescription.getClassInfo())
.getIgnored();
Expand Down
Loading
Loading