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 3235240588..80067ec0fc 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 @@ -226,7 +226,7 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context if (resolvedArrayAnnotation == null) { schemaRefFromAnnotation = resolvedSchemaAnnotation.ref(); if (!openapi31) { - return new JsonSchema().$ref(resolvedSchemaAnnotation.ref()).name(name); + return new Schema().$ref(resolvedSchemaAnnotation.ref()).name(name); } } else { ArraySchema schema = new ArraySchema(); @@ -578,9 +578,8 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context model = context.resolve(aType); return model; } else { - model = new Schema().name(name); - if ( - (openapi31 && Boolean.TRUE.equals(PrimitiveType.explicitObjectType)) || + model = openapi31 ? new JsonSchema().name(name) : new Schema().name(name); + if ((openapi31 && Boolean.TRUE.equals(PrimitiveType.explicitObjectType)) || (!openapi31 && (!Boolean.FALSE.equals(PrimitiveType.explicitObjectType)))) { if (openapi31 && resolvedArrayAnnotation == null) { model.addType("object"); @@ -2604,7 +2603,8 @@ protected Map resolveExtensions(Annotated a, Annotation[] annota if (schema != null && schema.extensions() != null && schema.extensions().length > 0) { - return AnnotationsUtils.getExtensions(openapi31, schema.extensions()); + boolean usePrefix = !openapi31; + return AnnotationsUtils.getExtensions(openapi31, usePrefix, schema.extensions()); } return null; } @@ -2798,7 +2798,8 @@ protected Map resolveExtensions(AnnotatedType a, io.swagger.v3.o if (arraySchema != null && arraySchema.extensions() != null && arraySchema.extensions().length > 0) { - return AnnotationsUtils.getExtensions(openapi31, arraySchema.extensions()); + boolean usePrefix = !openapi31; + return AnnotationsUtils.getExtensions(openapi31, usePrefix, arraySchema.extensions()); } return null; } diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/AnnotationsUtils.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/AnnotationsUtils.java index 9ce4fb1439..d2ccb8c7dd 100644 --- a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/AnnotationsUtils.java +++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/AnnotationsUtils.java @@ -539,7 +539,8 @@ public static Optional getArraySchema(io.swagger.v3.oas.annotations.medi } if (arraySchema.extensions().length > 0) { - Map extensions = AnnotationsUtils.getExtensions(openapi31, arraySchema.extensions()); + boolean usePrefix = !openapi31; + Map extensions = AnnotationsUtils.getExtensions(openapi31, usePrefix, arraySchema.extensions()); if (extensions != null) { extensions.forEach(arraySchemaObject::addExtension); } @@ -831,7 +832,8 @@ public static Optional getSchemaFromAnnotation( } if (schema.extensions().length > 0) { - Map extensions = AnnotationsUtils.getExtensions(openapi31, schema.extensions()); + boolean usePrefix = !openapi31; + Map extensions = AnnotationsUtils.getExtensions(openapi31, usePrefix, schema.extensions()); if (extensions != null) { extensions.forEach(schemaObject::addExtension); } @@ -1847,20 +1849,26 @@ public static io.swagger.v3.oas.annotations.media.Schema getSchemaDeclaredAnnota } public static Map getExtensions(Extension... extensions) { - return getExtensions(false, extensions); + return getExtensions(false, true, extensions); } public static Map getExtensions(boolean openapi31, Extension... extensions) { + return getExtensions(openapi31, true, extensions); + } + + public static Map getExtensions(boolean openapi31, boolean usePrefix, Extension... extensions) { final Map map = new HashMap<>(); for (Extension extension : extensions) { final String name = extension.name(); - String decoratedName = openapi31 ? name : StringUtils.prependIfMissing(name, "x-"); - final String key = name.length() > 0 ? decoratedName : name; + String decoratedName = usePrefix + ? StringUtils.prependIfMissing(name, "x-") + : name; + final String key = name.isEmpty() ? name : decoratedName; for (ExtensionProperty property : extension.properties()) { final String propertyName = property.name(); final String propertyValue = property.value(); - JsonNode processedValue = null; + JsonNode processedValue; final boolean propertyAsJson = property.parseValue(); if (StringUtils.isNotBlank(propertyName) && StringUtils.isNotBlank(propertyValue)) { if (key.isEmpty()) { @@ -1871,14 +1879,14 @@ public static Map getExtensions(boolean openapi31, Extension... } else { processedValue = Json.mapper().readTree(propertyValue); } - decoratedName = openapi31 ? propertyName : StringUtils.prependIfMissing(propertyName, "x-"); + decoratedName = usePrefix ? StringUtils.prependIfMissing(propertyName, "x-") : propertyName; map.put(decoratedName, processedValue); } catch (Exception e) { - decoratedName = openapi31 ? propertyName : StringUtils.prependIfMissing(propertyName, "x-"); + decoratedName = usePrefix ? StringUtils.prependIfMissing(propertyName, "x-") : propertyName; map.put(decoratedName, propertyValue); } } else { - decoratedName = openapi31 ? propertyName : StringUtils.prependIfMissing(propertyName, "x-"); + decoratedName = usePrefix ? StringUtils.prependIfMissing(propertyName, "x-") : propertyName; map.put(decoratedName, propertyValue); } } else { diff --git a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/ReaderTest.java b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/ReaderTest.java index 4d12144716..e84a55a957 100644 --- a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/ReaderTest.java +++ b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/ReaderTest.java @@ -90,6 +90,7 @@ import io.swagger.v3.jaxrs2.resources.Ticket4804NotBlankResource; import io.swagger.v3.jaxrs2.resources.Ticket4804ProcessorResource; import io.swagger.v3.jaxrs2.resources.Ticket4804Resource; +import io.swagger.v3.jaxrs2.resources.Ticket4850Resource; import io.swagger.v3.jaxrs2.resources.Ticket4859Resource; import io.swagger.v3.jaxrs2.resources.Ticket4879Resource; import io.swagger.v3.jaxrs2.resources.UploadResource; @@ -5342,4 +5343,37 @@ public void testTicket4065() { SerializationMatchers.assertEqualsToYaml31(openAPI, yaml); ModelConverters.reset(); } + + @Test(description = "Extensions Tests OAS 3.1") + public void testExtensionsOAS31() { + SwaggerConfiguration config = new SwaggerConfiguration().openAPI31(true); + Reader reader = new Reader(config); + + OpenAPI openAPI = reader.read(Ticket4850Resource.class); + assertNotNull(openAPI); + + String yaml = "openapi: 3.1.0\n" + + "paths:\n" + + " /bar:\n" + + " get:\n" + + " operationId: test\n" + + " responses:\n" + + " default:\n" + + " description: default response\n" + + " content:\n" + + " '*/*':\n" + + " schema:\n" + + " $ref: \"#/components/schemas/ExtensionsResource\"\n" + + "components:\n" + + " schemas:\n" + + " ExtensionsResource:\n" + + " description: ExtensionsResource\n" + + " x-user:\n" + + " name: Josh\n" + + " user-extensions:\n" + + " lastName: Hart\n" + + " address: House"; + SerializationMatchers.assertEqualsToYaml31(openAPI, yaml); + } + } diff --git a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/resources/Ticket4850Resource.java b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/resources/Ticket4850Resource.java new file mode 100644 index 0000000000..a11f237d56 --- /dev/null +++ b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/resources/Ticket4850Resource.java @@ -0,0 +1,31 @@ +package io.swagger.v3.jaxrs2.resources; + +import io.swagger.v3.oas.annotations.extensions.Extension; +import io.swagger.v3.oas.annotations.extensions.ExtensionProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +@Path("/bar") +public class Ticket4850Resource { + @GET + @Path("") + public ExtensionsResource test( + + ) {return new ExtensionsResource();} + + @Schema( + description = "ExtensionsResource", + extensions = { + @Extension(name = "x-user", properties = { + @ExtensionProperty(name = "name", value = "Josh")}), + @Extension(name = "user-extensions", properties = { + @ExtensionProperty(name = "lastName", value = "Hart"), + @ExtensionProperty(name = "address", value = "House")}) + } + ) + private class ExtensionsResource { + public ExtensionsResource() {} + } +}