diff --git a/.circleci/parallel.sh b/.circleci/parallel.sh index bf67b7738be..804100e29eb 100755 --- a/.circleci/parallel.sh +++ b/.circleci/parallel.sh @@ -29,6 +29,8 @@ elif [ "$JOB_ID" = "testJava17ClientSamples" ]; then echo "Running job $JOB_ID ..." java -version mvn -version + gradle --version + cat ./.circleci/testJava17ClientSamples.sh | parallel else diff --git a/.circleci/testJava17ClientSamples.sh b/.circleci/testJava17ClientSamples.sh index 15338a264ae..bb5187fb8b3 100644 --- a/.circleci/testJava17ClientSamples.sh +++ b/.circleci/testJava17ClientSamples.sh @@ -1,3 +1,3 @@ - (cd samples/client/petstore/java && mvn test) + (cd samples/client/petstore/java && gradle wrapper && gradle test) (cd samples/client/3_0_3_unit_test/java && mvn test) (cd samples/client/3_1_0_unit_test/java && mvn test) \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7bc90ae5294..cdc3ff9feec 100644 --- a/.gitignore +++ b/.gitignore @@ -49,7 +49,6 @@ test-output/ #Java/Android **/.gradle - # Python *.pyc __pycache__ diff --git a/bin/generate_samples_configs/java.yaml b/bin/generate_samples_configs/java.yaml index ae13418096b..7b008820445 100644 --- a/bin/generate_samples_configs/java.yaml +++ b/bin/generate_samples_configs/java.yaml @@ -3,4 +3,5 @@ outputDir: samples/client/petstore/java inputSpec: src/test/resources/3_0/python/petstore_customized.yaml additionalProperties: artifactId: petstore - hideGenerationTimestamp: "true" \ No newline at end of file + hideGenerationTimestamp: "true" + buildTool: gradle \ No newline at end of file diff --git a/docs/generators/java.md b/docs/generators/java.md index 93ff4abcfe7..593df646bf3 100644 --- a/docs/generators/java.md +++ b/docs/generators/java.md @@ -23,6 +23,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |artifactDescription|artifact description in generated pom.xml| |OpenAPI Java| |artifactUrl|artifact URL in generated pom.xml| |https://github.com/openapi-json-schema-tools/openapi-json-schema-generator| |artifactVersion|artifact version in generated pom.xml. This also becomes part of the generated library's filename| |1.0.0| +|buildTool|the build automation tool used in generated code|
**maven**
Use maven
**gradle**
Use gradle
|maven| |developerEmail|developer email in generated pom.xml| |team@openapijsonschematools.org| |developerName|developer name in generated pom.xml| |OpenAPI-Generator Contributors| |developerOrganization|developer organization in generated pom.xml| |OpenAPITools.org| diff --git a/samples/client/3_0_3_unit_test/java/.gitignore b/samples/client/3_0_3_unit_test/java/.gitignore new file mode 100644 index 00000000000..3a4ec036d04 --- /dev/null +++ b/samples/client/3_0_3_unit_test/java/.gitignore @@ -0,0 +1,9 @@ +build/ +.gradle/ +.idea/ +target/ + +# gradle wrapper +gradlew +gradlew.bat +gradle/ \ No newline at end of file diff --git a/samples/client/3_0_3_unit_test/java/.openapi-generator/FILES b/samples/client/3_0_3_unit_test/java/.openapi-generator/FILES index 2ae8ae4665a..ff3f42da119 100644 --- a/samples/client/3_0_3_unit_test/java/.openapi-generator/FILES +++ b/samples/client/3_0_3_unit_test/java/.openapi-generator/FILES @@ -1,3 +1,4 @@ +.gitignore README.md docs/RootServerInfo.md docs/components/schemas/AdditionalpropertiesAllowsASchemaWhichShouldValidate.md diff --git a/samples/client/3_0_3_unit_test/java/README.md b/samples/client/3_0_3_unit_test/java/README.md index 6d0d0cd6b04..b201a589706 100644 --- a/samples/client/3_0_3_unit_test/java/README.md +++ b/samples/client/3_0_3_unit_test/java/README.md @@ -41,19 +41,6 @@ Add this dependency to your project's POM: ``` -### Others - -At first generate the JAR by executing: - -```shell -mvn clean package -``` - -Then manually install the following JARs: - -- `target/unit-test-api-0.0.1.jar` -- `target/lib/*.jar` - ## Usage Notes ### Validation, Immutability, and Data Type diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/header/Rfc6570Serializer.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/header/Rfc6570Serializer.java index 11707301d30..5f1d6cc179f 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/header/Rfc6570Serializer.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/header/Rfc6570Serializer.java @@ -27,7 +27,11 @@ private static String percentEncode(String s) throws NotImplementedException { .replace("%7E", "~"); // This could be done faster with more hand-crafted code. } catch (UnsupportedEncodingException wow) { - throw new NotImplementedException(wow.getMessage()); + @Nullable String msg = wow.getMessage(); + if (msg == null) { + throw new NotImplementedException("UnsupportedEncodingException thrown"); + } + throw new NotImplementedException(msg); } } diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/parameter/CookieSerializer.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/parameter/CookieSerializer.java index dcd3b6faf6b..4ec9f6ef59d 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/parameter/CookieSerializer.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/parameter/CookieSerializer.java @@ -16,7 +16,7 @@ protected CookieSerializer(Map parameters) { public String serialize(Map inData) throws NotImplementedException { String result = ""; - Map sortedData = new TreeMap<>(inData); + Map sortedData = new TreeMap<>(inData); for (Map.Entry entry: sortedData.entrySet()) { String mapKey = entry.getKey(); @Nullable Parameter parameter = parameters.get(mapKey); diff --git a/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/header/SchemaHeaderTest.java b/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/header/SchemaHeaderTest.java index 6f2c8ce93cf..954d0e33a6b 100644 --- a/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/header/SchemaHeaderTest.java +++ b/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/header/SchemaHeaderTest.java @@ -34,7 +34,7 @@ public void testSerialization() throws ValidationException, NotImplementedExcept mapPayload.put("R", 100); mapPayload.put("G", 200); mapPayload.put("B", 150); - var testCases = List.of( + List testCases = List.of( new ParamTestCase( null, Map.of("color", List.of("")) @@ -135,28 +135,43 @@ public void testDeserialization() throws ValidationException, NotImplementedExce assertNull(deserialized); header = getHeader(NumberJsonSchema.NumberJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("1"), false, configuration); + var deserializedOne = header.deserialize(List.of("1"), false, configuration); + if (deserializedOne == null) { + throw new RuntimeException("invalid value"); + } @Nullable Object expected = 1L; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedOne); header = getHeader(NumberJsonSchema.NumberJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("3.14"), false, configuration); + var deserialized314 = header.deserialize(List.of("3.14"), false, configuration); + if (deserialized314 == null) { + throw new RuntimeException("invalid value"); + } expected = 3.14d; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserialized314); header = getHeader(StringJsonSchema.StringJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("blue"), false, configuration); + var deserializedBlue = header.deserialize(List.of("blue"), false, configuration); + if (deserializedBlue == null) { + throw new RuntimeException("invalid value"); + } expected = "blue"; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedBlue); header = getHeader(StringJsonSchema.StringJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("hello world"), false, configuration); + var deserializedHelloWorld = header.deserialize(List.of("hello world"), false, configuration); + if (deserializedHelloWorld == null) { + throw new RuntimeException("invalid value"); + } expected = "hello world"; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedHelloWorld); header = getHeader(ListJsonSchema.ListJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("blue", "black", "brown"), false, configuration); + var deserializedList = header.deserialize(List.of("blue", "black", "brown"), false, configuration); + if (deserializedList == null) { + throw new RuntimeException("invalid value"); + } expected = List.of("blue", "black", "brown"); - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedList); } } diff --git a/samples/client/3_1_0_unit_test/java/.gitignore b/samples/client/3_1_0_unit_test/java/.gitignore new file mode 100644 index 00000000000..3a4ec036d04 --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/.gitignore @@ -0,0 +1,9 @@ +build/ +.gradle/ +.idea/ +target/ + +# gradle wrapper +gradlew +gradlew.bat +gradle/ \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/.openapi-generator/FILES b/samples/client/3_1_0_unit_test/java/.openapi-generator/FILES index e00760803ba..317b3ba4e53 100644 --- a/samples/client/3_1_0_unit_test/java/.openapi-generator/FILES +++ b/samples/client/3_1_0_unit_test/java/.openapi-generator/FILES @@ -1,3 +1,4 @@ +.gitignore README.md docs/RootServerInfo.md docs/components/schemas/ASchemaGivenForPrefixitems.md diff --git a/samples/client/3_1_0_unit_test/java/README.md b/samples/client/3_1_0_unit_test/java/README.md index e14c9cfe8ec..0334e475923 100644 --- a/samples/client/3_1_0_unit_test/java/README.md +++ b/samples/client/3_1_0_unit_test/java/README.md @@ -41,19 +41,6 @@ Add this dependency to your project's POM: ``` -### Others - -At first generate the JAR by executing: - -```shell -mvn clean package -``` - -Then manually install the following JARs: - -- `target/unit-test-api-0.0.1.jar` -- `target/lib/*.jar` - ## Usage Notes ### Validation, Immutability, and Data Type diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/header/Rfc6570Serializer.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/header/Rfc6570Serializer.java index 11707301d30..5f1d6cc179f 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/header/Rfc6570Serializer.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/header/Rfc6570Serializer.java @@ -27,7 +27,11 @@ private static String percentEncode(String s) throws NotImplementedException { .replace("%7E", "~"); // This could be done faster with more hand-crafted code. } catch (UnsupportedEncodingException wow) { - throw new NotImplementedException(wow.getMessage()); + @Nullable String msg = wow.getMessage(); + if (msg == null) { + throw new NotImplementedException("UnsupportedEncodingException thrown"); + } + throw new NotImplementedException(msg); } } diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/parameter/CookieSerializer.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/parameter/CookieSerializer.java index dcd3b6faf6b..4ec9f6ef59d 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/parameter/CookieSerializer.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/parameter/CookieSerializer.java @@ -16,7 +16,7 @@ protected CookieSerializer(Map parameters) { public String serialize(Map inData) throws NotImplementedException { String result = ""; - Map sortedData = new TreeMap<>(inData); + Map sortedData = new TreeMap<>(inData); for (Map.Entry entry: sortedData.entrySet()) { String mapKey = entry.getKey(); @Nullable Parameter parameter = parameters.get(mapKey); diff --git a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/header/SchemaHeaderTest.java b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/header/SchemaHeaderTest.java index 6f2c8ce93cf..954d0e33a6b 100644 --- a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/header/SchemaHeaderTest.java +++ b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/header/SchemaHeaderTest.java @@ -34,7 +34,7 @@ public void testSerialization() throws ValidationException, NotImplementedExcept mapPayload.put("R", 100); mapPayload.put("G", 200); mapPayload.put("B", 150); - var testCases = List.of( + List testCases = List.of( new ParamTestCase( null, Map.of("color", List.of("")) @@ -135,28 +135,43 @@ public void testDeserialization() throws ValidationException, NotImplementedExce assertNull(deserialized); header = getHeader(NumberJsonSchema.NumberJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("1"), false, configuration); + var deserializedOne = header.deserialize(List.of("1"), false, configuration); + if (deserializedOne == null) { + throw new RuntimeException("invalid value"); + } @Nullable Object expected = 1L; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedOne); header = getHeader(NumberJsonSchema.NumberJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("3.14"), false, configuration); + var deserialized314 = header.deserialize(List.of("3.14"), false, configuration); + if (deserialized314 == null) { + throw new RuntimeException("invalid value"); + } expected = 3.14d; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserialized314); header = getHeader(StringJsonSchema.StringJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("blue"), false, configuration); + var deserializedBlue = header.deserialize(List.of("blue"), false, configuration); + if (deserializedBlue == null) { + throw new RuntimeException("invalid value"); + } expected = "blue"; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedBlue); header = getHeader(StringJsonSchema.StringJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("hello world"), false, configuration); + var deserializedHelloWorld = header.deserialize(List.of("hello world"), false, configuration); + if (deserializedHelloWorld == null) { + throw new RuntimeException("invalid value"); + } expected = "hello world"; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedHelloWorld); header = getHeader(ListJsonSchema.ListJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("blue", "black", "brown"), false, configuration); + var deserializedList = header.deserialize(List.of("blue", "black", "brown"), false, configuration); + if (deserializedList == null) { + throw new RuntimeException("invalid value"); + } expected = List.of("blue", "black", "brown"); - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedList); } } diff --git a/samples/client/petstore/java/.gitignore b/samples/client/petstore/java/.gitignore new file mode 100644 index 00000000000..3a4ec036d04 --- /dev/null +++ b/samples/client/petstore/java/.gitignore @@ -0,0 +1,9 @@ +build/ +.gradle/ +.idea/ +target/ + +# gradle wrapper +gradlew +gradlew.bat +gradle/ \ No newline at end of file diff --git a/samples/client/petstore/java/.openapi-generator/FILES b/samples/client/petstore/java/.openapi-generator/FILES index 8ee910d207d..b0ac369c015 100644 --- a/samples/client/petstore/java/.openapi-generator/FILES +++ b/samples/client/petstore/java/.openapi-generator/FILES @@ -1,4 +1,6 @@ +.gitignore README.md +build.gradle.kts docs/RootServerInfo.md docs/apis/paths/Anotherfakedummy.md docs/apis/paths/Commonparamsubdir.md @@ -751,7 +753,7 @@ docs/servers/RootServer1.md docs/servers/RootServer2.md docs/servers/rootserver0/RootServer0Variables.md docs/servers/rootserver1/RootServer1Variables.md -pom.xml +settings.gradle.kts src/main/java/org/openapijsonschematools/client/RootServerInfo.java src/main/java/org/openapijsonschematools/client/apiclient/ApiClient.java src/main/java/org/openapijsonschematools/client/apis/paths/Anotherfakedummy.java diff --git a/samples/client/petstore/java/README.md b/samples/client/petstore/java/README.md index 5a29bf2142b..592b954f0e2 100644 --- a/samples/client/petstore/java/README.md +++ b/samples/client/petstore/java/README.md @@ -10,50 +10,32 @@ This Java package is automatically generated by the [OpenAPI JSON Schema Generat ## Requirements 1. Java 17 -2. Maven +2. Gradle ## Installation To install the API client library to your local Maven repository, simply execute: ```shell -mvn clean install +gradle wrapper +gradlew clean build ``` -To deploy it to a remote Maven repository instead, configure the settings of the repository and execute: +### Gradle users -```shell -mvn clean deploy -``` - -Refer to the [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) for more information. +Add this dependency to your project's build file: -### Maven users - -Add this dependency to your project's POM: - -```xml - - org.openapijsonschematools - petstore - 1.0.0 - compile - ``` +repositories { + mavenCentral() // Needed if the 'petstore' jar has been published to maven centra + mavenLocal() // Needed if the 'petstore' jar has been published to the local maven repo +} -### Others - -At first generate the JAR by executing: - -```shell -mvn clean package +dependencies { + implementation "org.openapijsonschematools:petstore:1.0.0" +} ``` -Then manually install the following JARs: - -- `target/petstore-1.0.0.jar` -- `target/lib/*.jar` - ## Usage Notes ### Validation, Immutability, and Data Type diff --git a/samples/client/petstore/java/build.gradle.kts b/samples/client/petstore/java/build.gradle.kts new file mode 100644 index 00000000000..5184fd983c7 --- /dev/null +++ b/samples/client/petstore/java/build.gradle.kts @@ -0,0 +1,64 @@ +import org.checkerframework.gradle.plugin.CheckerFrameworkExtension + +plugins { + `java-library` + `maven-publish` + id("org.checkerframework") version "0.6.33" +} + +repositories { + mavenLocal() + maven { + url = uri("https://repo.maven.apache.org/maven2/") + } +} + +dependencies { + implementation("org.checkerframework:checker-qual:3.42.0") + implementation("com.google.code.gson:gson:2.10.1") + testImplementation("junit:junit:4.13.2") + checkerFramework("org.checkerframework:checker:3.42.0") +} + +configure { + checkers = listOf( + "org.checkerframework.checker.nullness.NullnessChecker" + ) +} + +group = "org.openapijsonschematools" +version = "1.0.0" +description = "OpenAPI Java" + +val testsJar by tasks.registering(Jar::class) { + archiveClassifier = "tests" + from(sourceSets["test"].output) +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + } + withSourcesJar() + withJavadocJar() +} + +publishing { + publications.create("maven") { + from(components["java"]) + artifact(testsJar) + } +} + +tasks.wrapper { + gradleVersion = "8.7" +} + +tasks.withType() { + options.encoding = "UTF-8" +} + +tasks.withType() { + enabled = false + options.encoding = "UTF-8" +} diff --git a/samples/client/petstore/java/pom.xml b/samples/client/petstore/java/pom.xml deleted file mode 100644 index d87b77db520..00000000000 --- a/samples/client/petstore/java/pom.xml +++ /dev/null @@ -1,239 +0,0 @@ - - 4.0.0 - org.openapijsonschematools - petstore - jar - petstore - 1.0.0 - https://github.com/openapi-json-schema-tools/openapi-json-schema-generator - OpenAPI Java - - scm:git:git@github.com:openapi-json-schema-tools/openapi-json-schema-generator.git - scm:git:git@github.com:openapi-json-schema-tools/openapi-json-schema-generator.git - https://github.com/openapi-json-schema-tools/openapi-json-schema-generator - - - - - Unlicense - https://www.apache.org/licenses/LICENSE-2.0.html - repo - - - - - - OpenAPI-Generator Contributors - team@openapijsonschematools.org - OpenAPITools.org - http://openapijsonschematools.org - - - - - src/main/java - install - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - true - 128m - 512m - -Xlint:all - - -Awarns - -J-Xss4m - -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED - -J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED - -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED - -J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED - -J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED - -J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED - -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED - -J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED - -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED - - - - org.checkerframework - checker - ${checker-version} - - - - - org.checkerframework.checker.nullness.NullnessChecker - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - 3.0.0-M1 - - - enforce-maven - - enforce - - - - - 2.2.0 - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.2.5 - - - - loggerPath - conf/log4j.properties - - - -Xms512m -Xmx1500m - classes - true - - - - maven-dependency-plugin - - - package - - copy-dependencies - - - ${project.build.directory}/lib - - - - - - - - org.apache.maven.plugins - maven-jar-plugin - 2.2 - - - - jar - test-jar - - - - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.10 - - - add_sources - generate-sources - - add-source - - - - src/main/java - - - - - add_test_sources - generate-test-sources - - add-test-source - - - - src/test/java - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.3.2 - - none - 1.8 - - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - attach-sources - - jar-no-fork - - - - - - - - - - - org.checkerframework - checker-qual - ${checker-version} - - - org.checkerframework - checker - ${checker-version} - - - - com.google.code.gson - gson - 2.10.1 - - - - junit - junit - ${junit-version} - test - - - - 17 - UTF-8 - 3.42.0 - 1.0.0 - 4.13.2 - - diff --git a/samples/client/petstore/java/settings.gradle.kts b/samples/client/petstore/java/settings.gradle.kts new file mode 100644 index 00000000000..588673f49ca --- /dev/null +++ b/samples/client/petstore/java/settings.gradle.kts @@ -0,0 +1,2 @@ +rootProject.name = "petstore" + diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/header/Rfc6570Serializer.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/header/Rfc6570Serializer.java index 11707301d30..5f1d6cc179f 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/header/Rfc6570Serializer.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/header/Rfc6570Serializer.java @@ -27,7 +27,11 @@ private static String percentEncode(String s) throws NotImplementedException { .replace("%7E", "~"); // This could be done faster with more hand-crafted code. } catch (UnsupportedEncodingException wow) { - throw new NotImplementedException(wow.getMessage()); + @Nullable String msg = wow.getMessage(); + if (msg == null) { + throw new NotImplementedException("UnsupportedEncodingException thrown"); + } + throw new NotImplementedException(msg); } } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/parameter/CookieSerializer.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/parameter/CookieSerializer.java index dcd3b6faf6b..4ec9f6ef59d 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/parameter/CookieSerializer.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/parameter/CookieSerializer.java @@ -16,7 +16,7 @@ protected CookieSerializer(Map parameters) { public String serialize(Map inData) throws NotImplementedException { String result = ""; - Map sortedData = new TreeMap<>(inData); + Map sortedData = new TreeMap<>(inData); for (Map.Entry entry: sortedData.entrySet()) { String mapKey = entry.getKey(); @Nullable Parameter parameter = parameters.get(mapKey); diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/securityrequirementobjects/AuthApplier.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/securityrequirementobjects/AuthApplier.java index 7e92135dda0..b54493b928e 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/securityrequirementobjects/AuthApplier.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/securityrequirementobjects/AuthApplier.java @@ -15,7 +15,7 @@ protected static void updateParamsForAuth( String resourcePath, String method, HttpRequest.BodyPublisher bodyPublisher, - Map queryMap, + @Nullable Map queryMap, ApiConfiguration apiConfiguration ) { if (securityRequirementObject == null) { diff --git a/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/header/SchemaHeaderTest.java b/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/header/SchemaHeaderTest.java index 6f2c8ce93cf..954d0e33a6b 100644 --- a/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/header/SchemaHeaderTest.java +++ b/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/header/SchemaHeaderTest.java @@ -34,7 +34,7 @@ public void testSerialization() throws ValidationException, NotImplementedExcept mapPayload.put("R", 100); mapPayload.put("G", 200); mapPayload.put("B", 150); - var testCases = List.of( + List testCases = List.of( new ParamTestCase( null, Map.of("color", List.of("")) @@ -135,28 +135,43 @@ public void testDeserialization() throws ValidationException, NotImplementedExce assertNull(deserialized); header = getHeader(NumberJsonSchema.NumberJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("1"), false, configuration); + var deserializedOne = header.deserialize(List.of("1"), false, configuration); + if (deserializedOne == null) { + throw new RuntimeException("invalid value"); + } @Nullable Object expected = 1L; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedOne); header = getHeader(NumberJsonSchema.NumberJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("3.14"), false, configuration); + var deserialized314 = header.deserialize(List.of("3.14"), false, configuration); + if (deserialized314 == null) { + throw new RuntimeException("invalid value"); + } expected = 3.14d; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserialized314); header = getHeader(StringJsonSchema.StringJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("blue"), false, configuration); + var deserializedBlue = header.deserialize(List.of("blue"), false, configuration); + if (deserializedBlue == null) { + throw new RuntimeException("invalid value"); + } expected = "blue"; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedBlue); header = getHeader(StringJsonSchema.StringJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("hello world"), false, configuration); + var deserializedHelloWorld = header.deserialize(List.of("hello world"), false, configuration); + if (deserializedHelloWorld == null) { + throw new RuntimeException("invalid value"); + } expected = "hello world"; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedHelloWorld); header = getHeader(ListJsonSchema.ListJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("blue", "black", "brown"), false, configuration); + var deserializedList = header.deserialize(List.of("blue", "black", "brown"), false, configuration); + if (deserializedList == null) { + throw new RuntimeException("invalid value"); + } expected = List.of("blue", "black", "brown"); - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedList); } } diff --git a/src/main/java/org/openapijsonschematools/codegen/clicommands/AuthorTemplate.java b/src/main/java/org/openapijsonschematools/codegen/clicommands/AuthorTemplate.java index 679087d254c..5002a811e9f 100644 --- a/src/main/java/org/openapijsonschematools/codegen/clicommands/AuthorTemplate.java +++ b/src/main/java/org/openapijsonschematools/codegen/clicommands/AuthorTemplate.java @@ -3,6 +3,7 @@ import io.airlift.airline.Command; import io.airlift.airline.Option; import org.apache.commons.lang3.StringUtils; +import org.openapijsonschematools.codegen.config.GeneratorSettings; import org.openapijsonschematools.codegen.generators.Generator; import org.openapijsonschematools.codegen.generators.generatorloader.GeneratorLoader; import org.slf4j.Logger; @@ -40,7 +41,7 @@ public class AuthorTemplate extends AbstractCommand { @Override void execute() { - Generator config = GeneratorLoader.getGenerator(generatorName, null, null); + Generator config = GeneratorLoader.getGenerator(generatorName, new GeneratorSettings(), null); String templateDirectory = config.generatorSettings().embeddedTemplateDir; log("Requesting '{}' from embedded resource directory '{}'", generatorName, templateDirectory); diff --git a/src/main/java/org/openapijsonschematools/codegen/clicommands/ConfigHelp.java b/src/main/java/org/openapijsonschematools/codegen/clicommands/ConfigHelp.java index eb4711909b7..c431ad310f9 100644 --- a/src/main/java/org/openapijsonschematools/codegen/clicommands/ConfigHelp.java +++ b/src/main/java/org/openapijsonschematools/codegen/clicommands/ConfigHelp.java @@ -20,6 +20,7 @@ import io.airlift.airline.Command; import io.airlift.airline.Option; import org.apache.commons.lang3.StringUtils; +import org.openapijsonschematools.codegen.config.GeneratorSettings; import org.openapijsonschematools.codegen.generators.generatormetadata.GeneratorMetadata; import org.openapijsonschematools.codegen.generators.models.CliOption; import org.openapijsonschematools.codegen.generators.Generator; @@ -107,7 +108,7 @@ public void execute() { try { StringBuilder sb = new StringBuilder(); - Generator config = GeneratorLoader.getGenerator(generatorName, null, null); + Generator config = GeneratorLoader.getGenerator(generatorName, new GeneratorSettings(), null); String desiredFormat = StringUtils.defaultIfBlank(format, FORMAT_TEXT); diff --git a/src/main/java/org/openapijsonschematools/codegen/common/CodegenConstants.java b/src/main/java/org/openapijsonschematools/codegen/common/CodegenConstants.java index d2841c00721..ef912629dca 100644 --- a/src/main/java/org/openapijsonschematools/codegen/common/CodegenConstants.java +++ b/src/main/java/org/openapijsonschematools/codegen/common/CodegenConstants.java @@ -143,6 +143,8 @@ public class CodegenConstants { public static final String SOURCE_FOLDER = "sourceFolder"; public static final String SOURCE_FOLDER_DESC = "source folder for generated code"; + public static final String BUILD_TOOL = "buildTool"; + public static final String BUILD_TOOL_DESC = "the build automation tool used in generated code"; public static final String IMPL_FOLDER = "implFolder"; public static final String IMPL_FOLDER_DESC = "folder for generated implementation code"; diff --git a/src/main/java/org/openapijsonschematools/codegen/generators/JavaClientGenerator.java b/src/main/java/org/openapijsonschematools/codegen/generators/JavaClientGenerator.java index 23de6836528..701358347fd 100644 --- a/src/main/java/org/openapijsonschematools/codegen/generators/JavaClientGenerator.java +++ b/src/main/java/org/openapijsonschematools/codegen/generators/JavaClientGenerator.java @@ -95,9 +95,23 @@ public JavaClientGenerator(GeneratorSettings generatorSettings, WorkflowSettings "openapi-java-client", "generated-code" + File.separator + "java" ); + String mavenBuildTool = "maven"; + String buildToolValue = (String) generatorSettings.getAdditionalProperties().getOrDefault(CodegenConstants.BUILD_TOOL, mavenBuildTool); + additionalProperties.put(CodegenConstants.BUILD_TOOL, buildToolValue); + String gradleBuildTool = "gradle"; + if (buildToolValue.equals(mavenBuildTool)) { + supportingFiles.add(new SupportingFile("pom.hbs", "", "pom.xml").doNotOverwrite()); + } else if (buildToolValue.equals(gradleBuildTool)) { + supportingFiles.add(new SupportingFile("build.gradle.hbs", "", "build.gradle.kts").doNotOverwrite()); + supportingFiles.add(new SupportingFile("settings.gradle.hbs", "", "settings.gradle.kts").doNotOverwrite()); + } if (this.outputTestFolder.isEmpty()) { setOutputTestFolder(this.generatorSettings.outputFolder); } + // Common files + supportingFiles.add(new SupportingFile("README.hbs", "", "README.md").doNotOverwrite()); + supportingFiles.add(new SupportingFile("gitignore.hbs", "", ".gitignore")); + headersSchemaFragment = "HeadersSchema"; supportsInheritance = true; @@ -117,7 +131,15 @@ public JavaClientGenerator(GeneratorSettings generatorSettings, WorkflowSettings cliOptions.add(new CliOption(CodegenConstants.LICENSE_NAME, CodegenConstants.LICENSE_NAME_DESC).defaultValue(this.getLicenseName())); cliOptions.add(new CliOption(CodegenConstants.LICENSE_URL, CodegenConstants.LICENSE_URL_DESC).defaultValue(this.getLicenseUrl())); cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC).defaultValue(this.getSourceFolder())); - + CliOption buildTool = CliOption.newString(CodegenConstants.BUILD_TOOL, CodegenConstants.BUILD_TOOL_DESC); + Map buildToolOptions = new LinkedHashMap<>(); + buildToolOptions.putAll(Map.of( + mavenBuildTool, "Use maven", + gradleBuildTool, "Use gradle" + )); + buildTool.setEnum(buildToolOptions); + buildTool.setDefault(mavenBuildTool); + cliOptions.add(buildTool); cliOptions.add(CliOption.newString(CodegenConstants.PARENT_GROUP_ID, CodegenConstants.PARENT_GROUP_ID_DESC)); cliOptions.add(CliOption.newString(CodegenConstants.PARENT_ARTIFACT_ID, CodegenConstants.PARENT_ARTIFACT_ID_DESC)); cliOptions.add(CliOption.newString(CodegenConstants.PARENT_VERSION, CodegenConstants.PARENT_VERSION_DESC)); @@ -1055,10 +1077,6 @@ public void processOpts() { super.processOpts(); authFolder = (sourceFolder + '/' + invokerPackage + ".auth").replace(".", "/"); - - //Common files - supportingFiles.add(new SupportingFile("pom.hbs", "", "pom.xml").doNotOverwrite()); - supportingFiles.add(new SupportingFile("README.hbs", "", "README.md").doNotOverwrite()); } @Override diff --git a/src/main/java/org/openapijsonschematools/codegen/generators/generatorloader/GeneratorLoader.java b/src/main/java/org/openapijsonschematools/codegen/generators/generatorloader/GeneratorLoader.java index b74352ca021..c671cde084b 100644 --- a/src/main/java/org/openapijsonschematools/codegen/generators/generatorloader/GeneratorLoader.java +++ b/src/main/java/org/openapijsonschematools/codegen/generators/generatorloader/GeneratorLoader.java @@ -89,11 +89,12 @@ public static Generator forName(String name) { } public static List getAll() { - List genrators = new ArrayList(); + GeneratorSettings generatorSettings = new GeneratorSettings(); + List generators = new ArrayList(); for (String generatorName: generatorNameToGenerator.keySet()) { - Generator generator = getGenerator(generatorName, null, null); - genrators.add(generator); + Generator generator = getGenerator(generatorName, generatorSettings, null); + generators.add(generator); } - return genrators; + return generators; } } diff --git a/src/main/resources/java/README.hbs b/src/main/resources/java/README.hbs index 8fdb4784426..022a99bd336 100644 --- a/src/main/resources/java/README.hbs +++ b/src/main/resources/java/README.hbs @@ -16,12 +16,13 @@ For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}}) ## Requirements 1. Java {{generatorLanguageVersion}} -2. Maven +2. {{#eq buildTool "maven"}}Maven{{else}}Gradle{{/eq}} ## Installation To install the API client library to your local Maven repository, simply execute: +{{#eq buildTool "maven"}} ```shell mvn clean install ``` @@ -47,19 +48,28 @@ Add this dependency to your project's POM: ``` -### Others - -At first generate the JAR by executing: - +{{else}} ```shell -mvn clean package +gradle wrapper +gradlew clean build ``` -Then manually install the following JARs: +### Gradle users + +Add this dependency to your project's build file: -- `target/{{{artifactId}}}-{{{artifactVersion}}}.jar` -- `target/lib/*.jar` +``` +repositories { + mavenCentral() // Needed if the '{{{artifactId}}}' jar has been published to maven centra + mavenLocal() // Needed if the '{{{artifactId}}}' jar has been published to the local maven repo +} + +dependencies { + implementation "{{{groupId}}}:{{{artifactId}}}:{{{artifactVersion}}}" +} +``` +{{/eq}} ## Usage Notes ### Validation, Immutability, and Data Type diff --git a/src/main/resources/java/build.gradle.hbs b/src/main/resources/java/build.gradle.hbs new file mode 100644 index 00000000000..2b484053fcf --- /dev/null +++ b/src/main/resources/java/build.gradle.hbs @@ -0,0 +1,64 @@ +import org.checkerframework.gradle.plugin.CheckerFrameworkExtension + +plugins { + `java-library` + `maven-publish` + id("org.checkerframework") version "0.6.33" +} + +repositories { + mavenLocal() + maven { + url = uri("https://repo.maven.apache.org/maven2/") + } +} + +dependencies { + implementation("org.checkerframework:checker-qual:3.42.0") + implementation("com.google.code.gson:gson:2.10.1") + testImplementation("junit:junit:4.13.2") + checkerFramework("org.checkerframework:checker:3.42.0") +} + +configure { + checkers = listOf( + "org.checkerframework.checker.nullness.NullnessChecker" + ) +} + +group = "{{groupId}}" +version = "{{artifactVersion}}" +description = "{{artifactDescription}}" + +val testsJar by tasks.registering(Jar::class) { + archiveClassifier = "tests" + from(sourceSets["test"].output) +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + } + withSourcesJar() + withJavadocJar() +} + +publishing { + publications.create("maven") { + from(components["java"]) + artifact(testsJar) + } +} + +tasks.wrapper { + gradleVersion = "8.7" +} + +tasks.withType() { + options.encoding = "UTF-8" +} + +tasks.withType() { + enabled = false + options.encoding = "UTF-8" +} diff --git a/src/main/resources/java/gitignore.hbs b/src/main/resources/java/gitignore.hbs new file mode 100644 index 00000000000..3a4ec036d04 --- /dev/null +++ b/src/main/resources/java/gitignore.hbs @@ -0,0 +1,9 @@ +build/ +.gradle/ +.idea/ +target/ + +# gradle wrapper +gradlew +gradlew.bat +gradle/ \ No newline at end of file diff --git a/src/main/resources/java/settings.gradle.hbs b/src/main/resources/java/settings.gradle.hbs new file mode 100644 index 00000000000..0a661d416eb --- /dev/null +++ b/src/main/resources/java/settings.gradle.hbs @@ -0,0 +1,2 @@ +rootProject.name = "{{artifactId}}" + diff --git a/src/main/resources/java/src/main/java/packagename/header/Rfc6570Serializer.hbs b/src/main/resources/java/src/main/java/packagename/header/Rfc6570Serializer.hbs index 93dbfab9980..d17e18e5c43 100644 --- a/src/main/resources/java/src/main/java/packagename/header/Rfc6570Serializer.hbs +++ b/src/main/resources/java/src/main/java/packagename/header/Rfc6570Serializer.hbs @@ -27,7 +27,11 @@ public class Rfc6570Serializer { .replace("%7E", "~"); // This could be done faster with more hand-crafted code. } catch (UnsupportedEncodingException wow) { - throw new NotImplementedException(wow.getMessage()); + @Nullable String msg = wow.getMessage(); + if (msg == null) { + throw new NotImplementedException("UnsupportedEncodingException thrown"); + } + throw new NotImplementedException(msg); } } diff --git a/src/main/resources/java/src/main/java/packagename/parameter/CookieSerializer.hbs b/src/main/resources/java/src/main/java/packagename/parameter/CookieSerializer.hbs index 5c52373a672..5905efe7ed3 100644 --- a/src/main/resources/java/src/main/java/packagename/parameter/CookieSerializer.hbs +++ b/src/main/resources/java/src/main/java/packagename/parameter/CookieSerializer.hbs @@ -16,7 +16,7 @@ public abstract class CookieSerializer { public String serialize(Map inData) throws NotImplementedException { String result = ""; - Map sortedData = new TreeMap<>(inData); + Map sortedData = new TreeMap<>(inData); for (Map.Entry entry: sortedData.entrySet()) { String mapKey = entry.getKey(); @Nullable Parameter parameter = parameters.get(mapKey); diff --git a/src/main/resources/java/src/main/java/packagename/securityrequirementobjects/AuthApplier.hbs b/src/main/resources/java/src/main/java/packagename/securityrequirementobjects/AuthApplier.hbs index 3b10e829d0d..30d74eff680 100644 --- a/src/main/resources/java/src/main/java/packagename/securityrequirementobjects/AuthApplier.hbs +++ b/src/main/resources/java/src/main/java/packagename/securityrequirementobjects/AuthApplier.hbs @@ -15,7 +15,7 @@ public class AuthApplier { String resourcePath, String method, HttpRequest.BodyPublisher bodyPublisher, - Map queryMap, + @Nullable Map queryMap, ApiConfiguration apiConfiguration ) { if (securityRequirementObject == null) { diff --git a/src/main/resources/java/src/test/java/packagename/header/SchemaHeaderTest.hbs b/src/main/resources/java/src/test/java/packagename/header/SchemaHeaderTest.hbs index 356b4e067da..c0404ccc143 100644 --- a/src/main/resources/java/src/test/java/packagename/header/SchemaHeaderTest.hbs +++ b/src/main/resources/java/src/test/java/packagename/header/SchemaHeaderTest.hbs @@ -34,7 +34,7 @@ public class SchemaHeaderTest { mapPayload.put("R", 100); mapPayload.put("G", 200); mapPayload.put("B", 150); - var testCases = List.of( + List testCases = List.of( new ParamTestCase( null, Map.of("color", List.of("")) @@ -135,28 +135,43 @@ public class SchemaHeaderTest { assertNull(deserialized); header = getHeader(NumberJsonSchema.NumberJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("1"), false, configuration); + var deserializedOne = header.deserialize(List.of("1"), false, configuration); + if (deserializedOne == null) { + throw new RuntimeException("invalid value"); + } @Nullable Object expected = 1L; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedOne); header = getHeader(NumberJsonSchema.NumberJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("3.14"), false, configuration); + var deserialized314 = header.deserialize(List.of("3.14"), false, configuration); + if (deserialized314 == null) { + throw new RuntimeException("invalid value"); + } expected = 3.14d; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserialized314); header = getHeader(StringJsonSchema.StringJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("blue"), false, configuration); + var deserializedBlue = header.deserialize(List.of("blue"), false, configuration); + if (deserializedBlue == null) { + throw new RuntimeException("invalid value"); + } expected = "blue"; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedBlue); header = getHeader(StringJsonSchema.StringJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("hello world"), false, configuration); + var deserializedHelloWorld = header.deserialize(List.of("hello world"), false, configuration); + if (deserializedHelloWorld == null) { + throw new RuntimeException("invalid value"); + } expected = "hello world"; - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedHelloWorld); header = getHeader(ListJsonSchema.ListJsonSchema1.getInstance()); - deserialized = header.deserialize(List.of("blue", "black", "brown"), false, configuration); + var deserializedList = header.deserialize(List.of("blue", "black", "brown"), false, configuration); + if (deserializedList == null) { + throw new RuntimeException("invalid value"); + } expected = List.of("blue", "black", "brown"); - Assert.assertEquals(expected, deserialized); + Assert.assertEquals(expected, deserializedList); } } diff --git a/src/test/java/org/openapijsonschematools/codegen/generators/JavaClientGeneratorTest.java b/src/test/java/org/openapijsonschematools/codegen/generators/JavaClientGeneratorTest.java index 95ca289ecd1..c36f2fad274 100644 --- a/src/test/java/org/openapijsonschematools/codegen/generators/JavaClientGeneratorTest.java +++ b/src/test/java/org/openapijsonschematools/codegen/generators/JavaClientGeneratorTest.java @@ -22,6 +22,7 @@ import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.parameters.Parameter; import org.openapijsonschematools.codegen.TestUtils; +import org.openapijsonschematools.codegen.config.GeneratorSettings; import org.openapijsonschematools.codegen.generators.openapimodels.CodegenParameter; import org.openapijsonschematools.codegen.generators.openapimodels.CodegenSchema; import org.openapijsonschematools.codegen.generators.openapimodels.EnumValue; @@ -33,7 +34,7 @@ public class JavaClientGeneratorTest { - private final JavaClientGenerator generator = new JavaClientGenerator(null, null); + private final JavaClientGenerator generator = new JavaClientGenerator(new GeneratorSettings(), null); @Test void inlineEnum() { @@ -135,7 +136,7 @@ void uuidGivenExample() { @Test public void testEnumNames() { OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/70_schema_enum_names.yaml"); - var javaGenerator = new JavaClientGenerator(null, null); + var javaGenerator = new JavaClientGenerator(new GeneratorSettings(), null); javaGenerator.setOpenAPI(openAPI); String modelName = "StringEnum";