From 440e545c15ff0b16316698fc207972f780d98938 Mon Sep 17 00:00:00 2001 From: des Date: Sun, 7 Mar 2021 14:17:09 +0100 Subject: [PATCH 1/3] add IntSequenceGeneratorAtClassLevel to JsonIdentityTest (#3907) --- .../v3/jaxrs2/resources/model/ModelWithJsonIdentity.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/resources/model/ModelWithJsonIdentity.java b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/resources/model/ModelWithJsonIdentity.java index f3cc661cfd..01f56ba4ed 100644 --- a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/resources/model/ModelWithJsonIdentity.java +++ b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/resources/model/ModelWithJsonIdentity.java @@ -142,4 +142,12 @@ public class SourceDefinition10 { public String driver; public String name; } + + @JsonProperty("IntSequenceGeneratorAtClassLevel") + public SourceDefinition11 testIntSequenceGeneratorAtClassLevel; + + @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class) + public class SourceDefinition11 { + public String name; + } } \ No newline at end of file From 2cfd002cc2b37b6772c7f32a490fdb3200f1dbca Mon Sep 17 00:00:00 2001 From: des Date: Sun, 7 Mar 2021 15:17:59 +0100 Subject: [PATCH 2/3] add expected result for IntSequenceGeneratorAtClassLevel to JsonIdentityTest (#3907) --- .../java/io/swagger/v3/jaxrs2/JsonIdentityTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/JsonIdentityTest.java b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/JsonIdentityTest.java index c6e7d0db1a..fc26eb54fc 100644 --- a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/JsonIdentityTest.java +++ b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/JsonIdentityTest.java @@ -142,6 +142,8 @@ public void testJsonIdentityCyclic() throws IOException { " type: string\n" + " WithoutJsonIdentityReference:\n" + " $ref: '#/components/schemas/SourceDefinition10'\n" + + " IntSequenceGeneratorAtClassLevel:\n" + + " $ref: '#/components/schemas/SourceDefinition11'\n" + " SourceDefinition3:\n" + " type: object\n" + " properties:\n" + @@ -165,6 +167,14 @@ public void testJsonIdentityCyclic() throws IOException { " type: string\n" + " name:\n" + " type: string\n" + + " SourceDefinition11:\n" + + " title: SourceDefinition11\n" + + " properties:\n" + + " '@id':\n" + + " type: integer\n" + + " format: int32\n"+ + " 'name':\n" + + " type: string\n" + " SourceDefinition8:\n" + " type: object\n" + " properties:\n" + From 6a793c5571c2ff1710975ec65965d86be08c6c43 Mon Sep 17 00:00:00 2001 From: des Date: Sun, 7 Mar 2021 18:17:13 +0100 Subject: [PATCH 3/3] fix NPE (#3907) --- .../v3/core/jackson/ModelResolver.java | 105 ++++++++++++------ .../swagger/v3/jaxrs2/JsonIdentityTest.java | 61 +++++----- 2 files changed, 103 insertions(+), 63 deletions(-) diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java index 177968b8d6..2c3256c319 100644 --- a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java +++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java @@ -303,7 +303,7 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context if (jsonIdentityReference == null) { jsonIdentityReference = type.getRawClass().getAnnotation(JsonIdentityReference.class); } - model = GeneratorWrapper.processJsonIdentity(annotatedType, context, _mapper, jsonIdentityInfo, jsonIdentityReference); + model = new GeneratorWrapper().processJsonIdentity(annotatedType, context, _mapper, jsonIdentityInfo, jsonIdentityReference); if (model != null) { return model; } @@ -1046,8 +1046,18 @@ private void handleUnwrapped(List props, Schema innerModel, String prefi } } - private enum GeneratorWrapper { - PROPERTY(ObjectIdGenerators.PropertyGenerator.class) { + + private class GeneratorWrapper { + + private final List wrappers = new ArrayList(); + + + private final class PropertyGeneratorWrapper extends GeneratorWrapper.Base { + + public PropertyGeneratorWrapper(Class generator) { + super(generator); + } + @Override protected Schema processAsProperty(String propertyName, AnnotatedType type, ModelConverterContext context, ObjectMapper mapper) { @@ -1064,7 +1074,7 @@ protected Schema processAsId(String propertyName, AnnotatedType type, ModelConverterContext context, ObjectMapper mapper) { final JavaType javaType; if (type.getType() instanceof JavaType) { - javaType = (JavaType)type.getType(); + javaType = (JavaType) type.getType(); } else { javaType = mapper.constructType(type.getType()); } @@ -1098,8 +1108,14 @@ protected Schema processAsId(String propertyName, AnnotatedType type, } return null; } - }, - INT(ObjectIdGenerators.IntSequenceGenerator.class) { + } + + private final class IntGeneratorWrapper extends GeneratorWrapper.Base { + + public IntGeneratorWrapper(Class generator) { + super(generator); + } + @Override protected Schema processAsProperty(String propertyName, AnnotatedType type, ModelConverterContext context, ObjectMapper mapper) { @@ -1112,8 +1128,14 @@ protected Schema processAsId(String propertyName, AnnotatedType type, ModelConverterContext context, ObjectMapper mapper) { return new IntegerSchema(); } - }, - UUID(ObjectIdGenerators.UUIDGenerator.class) { + + } + + private final class UUIDGeneratorWrapper extends GeneratorWrapper.Base { + + public UUIDGeneratorWrapper(Class generator) { + super(generator); + } @Override protected Schema processAsProperty(String propertyName, AnnotatedType type, ModelConverterContext context, ObjectMapper mapper) { @@ -1126,8 +1148,15 @@ protected Schema processAsId(String propertyName, AnnotatedType type, ModelConverterContext context, ObjectMapper mapper) { return new UUIDSchema(); } - }, - NONE(ObjectIdGenerators.None.class) { + + } + + private final class NoneGeneratorWrapper extends GeneratorWrapper.Base { + + public NoneGeneratorWrapper(Class generator) { + super(generator); + } + // When generator = ObjectIdGenerators.None.class property should be processed as normal property. @Override protected Schema processAsProperty(String propertyName, AnnotatedType type, @@ -1140,24 +1169,27 @@ protected Schema processAsId(String propertyName, AnnotatedType type, ModelConverterContext context, ObjectMapper mapper) { return null; } - }; + } - private final Class generator; + private abstract class Base { - GeneratorWrapper(Class generator) { - this.generator = generator; - } + private final Class generator; - protected abstract Schema processAsProperty(String propertyName, AnnotatedType type, - ModelConverterContext context, ObjectMapper mapper); + Base(Class generator) { + this.generator = generator; + } - protected abstract Schema processAsId(String propertyName, AnnotatedType type, - ModelConverterContext context, ObjectMapper mapper); + protected abstract Schema processAsProperty(String propertyName, AnnotatedType type, + ModelConverterContext context, ObjectMapper mapper); - public static Schema processJsonIdentity(AnnotatedType type, ModelConverterContext context, + protected abstract Schema processAsId(String propertyName, AnnotatedType type, + ModelConverterContext context, ObjectMapper mapper); + } + + public Schema processJsonIdentity(AnnotatedType type, ModelConverterContext context, ObjectMapper mapper, JsonIdentityInfo identityInfo, JsonIdentityReference identityReference) { - final GeneratorWrapper wrapper = identityInfo != null ? getWrapper(identityInfo.generator()) : null; + final GeneratorWrapper.Base wrapper = identityInfo != null ? getWrapper(identityInfo.generator()) : null; if (wrapper == null) { return null; } @@ -1168,25 +1200,32 @@ public static Schema processJsonIdentity(AnnotatedType type, ModelConverterConte } } - private static GeneratorWrapper getWrapper(Class generator) { - for (GeneratorWrapper value : GeneratorWrapper.values()) { - if (value.generator.isAssignableFrom(generator)) { - return value; - } + private GeneratorWrapper.Base getWrapper(Class generator) { + if(ObjectIdGenerators.PropertyGenerator.class.isAssignableFrom(generator)) { + return new PropertyGeneratorWrapper(generator); + } else if(ObjectIdGenerators.IntSequenceGenerator.class.isAssignableFrom(generator)) { + return new IntGeneratorWrapper(generator); + } else if(ObjectIdGenerators.UUIDGenerator.class.isAssignableFrom(generator)) { + return new UUIDGeneratorWrapper(generator); + } else if(ObjectIdGenerators.None.class.isAssignableFrom(generator)) { + return new NoneGeneratorWrapper(generator); } return null; } - private static Schema process(Schema id, String propertyName, AnnotatedType type, + protected Schema process(Schema id, String propertyName, AnnotatedType type, ModelConverterContext context) { - Schema model = context.resolve(removeJsonIdentityAnnotations(type)); - Schema mi = model; - mi.addProperties(propertyName, id); - return new Schema().$ref(StringUtils.isNotEmpty(mi.get$ref()) - ? mi.get$ref() : mi.getName()); + type = removeJsonIdentityAnnotations(type); + Schema model = context.resolve(type); + if(model == null){ + model = resolve(type,context, null); + } + model.addProperties(propertyName, id); + return new Schema().$ref(StringUtils.isNotEmpty(model.get$ref()) + ? model.get$ref() : model.getName()); } - private static AnnotatedType removeJsonIdentityAnnotations(AnnotatedType type) { + private AnnotatedType removeJsonIdentityAnnotations(AnnotatedType type) { return new AnnotatedType() .jsonUnwrappedHandler(type.getJsonUnwrappedHandler()) .jsonViewAnnotation(type.getJsonViewAnnotation()) diff --git a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/JsonIdentityTest.java b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/JsonIdentityTest.java index fc26eb54fc..bbc9d4ece3 100644 --- a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/JsonIdentityTest.java +++ b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/JsonIdentityTest.java @@ -85,22 +85,6 @@ public void testJsonIdentityCyclic() throws IOException { " application/xml: {}\n" + "components:\n" + " schemas:\n" + - " SourceDefinition4:\n" + - " type: object\n" + - " properties:\n" + - " name:\n" + - " type: string\n" + - " testName2:\n" + - " type: integer\n" + - " format: int32\n" + - " SourceDefinition5:\n" + - " type: object\n" + - " properties:\n" + - " name:\n" + - " type: string\n" + - " '@id':\n" + - " type: integer\n" + - " format: int32\n" + " ModelWithJsonIdentity:\n" + " type: object\n" + " properties:\n" + @@ -144,15 +128,6 @@ public void testJsonIdentityCyclic() throws IOException { " $ref: '#/components/schemas/SourceDefinition10'\n" + " IntSequenceGeneratorAtClassLevel:\n" + " $ref: '#/components/schemas/SourceDefinition11'\n" + - " SourceDefinition3:\n" + - " type: object\n" + - " properties:\n" + - " name:\n" + - " type: string\n" + - " driverId:\n" + - " type: string\n" + - " '@id':\n" + - " type: string\n" + " SourceDefinition1:\n" + " type: object\n" + " properties:\n" + @@ -168,20 +143,38 @@ public void testJsonIdentityCyclic() throws IOException { " name:\n" + " type: string\n" + " SourceDefinition11:\n" + - " title: SourceDefinition11\n" + + " type: object\n" + " properties:\n" + + " 'name':\n" + + " type: string\n" + " '@id':\n" + " type: integer\n" + " format: int32\n"+ - " 'name':\n" + - " type: string\n" + - " SourceDefinition8:\n" + + " SourceDefinition3:\n" + " type: object\n" + " properties:\n" + " name:\n" + " type: string\n" + " driverId:\n" + " type: string\n" + + " '@id':\n" + + " type: string\n" + + " SourceDefinition4:\n" + + " type: object\n" + + " properties:\n" + + " name:\n" + + " type: string\n" + + " testName2:\n" + + " type: integer\n" + + " format: int32\n" + + " SourceDefinition5:\n" + + " type: object\n" + + " properties:\n" + + " name:\n" + + " type: string\n" + + " '@id':\n" + + " type: integer\n" + + " format: int32\n" + " SourceDefinition6:\n" + " type: object\n" + " properties:\n" + @@ -197,5 +190,13 @@ public void testJsonIdentityCyclic() throws IOException { " type: string\n" + " '@id':\n" + " type: string\n" + - " format: uuid\n"; + " format: uuid\n" + + " SourceDefinition8:\n" + + " type: object\n" + + " properties:\n" + + " name:\n" + + " type: string\n" + + " driverId:\n" + + " type: string\n"; + } \ No newline at end of file