diff --git a/bin/configs/spring-boot-useOneOfExtensibleEnum.yaml b/bin/configs/spring-boot-useOneOfExtensibleEnum.yaml new file mode 100644 index 000000000000..1c3a548f31ca --- /dev/null +++ b/bin/configs/spring-boot-useOneOfExtensibleEnum.yaml @@ -0,0 +1,12 @@ +generatorName: spring +outputDir: samples/server/petstore/springboot-useoneofextensibleenum +inputSpec: modules/openapi-generator/src/test/resources/3_0/java/extended-enums.yaml +templateDir: modules/openapi-generator/src/main/resources/JavaSpring +additionalProperties: + groupId: org.openapitools.openapi3 + documentationProvider: springfox + useOneOfExtensibleEnums: true + useOneOfInterfaces: true + useBeanValidation: true + artifactId: spring-boot-useoneofextensibleenum + hideGenerationTimestamp: "true" diff --git a/docs/generators/java-camel.md b/docs/generators/java-camel.md index c17f9e2620a9..5fd797249105 100644 --- a/docs/generators/java-camel.md +++ b/docs/generators/java-camel.md @@ -102,6 +102,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |useFeignClientContextId|Whether to generate Feign client with contextId parameter.| |true| |useFeignClientUrl|Whether to generate Feign client with url parameter.| |true| |useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false| +|useOneOfExtensibleEnums|whether to generate custom extensible enumeration using the extensible enums with interface pattern| |false| |useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false| |useOptional|Use Optional container for optional parameters| |false| |useResponseEntity|Use the `ResponseEntity` type to wrap return values of generated API methods. If disabled, method are annotated using a `@ResponseStatus` annotation, which has the status of the first response declared in the Api definition| |true| diff --git a/docs/generators/spring.md b/docs/generators/spring.md index 11081f66121f..c2d5e7882e94 100644 --- a/docs/generators/spring.md +++ b/docs/generators/spring.md @@ -95,6 +95,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |useFeignClientContextId|Whether to generate Feign client with contextId parameter.| |true| |useFeignClientUrl|Whether to generate Feign client with url parameter.| |true| |useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false| +|useOneOfExtensibleEnums|whether to generate custom extensible enumeration using the extensible enums with interface pattern| |false| |useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false| |useOptional|Use Optional container for optional parameters| |false| |useResponseEntity|Use the `ResponseEntity` type to wrap return values of generated API methods. If disabled, method are annotated using a `@ResponseStatus` annotation, which has the status of the first response declared in the Api definition| |true| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 97e859e80c59..7b692bae023c 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -514,6 +514,7 @@ public Map postProcessAllModels(Map objs) CodegenModel cm = mo.getModel(); if (cm.oneOf.size() > 0) { cm.vendorExtensions.put("x-is-one-of-interface", true); + for (String one : cm.oneOf) { if (!additionalDataMap.containsKey(one)) { additionalDataMap.put(one, new OneOfImplementorAdditionalData(one)); @@ -522,6 +523,10 @@ public Map postProcessAllModels(Map objs) } // if this is oneOf interface, make sure we include the necessary imports for it addImportsToOneOfInterface(modelsImports); + boolean hasOfEnum = (cm.interfaceModels != null) && cm.interfaceModels.stream().anyMatch(m -> m.isEnum) ; + if (hasOfEnum) { + addExtensibleEnum(objs, cm, modelsImports); + } } } } @@ -8385,6 +8390,9 @@ public void addOneOfInterfaceModel(Schema cs, String type) { addOneOfInterfaces.add(cm); } + public void addExtensibleEnum(Map objs, CodegenModel cm, List> imports) { + } + public void addImportsToOneOfInterface(List> imports) { } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java index 8a624b0bbf86..adfd071dc265 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java @@ -101,6 +101,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code public static final String CAMEL_CASE_DOLLAR_SIGN = "camelCaseDollarSign"; public static final String USE_ONE_OF_INTERFACES = "useOneOfInterfaces"; + public static final String USE_ONE_OF_EXTENSIBLE_ENUMS = "useOneOfExtensibleEnums"; public static final String LOMBOK = "lombok"; public static final String DEFAULT_TEST_FOLDER = "${project.build.directory}/generated-test-sources/openapi"; public static final String GENERATE_CONSTRUCTOR_WITH_ALL_ARGS = "generateConstructorWithAllArgs"; @@ -153,6 +154,8 @@ protected enum ENUM_PROPERTY_NAMING_TYPE {MACRO_CASE, legacy, original} protected static final String ENUM_PROPERTY_NAMING_DESC = "Naming convention for enum properties: 'MACRO_CASE', 'legacy' and 'original'"; @Getter protected ENUM_PROPERTY_NAMING_TYPE enumPropertyNaming = ENUM_PROPERTY_NAMING_TYPE.MACRO_CASE; + @Getter @Setter + protected boolean useOneOfExtensibleEnums = false; /** * -- SETTER -- * Set whether discriminator value lookup is case-sensitive or not. @@ -570,6 +573,7 @@ public void processOpts() { convertPropertyToStringAndWriteBack(IMPLICIT_HEADERS_REGEX, this::setImplicitHeadersRegex); convertPropertyToBooleanAndWriteBack(CAMEL_CASE_DOLLAR_SIGN, this::setCamelCaseDollarSign); convertPropertyToBooleanAndWriteBack(USE_ONE_OF_INTERFACES, this::setUseOneOfInterfaces); + convertPropertyToBooleanAndWriteBack(USE_ONE_OF_EXTENSIBLE_ENUMS, this::setUseOneOfExtensibleEnums); convertPropertyToStringAndWriteBack(CodegenConstants.ENUM_PROPERTY_NAMING, this::setEnumPropertyNaming); if (!StringUtils.isEmpty(parentGroupId) && !StringUtils.isEmpty(parentArtifactId) && !StringUtils.isEmpty(parentVersion)) { @@ -621,6 +625,11 @@ public void processOpts() { // used later in recursive import in postProcessingModels importMapping.put("com.fasterxml.jackson.annotation.JsonProperty", "com.fasterxml.jackson.annotation.JsonCreator"); + if (useOneOfExtensibleEnums) { + importMapping.put("DeserializationContext", "com.fasterxml.jackson.databind.DeserializationContext"); + importMapping.put("StdDeserializer", "com.fasterxml.jackson.databind.deser.std.StdDeserializer"); + importMapping.put("JsonParser", "com.fasterxml.jackson.core.JsonParser"); + } convertPropertyToBooleanAndWriteBack(SUPPORT_ASYNC, this::setSupportAsync); convertPropertyToStringAndWriteBack(DATE_LIBRARY, this::setDateLibrary); @@ -2395,16 +2404,51 @@ private boolean shouldBeImplicitHeader(CodegenParameter parameter) { @Override public void addImportsToOneOfInterface(List> imports) { if (jackson) { - for (String i : Arrays.asList("JsonSubTypes", "JsonTypeInfo")) { - Map oneImport = new HashMap<>(); - oneImport.put("import", importMapping.get(i)); - if (!imports.contains(oneImport)) { - imports.add(oneImport); - } + addAdditionalImports(imports, "JsonSubTypes", "JsonTypeInfo"); + } + } + + protected void addAdditionalImports(List> imports, String... additionalImports) { + for (String i : additionalImports) { + Map oneImport = new HashMap<>(); + oneImport.put("import", Objects.requireNonNull(importMapping.get(i), "importMapping not found " + i)); + if (!imports.contains(oneImport)) { + imports.add(oneImport); } } } + @Override + public void addExtensibleEnum(Map objs, CodegenModel cm, List> imports) { + if (jackson) { + addAdditionalImports(imports, + "DeserializationContext", + "JsonDeserialize", + "StdDeserializer", + "JsonValue", + "JsonParser", + "IOException"); + + ExtensibleEnumParam param = new ExtensibleEnumParam(); + cm.vendorExtensions.put("x-extensible-enum", param); + if (cm.oneOf.contains("String")) { + param.useString = true; + param.property = cm.getComposedSchemas().getOneOf().stream().filter(p -> "String".equals(p.datatypeWithEnum)) + .findFirst().orElseThrow(); + // The name of the String property looks like oneOf1 + // Use a sensible name instead + param.stringClassName = cm.classname + "String"; + + } + } + } + + static class ExtensibleEnumParam { + public boolean useString; + public String stringClassName; + public CodegenProperty property; + } + @Override public List getSupportedVendorExtensions() { List extensions = super.getSupportedVendorExtensions(); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index 4d1f9438f057..a0bd7745e514 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -237,6 +237,7 @@ public SpringCodegen() { cliOptions .add(CliOption.newBoolean(RETURN_SUCCESS_CODE, "Generated server returns 2xx code", returnSuccessCode)); cliOptions.add(CliOption.newBoolean(SPRING_CONTROLLER, "Annotate the generated API as a Spring Controller", useSpringController)); + cliOptions.add(CliOption.newBoolean(USE_ONE_OF_EXTENSIBLE_ENUMS, "whether to generate custom extensible enumeration using the extensible enums with interface pattern", useOneOfExtensibleEnums)); CliOption requestMappingOpt = new CliOption(REQUEST_MAPPING_OPTION, "Where to generate the class level @RequestMapping annotation.") diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache index e83ac99867f5..af8353ab2760 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache @@ -6,8 +6,82 @@ {{>typeInfoAnnotation}} {{/discriminator}} {{>generatedAnnotation}} +{{#vendorExtensions.x-extensible-enum}} +@JsonDeserialize(using = {{classname}}.EnumDeserializer.class) +{{/vendorExtensions.x-extensible-enum}} public {{>sealed}}interface {{classname}}{{#vendorExtensions.x-implements}}{{#-first}} extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} {{>permits}}{ {{#discriminator}} public {{propertyType}} {{propertyGetter}}(); {{/discriminator}} + {{^discriminator}} + {{#vendorExtensions.x-extensible-enum}} + {{#useBeanValidation}}@Valid{{/useBeanValidation}} + @JsonValue + String getValue(); + + static {{classname}} fromValue(String value) { + {{#interfaceModels}} + try { + return {{classname}}.fromValue(value); + } catch (IllegalArgumentException e) { + // continue + } + {{/interfaceModels}} + {{#useString}} + return new {{stringClassName}}(value); + {{/useString}} + {{^useString}} + throw new IllegalArgumentException(value + " not supported in classes " + Arrays.asList({{#interfaceModels}}"{{classname}}"{{^-last}}, {{/-last}}{{/interfaceModels}})); + {{/useString}} + } + + // custom jackson deserializer + class EnumDeserializer extends StdDeserializer<{{classname}}> { + + public EnumDeserializer() { + super({{classname}}.class); + } + + @Override + public {{classname}} deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + String value = p.readValueAs(String.class); + return {{classname}}.fromValue(value); + } + } + {{#useString}} + {{#property.description}} + /** + * {{{.}}} + */ + {{/property.description}} + class {{stringClassName}} implements {{classname}} { + private final String value; + public {{stringClassName}}(String value) { + this.value = value; + } + + {{#useBeanValidation}}@NotNull {{#property}}{{>beanValidationCore}} {{/property}}{{/useBeanValidation}} + @Override + public String getValue() { + return value; + } + @Override + public String toString() { + return "{{stringClassName}}:" + value; + } + + @Override + public final boolean equals(Object o) { + if (!(o instanceof {{stringClassName}} )) return false; + return value.equals((({{stringClassName}})o).value); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + } + {{/useString}} + {{/vendorExtensions.x-extensible-enum}} + {{/discriminator}} } \ No newline at end of file diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index 328a8acdb348..b3d427a083f0 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -5501,4 +5501,23 @@ public void testEnumFieldShouldBeFinal_issue21018() throws IOException { JavaFileAssert.assertThat(files.get("SomeObject.java")) .fileContains("private final String value"); } + + @Test + public void testExtensibleEnum() throws IOException { + SpringCodegen codegen = new SpringCodegen(); + codegen.setUseOneOfExtensibleEnums(true); + codegen.setUseBeanValidation(true); + Map files = generateFiles(codegen,"src/test/resources/3_0/java/extended-enums.yaml"); + JavaFileAssert.assertThat(files.get("Country.java")) + .fileContains("@JsonDeserialize(using = Country.EnumDeserializer.class)", + "String getValue()", + "class EnumDeserializer extends StdDeserializer", + "class CountryString implements Country"); + JavaFileAssert.assertThat(files.get("CountryOrOther.java")) + .fileContains("@JsonDeserialize(using = CountryOrOther.EnumDeserializer.class)", + "String getValue()", + "class EnumDeserializer extends StdDeserializer", + "static CountryOrOther fromValue(String value)"); + + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/java/extended-enums.yaml b/modules/openapi-generator/src/test/resources/3_0/java/extended-enums.yaml new file mode 100644 index 000000000000..ebc6f59ac520 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/java/extended-enums.yaml @@ -0,0 +1,54 @@ +openapi: 3.0.3 +info: + title: Extended enum + description: '' + version: v1 +servers: + - url: http://localhost + description: test +paths: + /test: + get: + operationId: test + responses: + 200: + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Address' +components: + schemas: + Address: + properties: + street: + type: string + countryOrString: + $ref: '#/components/schemas/Country' + countryOrOther: + $ref: '#/components/schemas/countryOrOther' + Country: + oneOf: + - $ref: '#/components/schemas/SubsetCountry' + - type: string + description: other coutries + title: OtherCountry + pattern: ^[A-Z]{2}$ + SubsetCountry: + type: string + enum: + - BE + - LU + - NL + countryOrOther: + oneOf: + - $ref: '#/components/schemas/SubsetCountry' + - $ref: '#/components/schemas/OtherCountryEnum' + OtherCountryEnum: + type: string + enum: + - IT + - DE + - FR + + diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/.openapi-generator-ignore b/samples/server/petstore/springboot-useoneofextensibleenum/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/.openapi-generator/FILES b/samples/server/petstore/springboot-useoneofextensibleenum/.openapi-generator/FILES new file mode 100644 index 000000000000..657c9d127d0c --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/.openapi-generator/FILES @@ -0,0 +1,18 @@ +README.md +pom.xml +src/main/java/org/openapitools/OpenApiGeneratorApplication.java +src/main/java/org/openapitools/RFC3339DateFormat.java +src/main/java/org/openapitools/api/ApiUtil.java +src/main/java/org/openapitools/api/TestApi.java +src/main/java/org/openapitools/configuration/EnumConverterConfiguration.java +src/main/java/org/openapitools/configuration/HomeController.java +src/main/java/org/openapitools/configuration/SpringFoxConfiguration.java +src/main/java/org/openapitools/model/Address.java +src/main/java/org/openapitools/model/Country.java +src/main/java/org/openapitools/model/CountryOrOther.java +src/main/java/org/openapitools/model/OtherCountryEnum.java +src/main/java/org/openapitools/model/SubsetCountry.java +src/main/resources/application.properties +src/main/resources/openapi.yaml +src/main/resources/static/swagger-ui.html +src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/.openapi-generator/VERSION b/samples/server/petstore/springboot-useoneofextensibleenum/.openapi-generator/VERSION new file mode 100644 index 000000000000..4c631cf217a2 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.14.0-SNAPSHOT diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/README.md b/samples/server/petstore/springboot-useoneofextensibleenum/README.md new file mode 100644 index 000000000000..54292416f462 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/README.md @@ -0,0 +1,27 @@ +# OpenAPI generated server + +Spring Boot Server + +## Overview +This server was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. +By using the [OpenAPI-Spec](https://openapis.org), you can easily generate a server stub. +This is an example of building a OpenAPI-enabled server in Java using the SpringBoot framework. + +The underlying library integrating OpenAPI to Spring Boot is [springfox](https://github.com/springfox/springfox). +Springfox will generate an OpenAPI v2 (fka Swagger RESTful API Documentation Specification) specification based on the +generated Controller and Model classes. The specification is available to download using the following url: +http://localhost:8080/v2/api-docs/ + +**HEADS-UP**: Springfox is deprecated for removal in version 6.0.0 of openapi-generator. The project seems to be no longer +maintained (last commit is of Oct 14, 2020). It works with Spring Boot 2.5.x but not with 2.6. Spring Boot 2.5 is +supported until 2022-05-19. Users of openapi-generator should migrate to the springdoc documentation provider which is, +as an added bonus, OpenAPI v3 compatible. + + + +Start your server as a simple java application + +You can view the api documentation in swagger-ui by pointing to +http://localhost:8080/swagger-ui.html + +Change default port value in application.properties \ No newline at end of file diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/pom.xml b/samples/server/petstore/springboot-useoneofextensibleenum/pom.xml new file mode 100644 index 000000000000..9acd9fad3941 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/pom.xml @@ -0,0 +1,91 @@ + + 4.0.0 + org.openapitools.openapi3 + spring-boot-useoneofextensibleenum + jar + spring-boot-useoneofextensibleenum + v1 + + 1.8 + ${java.version} + ${java.version} + UTF-8 + 2.9.2 + 5.3.1 + + + org.springframework.boot + spring-boot-starter-parent + 2.5.14 + + + + src/main/java + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.data + spring-data-commons + + + + io.springfox + springfox-swagger2 + ${springfox.version} + + + org.webjars + swagger-ui + ${swagger-ui.version} + + + org.webjars + webjars-locator-core + + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + org.openapitools + jackson-databind-nullable + 0.2.6 + + + + org.springframework.boot + spring-boot-starter-validation + + + com.fasterxml.jackson.core + jackson-databind + + + org.springframework.boot + spring-boot-starter-test + test + + + diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/OpenApiGeneratorApplication.java b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/OpenApiGeneratorApplication.java new file mode 100644 index 000000000000..97252a8a9402 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/OpenApiGeneratorApplication.java @@ -0,0 +1,30 @@ +package org.openapitools; + +import com.fasterxml.jackson.databind.Module; +import org.openapitools.jackson.nullable.JsonNullableModule; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.context.annotation.FullyQualifiedAnnotationBeanNameGenerator; + +@SpringBootApplication( + nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class +) +@ComponentScan( + basePackages = {"org.openapitools", "org.openapitools.api" , "org.openapitools.configuration"}, + nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class +) +public class OpenApiGeneratorApplication { + + public static void main(String[] args) { + SpringApplication.run(OpenApiGeneratorApplication.class, args); + } + + @Bean(name = "org.openapitools.OpenApiGeneratorApplication.jsonNullableModule") + public Module jsonNullableModule() { + return new JsonNullableModule(); + } + +} \ No newline at end of file diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/RFC3339DateFormat.java b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/RFC3339DateFormat.java new file mode 100644 index 000000000000..bcd3936d8b34 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/RFC3339DateFormat.java @@ -0,0 +1,38 @@ +package org.openapitools; + +import com.fasterxml.jackson.databind.util.StdDateFormat; + +import java.text.DateFormat; +import java.text.FieldPosition; +import java.text.ParsePosition; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +public class RFC3339DateFormat extends DateFormat { + private static final long serialVersionUID = 1L; + private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC"); + + private final StdDateFormat fmt = new StdDateFormat() + .withTimeZone(TIMEZONE_Z) + .withColonInTimeZone(true); + + public RFC3339DateFormat() { + this.calendar = new GregorianCalendar(); + } + + @Override + public Date parse(String source, ParsePosition pos) { + return fmt.parse(source, pos); + } + + @Override + public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { + return fmt.format(date, toAppendTo, fieldPosition); + } + + @Override + public Object clone() { + return this; + } +} \ No newline at end of file diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/api/ApiUtil.java b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/api/ApiUtil.java new file mode 100644 index 000000000000..1245b1dd0ccf --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/api/ApiUtil.java @@ -0,0 +1,19 @@ +package org.openapitools.api; + +import org.springframework.web.context.request.NativeWebRequest; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class ApiUtil { + public static void setExampleResponse(NativeWebRequest req, String contentType, String example) { + try { + HttpServletResponse res = req.getNativeResponse(HttpServletResponse.class); + res.setCharacterEncoding("UTF-8"); + res.addHeader("Content-Type", contentType); + res.getWriter().print(example); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/api/TestApi.java b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/api/TestApi.java new file mode 100644 index 000000000000..006e0e69f1d9 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/api/TestApi.java @@ -0,0 +1,70 @@ +/** + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (7.14.0-SNAPSHOT). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +package org.openapitools.api; + +import org.openapitools.model.Address; +import io.swagger.annotations.*; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.multipart.MultipartFile; + +import javax.validation.Valid; +import javax.validation.constraints.*; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import javax.annotation.Generated; + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.14.0-SNAPSHOT") +@Validated +@Api(value = "test", description = "the test API") +public interface TestApi { + + default Optional getRequest() { + return Optional.empty(); + } + + /** + * GET /test + * + * @return Successful operation (status code 200) + */ + @ApiOperation( + value = "", + nickname = "test", + notes = "", + response = Address.class + ) + @ApiResponses({ + @ApiResponse(code = 200, message = "Successful operation", response = Address.class) + }) + @RequestMapping( + method = RequestMethod.GET, + value = "/test", + produces = { "application/json" } + ) + + default ResponseEntity
test( + + ) { + getRequest().ifPresent(request -> { + for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = "{ \"street\" : \"street\", \"countryOrString\" : \"BE\" }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + + } + +} diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/api/TestApiController.java b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/api/TestApiController.java new file mode 100644 index 000000000000..de58f37a7eca --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/api/TestApiController.java @@ -0,0 +1,46 @@ +package org.openapitools.api; + +import org.openapitools.model.Address; + + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.context.request.NativeWebRequest; + +import javax.validation.constraints.*; +import javax.validation.Valid; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import javax.annotation.Generated; + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.14.0-SNAPSHOT") +@Controller +@RequestMapping("${openapi.extendedEnum.base-path:}") +public class TestApiController implements TestApi { + + private final NativeWebRequest request; + + @Autowired + public TestApiController(NativeWebRequest request) { + this.request = request; + } + + @Override + public Optional getRequest() { + return Optional.ofNullable(request); + } + +} diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/configuration/EnumConverterConfiguration.java b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/configuration/EnumConverterConfiguration.java new file mode 100644 index 000000000000..3fce79ed6a94 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/configuration/EnumConverterConfiguration.java @@ -0,0 +1,32 @@ +package org.openapitools.configuration; + +import org.openapitools.model.OtherCountryEnum; +import org.openapitools.model.SubsetCountry; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.converter.Converter; + +@Configuration(value = "org.openapitools.configuration.enumConverterConfiguration") +public class EnumConverterConfiguration { + + @Bean(name = "org.openapitools.configuration.EnumConverterConfiguration.otherCountryEnumConverter") + Converter otherCountryEnumConverter() { + return new Converter() { + @Override + public OtherCountryEnum convert(String source) { + return OtherCountryEnum.fromValue(source); + } + }; + } + @Bean(name = "org.openapitools.configuration.EnumConverterConfiguration.subsetCountryConverter") + Converter subsetCountryConverter() { + return new Converter() { + @Override + public SubsetCountry convert(String source) { + return SubsetCountry.fromValue(source); + } + }; + } + +} diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/configuration/HomeController.java b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/configuration/HomeController.java new file mode 100644 index 000000000000..e390f86f5b73 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/configuration/HomeController.java @@ -0,0 +1,28 @@ +package org.openapitools.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.GetMapping; + +/** + * Home redirection to OpenAPI api documentation + */ +@Controller +public class HomeController { + + static final String API_DOCS_PATH = "/v2/api-docs"; + + @GetMapping(value = "/swagger-config.yaml", produces = "text/plain") + @ResponseBody + public String swaggerConfig() { + return "url: " + API_DOCS_PATH + "\n"; + } + + @RequestMapping("/") + public String index() { + return "redirect:swagger-ui.html"; + } + +} \ No newline at end of file diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/configuration/SpringFoxConfiguration.java b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/configuration/SpringFoxConfiguration.java new file mode 100644 index 000000000000..3df03eb1e246 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/configuration/SpringFoxConfiguration.java @@ -0,0 +1,71 @@ +package org.openapitools.configuration; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import org.springframework.web.util.UriComponentsBuilder; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.paths.Paths; +import springfox.documentation.spring.web.paths.RelativePathProvider; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import javax.annotation.Generated; +import javax.servlet.ServletContext; + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.14.0-SNAPSHOT") +@Configuration +@EnableSwagger2 +public class SpringFoxConfiguration { + + ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title("Extended enum") + .description("No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)") + .license("") + .licenseUrl("http://unlicense.org") + .termsOfServiceUrl("") + .version("v1") + .contact(new Contact("","", "")) + .build(); + } + + @Bean + public Docket customImplementation(ServletContext servletContext, @Value("${openapi.extendedEnum.base-path:}") String basePath) { + return new Docket(DocumentationType.SWAGGER_2) + .select() + .apis(RequestHandlerSelectors.basePackage("org.openapitools.api")) + .build() + .pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath)) + .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class) + .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class) + .apiInfo(apiInfo()); + } + + class BasePathAwareRelativePathProvider extends RelativePathProvider { + private String basePath; + + public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) { + super(servletContext); + this.basePath = basePath; + } + + @Override + protected String applicationPath() { + return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString()); + } + + @Override + public String getOperationPath(String operationPath) { + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/"); + return Paths.removeAdjacentForwardSlashes( + uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString()); + } + } + +} diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/Address.java b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/Address.java new file mode 100644 index 000000000000..d610d14bb0b6 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/Address.java @@ -0,0 +1,135 @@ +package org.openapitools.model; + +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.openapitools.model.Country; +import org.openapitools.model.CountryOrOther; +import org.springframework.lang.Nullable; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; + + +import java.util.*; +import javax.annotation.Generated; + +/** + * Address + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.14.0-SNAPSHOT") +public class Address { + + private @Nullable String street; + + private @Nullable Country countryOrString; + + private @Nullable CountryOrOther countryOrOther; + + public Address street(String street) { + this.street = street; + return this; + } + + /** + * Get street + * @return street + */ + + @ApiModelProperty(value = "") + @JsonProperty("street") + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public Address countryOrString(Country countryOrString) { + this.countryOrString = countryOrString; + return this; + } + + /** + * Get countryOrString + * @return countryOrString + */ + @Valid + @ApiModelProperty(value = "") + @JsonProperty("countryOrString") + public Country getCountryOrString() { + return countryOrString; + } + + public void setCountryOrString(Country countryOrString) { + this.countryOrString = countryOrString; + } + + public Address countryOrOther(CountryOrOther countryOrOther) { + this.countryOrOther = countryOrOther; + return this; + } + + /** + * Get countryOrOther + * @return countryOrOther + */ + @Valid + @ApiModelProperty(value = "") + @JsonProperty("countryOrOther") + public CountryOrOther getCountryOrOther() { + return countryOrOther; + } + + public void setCountryOrOther(CountryOrOther countryOrOther) { + this.countryOrOther = countryOrOther; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Address address = (Address) o; + return Objects.equals(this.street, address.street) && + Objects.equals(this.countryOrString, address.countryOrString) && + Objects.equals(this.countryOrOther, address.countryOrOther); + } + + @Override + public int hashCode() { + return Objects.hash(street, countryOrString, countryOrOther); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Address {\n"); + sb.append(" street: ").append(toIndentedString(street)).append("\n"); + sb.append(" countryOrString: ").append(toIndentedString(countryOrString)).append("\n"); + sb.append(" countryOrOther: ").append(toIndentedString(countryOrOther)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/Country.java b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/Country.java new file mode 100644 index 000000000000..4aee0773b862 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/Country.java @@ -0,0 +1,83 @@ +package org.openapitools.model; + +import java.net.URI; +import java.util.Objects; +import org.openapitools.model.SubsetCountry; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.core.JsonParser; +import java.io.IOException; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; + + +import java.util.*; +import javax.annotation.Generated; + + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.14.0-SNAPSHOT") +@JsonDeserialize(using = Country.EnumDeserializer.class) +public interface Country { + @Valid + @JsonValue + String getValue(); + + static Country fromValue(String value) { + try { + return SubsetCountry.fromValue(value); + } catch (IllegalArgumentException e) { + // continue + } + return new CountryString(value); + } + + // custom jackson deserializer + class EnumDeserializer extends StdDeserializer { + + public EnumDeserializer() { + super(Country.class); + } + + @Override + public Country deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + String value = p.readValueAs(String.class); + return Country.fromValue(value); + } + } + /** + * other coutries + */ + class CountryString implements Country { + private final String value; + public CountryString(String value) { + this.value = value; + } + + @NotNull @Pattern(regexp = "^[A-Z]{2}$") + @Override + public String getValue() { + return value; + } + @Override + public String toString() { + return "CountryString:" + value; + } + + @Override + public final boolean equals(Object o) { + if (!(o instanceof CountryString )) return false; + return value.equals(((CountryString)o).value); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + } +} diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/CountryOrOther.java b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/CountryOrOther.java new file mode 100644 index 000000000000..a980297aac24 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/CountryOrOther.java @@ -0,0 +1,60 @@ +package org.openapitools.model; + +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonTypeName; +import org.openapitools.model.OtherCountryEnum; +import org.openapitools.model.SubsetCountry; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.core.JsonParser; +import java.io.IOException; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; + + +import java.util.*; +import javax.annotation.Generated; + + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.14.0-SNAPSHOT") +@JsonDeserialize(using = CountryOrOther.EnumDeserializer.class) +public interface CountryOrOther { + @Valid + @JsonValue + String getValue(); + + static CountryOrOther fromValue(String value) { + try { + return SubsetCountry.fromValue(value); + } catch (IllegalArgumentException e) { + // continue + } + try { + return OtherCountryEnum.fromValue(value); + } catch (IllegalArgumentException e) { + // continue + } + throw new IllegalArgumentException(value + " not supported in classes " + Arrays.asList("SubsetCountry", "OtherCountryEnum")); + } + + // custom jackson deserializer + class EnumDeserializer extends StdDeserializer { + + public EnumDeserializer() { + super(CountryOrOther.class); + } + + @Override + public CountryOrOther deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + String value = p.readValueAs(String.class); + return CountryOrOther.fromValue(value); + } + } +} diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/OtherCountryEnum.java b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/OtherCountryEnum.java new file mode 100644 index 000000000000..38f25d415599 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/OtherCountryEnum.java @@ -0,0 +1,58 @@ +package org.openapitools.model; + +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonTypeName; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; + + +import java.util.*; +import javax.annotation.Generated; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Gets or Sets OtherCountryEnum + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.14.0-SNAPSHOT") +public enum OtherCountryEnum implements CountryOrOther { + + IT("IT"), + + DE("DE"), + + FR("FR"); + + private final String value; + + OtherCountryEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static OtherCountryEnum fromValue(String value) { + for (OtherCountryEnum b : OtherCountryEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/SubsetCountry.java b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/SubsetCountry.java new file mode 100644 index 000000000000..e0ab73cd6b33 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/java/org/openapitools/model/SubsetCountry.java @@ -0,0 +1,58 @@ +package org.openapitools.model; + +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonTypeName; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; + + +import java.util.*; +import javax.annotation.Generated; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Gets or Sets SubsetCountry + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.14.0-SNAPSHOT") +public enum SubsetCountry implements Country, CountryOrOther { + + BE("BE"), + + LU("LU"), + + NL("NL"); + + private final String value; + + SubsetCountry(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static SubsetCountry fromValue(String value) { + for (SubsetCountry b : SubsetCountry.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/resources/application.properties b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/resources/application.properties new file mode 100644 index 000000000000..7e90813e59b2 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/resources/application.properties @@ -0,0 +1,3 @@ +server.port=8080 +spring.jackson.date-format=org.openapitools.RFC3339DateFormat +spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/resources/openapi.yaml b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/resources/openapi.yaml new file mode 100644 index 000000000000..e4a8811f3b59 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/resources/openapi.yaml @@ -0,0 +1,60 @@ +openapi: 3.0.3 +info: + description: "" + title: Extended enum + version: v1 +servers: +- description: test + url: http://localhost +paths: + /test: + get: + operationId: test + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/Address' + description: Successful operation + x-accepts: + - application/json +components: + schemas: + Address: + example: + street: street + countryOrOther: null + countryOrString: BE + properties: + street: + type: string + countryOrString: + $ref: '#/components/schemas/Country' + countryOrOther: + $ref: '#/components/schemas/countryOrOther' + Country: + oneOf: + - $ref: '#/components/schemas/SubsetCountry' + - description: other coutries + pattern: "^[A-Z]{2}$" + title: OtherCountry + type: string + x-one-of-name: Country + SubsetCountry: + enum: + - BE + - LU + - NL + type: string + countryOrOther: + oneOf: + - $ref: '#/components/schemas/SubsetCountry' + - $ref: '#/components/schemas/OtherCountryEnum' + x-one-of-name: CountryOrOther + OtherCountryEnum: + enum: + - IT + - DE + - FR + type: string diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/main/resources/static/swagger-ui.html b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/resources/static/swagger-ui.html new file mode 100644 index 000000000000..f85b6654f67d --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/main/resources/static/swagger-ui.html @@ -0,0 +1,60 @@ + + + + + + Swagger UI + + + + + + + +
+ + + + + + diff --git a/samples/server/petstore/springboot-useoneofextensibleenum/src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java b/samples/server/petstore/springboot-useoneofextensibleenum/src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java new file mode 100644 index 000000000000..3681f67e7705 --- /dev/null +++ b/samples/server/petstore/springboot-useoneofextensibleenum/src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java @@ -0,0 +1,13 @@ +package org.openapitools; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class OpenApiGeneratorApplicationTests { + + @Test + void contextLoads() { + } + +} \ No newline at end of file