diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..8c2e2b8196 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: + - package-ecosystem: "maven" + directory: "/" + schedule: + interval: "daily" + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-major"] diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000000..f67f5a42c2 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,16 @@ +name: 'Dependency Review' +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: 'Checkout Repository' + uses: actions/checkout@v4 + - name: Dependency Review + uses: actions/dependency-review-action@v3 + with: + fail-on-severity: high diff --git a/.github/workflows/maven-pr.yml b/.github/workflows/maven-pr.yml new file mode 100644 index 0000000000..b4a058ade6 --- /dev/null +++ b/.github/workflows/maven-pr.yml @@ -0,0 +1,81 @@ +name: Build Test PR + +on: + pull_request: + branches: [ "master" ] + +jobs: + build_pr: + + runs-on: ubuntu-latest + strategy: + matrix: + java: [ 8, 11, 17 ] + + env: + GENERATORS_VERSION_PROPERTY: "" + steps: + - uses: actions/checkout@v3 + name: git checkout + - name: Set up Java + uses: actions/setup-java@v3 + with: + java-version: ${{ matrix.java }} + distribution: temurin + cache: maven + - name: preliminary checks + run: | + docker login --username=${{ secrets.DOCKERHUB_SB_USERNAME }} --password=${{ secrets.DOCKERHUB_SB_PASSWORD }} + set -e + # fail if templates/generators contain carriage return '\r' + /bin/bash ./bin/utils/detect_carriage_return.sh + # fail if generators contain merge conflicts + /bin/bash ./bin/utils/detect_merge_conflict.sh + # fail if generators contain tab '\t' + /bin/bash ./bin/utils/detect_tab_in_java_class.sh + - uses: s4u/maven-settings-action@v2.8.0 + name: setup maven settings.xml + with: + servers: | + [{ + "id": "sonatype-nexus-staging", + "username": "${{ secrets.OSSRH_USERNAME }}", + "password": "${{ secrets.OSSRH_TOKEN }}" + }, + { + "id": "sonatype-nexus-snapshots", + "username": "${{ secrets.OSSRH_USERNAME }}", + "password": "${{ secrets.OSSRH_TOKEN }}" + }] + - name: Build with Maven + if: ${{ matrix.java != 8 }} + run: | + export MY_POM_VERSION=`mvn -Dswagger-codegen-version=3.0.38 -q -Dexec.executable="echo" -Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` + echo "POM VERSION" ${MY_POM_VERSION} + export CODEGEN_VERSION=`sed -n 's/\([^\s]*\)<\/swagger\-codegen\-version>/\1/p' pom.xml` + export CODEGEN_VERSION=`echo ${CODEGEN_VERSION} | tr -d '[:space:]'` + echo "CODEGEN_VERSION" ${CODEGEN_VERSION} + export CODEGEN_VERSION_PROPERTY="" + if [[ ! $MY_POM_VERSION =~ ^.*SNAPSHOT$ ]]; + then + if [[ ! $CODEGEN_VERSION =~ ^.*SNAPSHOT$ ]]; + then + # check release version exists + export CODEGEN_FOUND_JSON=`curl -s --max-time 60 --retry 15 --connect-timeout 20 https://search.maven.org/solrsearch/select?q=g:io.swagger.codegen.v3%20AND%20a:swagger-codegen%20AND%20v:${CODEGEN_VERSION}%20AND%20p:jar` + export CODEGEN_FOUND=`echo ${CODEGEN_FOUND_JSON} | jq '.response.numFound'` + echo "CODEGEN_FOUND" ${CODEGEN_FOUND} + if [[ $CODEGEN_FOUND == '0' ]]; + then + echo "codegen version not found" + rm -f maven-metadata.json + curl -o maven-metadata.json -s --max-time 60 --retry 15 --connect-timeout 30 -H "accept: application/json" https://oss.sonatype.org/service/local/repositories/snapshots/content/io/swagger/codegen/v3/swagger-codegen/ + LAST_SNAP=`jq '[.data | sort_by(.lastModified) | reverse | .[] | select( .text | contains("3."))]| .[0].text' maven-metadata.json` + export LAST_SNAP=${LAST_SNAP:1:${#LAST_SNAP}-2} + echo "LAST_SNAP $LAST_SNAP" + export CODEGEN_VERSION_PROPERTY=-Dswagger-codegen-version=$LAST_SNAP + fi + fi + fi + echo "CODEGEN_VERSION_PROPERTY ${CODEGEN_VERSION_PROPERTY}" + echo "CODEGEN_VERSION_PROPERTY=${CODEGEN_VERSION_PROPERTY}" >> $GITHUB_ENV + ./mvnw clean verify -U ${CODEGEN_VERSION_PROPERTY} diff --git a/.github/workflows/maven-push.yml b/.github/workflows/maven-push.yml new file mode 100644 index 0000000000..6145fbc315 --- /dev/null +++ b/.github/workflows/maven-push.yml @@ -0,0 +1,96 @@ +name: Build Test Push + +on: + push: + branches: [ "master" ] + +jobs: + build_push: + + runs-on: ubuntu-latest + strategy: + matrix: + java: [ 8, 11, 17 ] + + env: + GENERATORS_VERSION_PROPERTY: "" + + steps: + - uses: actions/checkout@v3 + name: git checkout + with: + ref: master + - name: Set up Java + uses: actions/setup-java@v3 + with: + java-version: ${{ matrix.java }} + distribution: temurin + cache: maven + - name: preliminary checks + run: | + docker login --username=${{ secrets.DOCKERHUB_SB_USERNAME }} --password=${{ secrets.DOCKERHUB_SB_PASSWORD }} + set -e + # fail if templates/generators contain carriage return '\r' + /bin/bash ./bin/utils/detect_carriage_return.sh + # fail if generators contain merge conflicts + /bin/bash ./bin/utils/detect_merge_conflict.sh + # fail if generators contain tab '\t' + /bin/bash ./bin/utils/detect_tab_in_java_class.sh + - uses: s4u/maven-settings-action@v2.8.0 + name: setup maven settings.xml + with: + servers: | + [{ + "id": "sonatype-nexus-staging", + "username": "${{ secrets.OSSRH_USERNAME }}", + "password": "${{ secrets.OSSRH_TOKEN }}" + }, + { + "id": "sonatype-nexus-snapshots", + "username": "${{ secrets.OSSRH_USERNAME }}", + "password": "${{ secrets.OSSRH_TOKEN }}" + }] + - name: Build with Maven + if: ${{ matrix.java != 8 }} + run: | + export MY_POM_VERSION=`mvn -Dswagger-codegen-version=3.0.38 -q -Dexec.executable="echo" -Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` + echo "POM VERSION" ${MY_POM_VERSION} + export CODEGEN_VERSION=`sed -n 's/\([^\s]*\)<\/swagger\-codegen\-version>/\1/p' pom.xml` + export CODEGEN_VERSION=`echo ${CODEGEN_VERSION} | tr -d '[:space:]'` + echo "CODEGEN_VERSION" ${CODEGEN_VERSION} + export CODEGEN_VERSION_PROPERTY="" + if [[ ! $MY_POM_VERSION =~ ^.*SNAPSHOT$ ]]; + then + if [[ ! $CODEGEN_VERSION =~ ^.*SNAPSHOT$ ]]; + then + # check release version exists + export CODEGEN_FOUND_JSON=`curl -s --max-time 60 --retry 15 --connect-timeout 20 https://search.maven.org/solrsearch/select?q=g:io.swagger.codegen.v3%20AND%20a:swagger-codegen%20AND%20v:${CODEGEN_VERSION}%20AND%20p:jar` + export CODEGEN_FOUND=`echo ${CODEGEN_FOUND_JSON} | jq '.response.numFound'` + echo "CODEGEN_FOUND" ${CODEGEN_FOUND} + if [[ $CODEGEN_FOUND == '0' ]]; + then + echo "codegen version not found" + rm -f maven-metadata.json + curl -o maven-metadata.json -s --max-time 60 --retry 15 --connect-timeout 30 -H "accept: application/json" https://oss.sonatype.org/service/local/repositories/snapshots/content/io/swagger/codegen/v3/swagger-codegen/ + LAST_SNAP=`jq '[.data | sort_by(.lastModified) | reverse | .[] | select( .text | contains("3."))]| .[0].text' maven-metadata.json` + export LAST_SNAP=${LAST_SNAP:1:${#LAST_SNAP}-2} + echo "LAST_SNAP $LAST_SNAP" + export CODEGEN_VERSION_PROPERTY=-Dswagger-codegen-version=$LAST_SNAP + fi + fi + fi + echo "CODEGEN_VERSION_PROPERTY ${CODEGEN_VERSION_PROPERTY}" + echo "CODEGEN_VERSION_PROPERTY=${CODEGEN_VERSION_PROPERTY}" >> $GITHUB_ENV + ./mvnw clean verify -U ${CODEGEN_VERSION_PROPERTY} + - name: Deploy Maven Snapshot + if: ${{ matrix.java == 17 }} + run: | + export MY_POM_VERSION=`mvn -Dswagger-codegen-version=3.0.38 -q -Dexec.executable="echo" -Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` + echo "POM VERSION" ${MY_POM_VERSION} + if [[ $MY_POM_VERSION =~ ^.*SNAPSHOT$ ]]; + then + ./mvnw clean deploy -U --settings $HOME/.m2/settings.xml + else + echo "not deploying release: " ${MY_POM_VERSION} + fi + diff --git a/.gitignore b/.gitignore index 18de241bc9..a7e3653162 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,10 @@ # Log file *.log +# Temporary files +*.tmp +tmp/ + # BlueJ files *.ctxt diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar old mode 100755 new mode 100644 index f775b1c04c..bf82ff01c6 Binary files a/.mvn/wrapper/maven-wrapper.jar and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index eb91947648..30052152b2 100755 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1 +1,18 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip \ No newline at end of file +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar diff --git a/.whitesource b/.whitesource new file mode 100644 index 0000000000..2aa441810e --- /dev/null +++ b/.whitesource @@ -0,0 +1,3 @@ +{ + "settingsInheritedFrom": "swagger-api/whitesource-config@main" +} diff --git a/README.md b/README.md index 8689759411..e432d7486c 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ## Overview **Swagger Codegen Generators** project is a set of classes and templates ([Handlebars](https://jknack.github.io/handlebars.java)) used by [Swagger Codegen 3.0.0 project](https://github.com/swagger-api/swagger-codegen/tree/3.0.0) in its code generation process for a specific language or language framework. The main differents with **Swagger Codegen 2.x.x** are: -- **Handlebars as template engine:** with Handelbars feature is possible to create more logic-less templates. +- **Handlebars as template engine:** with Handlebars feature is possible to create more logic-less templates. - **OAS 3 support:** generator classes work with OpenAPI Specification V3. More details about these and more differences are referenced at [https://github.com/swagger-api/swagger-codegen/releases/tag/v3.0.0](https://github.com/swagger-api/swagger-codegen/releases/tag/v3.0.0) @@ -18,16 +18,16 @@ You need the following installed and available in your $PATH: * Java 8 (http://java.oracle.com) * Apache maven 3.0.4 or greater (http://maven.apache.org/) -## How to contribute. -Right now the templates and generators classes are migrated from [Swagger Codegen](https://github.com/swagger-api/swagger-codegen) **3.0.0** branch. +## How to Contribute. +Right now the templates and generators classes are migrated from [Swagger Codegen](https://github.com/swagger-api/swagger-codegen) **3.0.0** branch. If you want to migrate an existing language/framework, you can follow this [guide](https://github.com/swagger-api/swagger-codegen/wiki/Swagger-Codegen-migration-(swagger-codegen-generators-repository)). -Also you need to keep in mind that **Handlebars** is used as template engines and besides it's pretty similar to **Mustache** there are different that can not be ignored. So you can follow this [guide](https://github.com/swagger-api/swagger-codegen/wiki/Swagger-Codegen-migration-from-Mustache-and-Handlebars-templates.) which explains steps to migrate templates from **Mustaches** to **Handelbars**. +Also you need to keep in mind that **Handlebars** is used as the template engine. It's pretty similar to **Mustache**, but there are differences that can not be ignored. So you can follow this [guide](https://github.com/swagger-api/swagger-codegen/wiki/Swagger-Codegen-migration-from-Mustache-and-Handlebars-templates.) which explains steps to migrate templates from **Mustaches** to **Handlebars**. -## Security contact +## Security Contact Please disclose any security-related issues or vulnerabilities by emailing [security@swagger.io](mailto:security@swagger.io), instead of using the public issue tracker. -## License information on Generated Code +## License Information on Generated Code The Swagger Codegen project is intended as a benefit for users of the Swagger / Open API Specification. The project itself has the [License](#license) as specified. In addition, please understand the following points: diff --git a/mvnw b/mvnw index e96ccd5fbb..b7f064624f 100755 --- a/mvnw +++ b/mvnw @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script +# Apache Maven Wrapper startup batch script, version 3.1.1 # # Required ENV vars: # ------------------ @@ -27,7 +27,6 @@ # # Optional ENV vars # ----------------- -# M2_HOME - location of maven2's installed home dir # MAVEN_OPTS - parameters passed to the Java VM when running Maven # e.g. to debug Maven itself, use # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @@ -36,6 +35,10 @@ if [ -z "$MAVEN_SKIP_RC" ] ; then + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + if [ -f /etc/mavenrc ] ; then . /etc/mavenrc fi @@ -58,9 +61,9 @@ case "`uname`" in # See https://developer.apple.com/library/mac/qa/qa1170/_index.html if [ -z "$JAVA_HOME" ]; then if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" + JAVA_HOME="`/usr/libexec/java_home`"; export JAVA_HOME else - export JAVA_HOME="/Library/Java/Home" + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME fi fi ;; @@ -72,36 +75,8 @@ if [ -z "$JAVA_HOME" ] ; then fi fi -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - # For Cygwin, ensure paths are in UNIX format before anything is touched if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` [ -n "$CLASSPATH" ] && @@ -110,11 +85,8 @@ fi # For Mingw, ensure paths are in UNIX format before anything is touched if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" [ -n "$JAVA_HOME" ] && JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" - # TODO classpath? fi if [ -z "$JAVA_HOME" ]; then @@ -146,7 +118,7 @@ if [ -z "$JAVACMD" ] ; then JAVACMD="$JAVA_HOME/bin/java" fi else - JAVACMD="`which java`" + JAVACMD="`\\unset -f command; \\command -v java`" fi fi @@ -160,12 +132,9 @@ if [ -z "$JAVA_HOME" ] ; then echo "Warning: JAVA_HOME environment variable is not set." fi -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - # traverses directory structure from process work directory to filesystem root # first directory with .mvn subdirectory is considered project base directory find_maven_basedir() { - if [ -z "$1" ] then echo "Path not specified to find_maven_basedir" @@ -185,7 +154,7 @@ find_maven_basedir() { fi # end of workaround done - echo "${basedir}" + printf '%s' "$(cd "$basedir"; pwd)" } # concatenates all lines of a file @@ -195,21 +164,106 @@ concat_lines() { fi } -BASE_DIR=`find_maven_basedir "$(pwd)"` +BASE_DIR=$(find_maven_basedir "$(dirname $0)") if [ -z "$BASE_DIR" ]; then exit 1; fi -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR if [ "$MVNW_VERBOSE" = true ]; then echo $MAVEN_PROJECTBASEDIR fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + else + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) wrapperUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $wrapperUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + QUIET="--quiet" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + QUIET="" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" + else + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" + fi + [ $? -eq 0 ] || rm -f "$wrapperJarPath" + elif command -v curl > /dev/null; then + QUIET="--silent" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + QUIET="" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L + else + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L + fi + [ $? -eq 0 ] || rm -f "$wrapperJarPath" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaSource="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaSource=`cygpath --path --windows "$javaSource"` + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaSource") + fi + if [ -e "$javaClass" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" # For Cygwin, switch paths to Windows format before running java if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` [ -n "$CLASSPATH" ] && @@ -218,10 +272,16 @@ if $cygwin; then MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` fi +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain exec "$JAVACMD" \ $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd old mode 100755 new mode 100644 index 4f0b068a03..cba1f040dc --- a/mvnw.cmd +++ b/mvnw.cmd @@ -18,15 +18,14 @@ @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script +@REM Apache Maven Wrapper startup batch script, version 3.1.1 @REM @REM Required ENV vars: @REM JAVA_HOME - location of a JDK home dir @REM @REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven @REM e.g. to debug Maven itself, use @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @@ -37,7 +36,7 @@ @echo off @REM set title of command window title %0 -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% @REM set %HOME% to equivalent of $HOME @@ -46,8 +45,8 @@ if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") @REM Execute a user defined script before this one if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre @REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* :skipRcPre @setlocal @@ -117,11 +116,54 @@ for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do s :endReadAdditionalConfig SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" - set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %WRAPPER_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* if ERRORLEVEL 1 goto error goto end @@ -131,15 +173,15 @@ set ERROR_CODE=1 :end @endlocal & set ERROR_CODE=%ERROR_CODE% -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost @REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" :skipRcPost @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause +if "%MAVEN_BATCH_PAUSE%"=="on" pause -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% -exit /B %ERROR_CODE% +cmd /C exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml index 1c2286b80d..337a5c8700 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ io.swagger.codegen.v3 swagger-codegen-generators - 1.0.28-SNAPSHOT + 1.0.47-SNAPSHOT jar @@ -20,16 +20,12 @@ org.apache.maven.plugins maven-compiler-plugin - 3.6.1 - - 1.8 - 1.8 - + 3.10.1 org.apache.maven.plugins maven-javadoc-plugin - 3.0.1 + 3.5.0 true 1.8 @@ -53,7 +49,7 @@ org.apache.maven.plugins maven-source-plugin - 3.0.1 + 3.2.1 attach-sources @@ -65,12 +61,19 @@ + org.apache.maven.plugins maven-surefire-plugin - 2.22.0 + ${surefire-version} + + + org.apache.maven.surefire + surefire-junit4 + ${surefire-version} + + - - -javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit-version}/jmockit-${jmockit-version}.jar - + none:none + -javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit-version}/jmockit-${jmockit-version}.jar -XX:+IgnoreUnrecognizedVMOptions --add-opens=java.base/java.util=ALL-UNNAMED @@ -118,7 +121,7 @@ com.fasterxml.jackson.core jackson-databind - ${jackson-version} + ${jackson-databind-version} com.fasterxml.jackson.core @@ -215,6 +218,12 @@ + + junit + junit + ${junit-version} + test + org.slf4j slf4j-simple @@ -242,33 +251,35 @@ com.atlassian.commonmark commonmark - 0.9.0 + 0.17.0 org.mockito mockito-core - 2.8.47 + 2.28.2 test - 3.0.28-SNAPSHOT - 2.0.27 - 2.1.10 - 2.12.1 + 8 + 3.0.53-SNAPSHOT + 2.1.19 + 2.2.20 + 2.16.1 + 2.15.3 2.11.1 3.3.0 - 2.4 - 1.2 - 4.13.1 + 2.15.1 + 1.6.0 + 4.13.2 1.0.0 - 3.4 - 1.7.12 + 3.14.0 + 1.7.36 3.2.1 - 6.9.6 - 2.19.1 - 1.42 - 0.9.11 + 7.9.0 + 3.2.3 + 1.49 + 0.10.2 diff --git a/src/main/java/io/swagger/codegen/v3/generators/DefaultCodegenConfig.java b/src/main/java/io/swagger/codegen/v3/generators/DefaultCodegenConfig.java index 3273c05a07..20f0f8d9e7 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/DefaultCodegenConfig.java +++ b/src/main/java/io/swagger/codegen/v3/generators/DefaultCodegenConfig.java @@ -83,6 +83,7 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -160,7 +161,7 @@ public abstract class DefaultCodegenConfig implements CodegenConfig { protected Boolean sortParamsByRequiredFlag = true; protected Boolean ensureUniqueParams = true; protected Boolean allowUnicodeIdentifiers = false; - protected String gitUserId, gitRepoId, releaseNote; + protected String gitUserId, gitRepoId, releaseNote, gitRepoBaseURL; protected String httpUserAgent; protected Boolean hideGenerationTimestamp = true; protected TemplateEngine templateEngine = new HandlebarTemplateEngine(this); @@ -173,7 +174,6 @@ public abstract class DefaultCodegenConfig implements CodegenConfig { protected String ignoreFilePathOverride; protected boolean useOas2 = false; - protected boolean copyFistAllOfProperties = false; protected boolean ignoreImportMapping; public List cliOptions() { @@ -1344,6 +1344,9 @@ public CodegenModel fromModel(String name, Schema schema, Map al codegenModel.getVendorExtensions().put(CodegenConstants.IS_ALIAS_EXT_NAME, typeAliases.containsKey(name)); codegenModel.discriminator = schema.getDiscriminator(); + if (codegenModel.discriminator != null && codegenModel.discriminator.getPropertyName() != null) { + codegenModel.discriminator.setPropertyName(toVarName(codegenModel.discriminator.getPropertyName())); + } if (schema.getXml() != null) { codegenModel.xmlPrefix = schema.getXml().getPrefix(); @@ -1358,12 +1361,7 @@ public CodegenModel fromModel(String name, Schema schema, Map al addParentContainer(codegenModel, name, schema); } else if (schema instanceof MapSchema) { - codegenModel.getVendorExtensions().put(CodegenConstants.IS_MAP_CONTAINER_EXT_NAME, Boolean.TRUE); - codegenModel.getVendorExtensions().put(IS_CONTAINER_EXT_NAME, Boolean.TRUE); - addParentContainer(codegenModel, name, schema); - if (hasSchemaProperties(schema) || hasTrueAdditionalProperties(schema)) { - addAdditionPropertiesToCodeGenModel(codegenModel, schema); - } + processMapSchema(codegenModel, name, schema); } else if (schema instanceof ComposedSchema) { @@ -1407,49 +1405,29 @@ else if (schema instanceof ComposedSchema) { final String parentName = getParentName(composed); final Schema parent = StringUtils.isBlank(parentName) ? null : allDefinitions.get(parentName); final List allOf = composed.getAllOf(); - // interfaces (intermediate models) if (allOf != null && !allOf.isEmpty()) { - - if (codegenModel.discriminator != null && codegenModel.discriminator.getPropertyName() != null) { - codegenModel.discriminator.setPropertyName(toVarName(codegenModel.discriminator.getPropertyName())); - } - - for (int i = 0; i < allOf.size(); i++) { - if (i == 0 && !copyFistAllOfProperties) { - continue; - } - Schema interfaceSchema = allOf.get(i); - if (StringUtils.isBlank(interfaceSchema.get$ref())) { - continue; - } - Schema refSchema = null; - String ref = OpenAPIUtil.getSimpleRef(interfaceSchema.get$ref()); - if (allDefinitions != null) { - refSchema = allDefinitions.get(ref); + final int index = copyFirstAllOfProperties(allOf.get(0)) ? 0 : 1; + for (int i = index; i < allOf.size(); i++) { + Schema allOfSchema = allOf.get(i); + if (StringUtils.isNotBlank(allOfSchema.get$ref())) { + String ref = OpenAPIUtil.getSimpleRef(allOfSchema.get$ref()); + if (allDefinitions != null) { + allOfSchema = allDefinitions.get(ref); + } + final String modelName = toModelName(ref); + addImport(codegenModel, modelName); } - final String modelName = toModelName(ref); - addImport(codegenModel, modelName); - if (allDefinitions != null && refSchema != null) { + if (allDefinitions != null && allOfSchema != null) { if (!supportsMixins) { - addProperties(properties, required, refSchema, allDefinitions); + addProperties(properties, required, allOfSchema, allDefinitions); } if (supportsInheritance) { - addProperties(allProperties, allRequired, refSchema, allDefinitions); + addProperties(allProperties, allRequired, allOfSchema, allDefinitions); } } } } - final List oneOf = composed.getOneOf(); - if (oneOf != null && !oneOf.isEmpty()) { - if (schema.getDiscriminator() != null) { - codegenModel.discriminator = schema.getDiscriminator(); - if (codegenModel.discriminator != null && codegenModel.discriminator.getPropertyName() != null) { - codegenModel.discriminator.setPropertyName(toVarName(codegenModel.discriminator.getPropertyName())); - } - } - } - if (parent != null) { codegenModel.parentSchema = parentName; codegenModel.parent = typeMapping.containsKey(parentName) ? typeMapping.get(parentName): toModelName(parentName); @@ -1493,6 +1471,20 @@ else if (schema instanceof ComposedSchema) { return codegenModel; } + protected boolean copyFirstAllOfProperties(Schema allOfSchema) { + return StringUtils.isBlank(allOfSchema.get$ref()) + && allOfSchema.getProperties() != null && !allOfSchema.getProperties().isEmpty(); + } + + protected void processMapSchema(CodegenModel codegenModel, String name, Schema schema) { + codegenModel.getVendorExtensions().put(CodegenConstants.IS_MAP_CONTAINER_EXT_NAME, Boolean.TRUE); + codegenModel.getVendorExtensions().put(IS_CONTAINER_EXT_NAME, Boolean.TRUE); + addParentContainer(codegenModel, name, schema); + if (hasSchemaProperties(schema) || hasTrueAdditionalProperties(schema)) { + addAdditionPropertiesToCodeGenModel(codegenModel, schema); + } + } + /** * Recursively look for a discriminator in the interface tree */ @@ -1574,36 +1566,62 @@ public CodegenProperty fromProperty(String name, Schema propertySchema) { codegenProperty.name = toVarName(name); codegenProperty.baseName = name; codegenProperty.nameInCamelCase = camelize(codegenProperty.name, false); - codegenProperty.description = escapeText(propertySchema.getDescription()); - codegenProperty.unescapedDescription = propertySchema.getDescription(); - codegenProperty.title = propertySchema.getTitle(); codegenProperty.getter = toGetter(name); codegenProperty.setter = toSetter(name); - String example = toExampleValue(propertySchema); + setSchemaProperties(name, codegenProperty, propertySchema); + + final String type = getSchemaType(propertySchema); + + processPropertySchemaTypes(name, codegenProperty, propertySchema); + + codegenProperty.datatype = getTypeDeclaration(propertySchema); + codegenProperty.dataFormat = propertySchema.getFormat(); + + // this can cause issues for clients which don't support enums + boolean isEnum = getBooleanValue(codegenProperty, IS_ENUM_EXT_NAME); + if (isEnum) { + codegenProperty.datatypeWithEnum = toEnumName(codegenProperty); + codegenProperty.enumName = toEnumName(codegenProperty); + } else { + codegenProperty.datatypeWithEnum = codegenProperty.datatype; + } + + codegenProperty.baseType = getSchemaType(propertySchema); + + processPropertySchemaContainerTypes(codegenProperty, propertySchema, type); + return codegenProperty; + } + + protected void setSchemaProperties(String name, CodegenProperty codegenProperty, Schema schema) { + codegenProperty.description = escapeText(schema.getDescription()); + codegenProperty.unescapedDescription = schema.getDescription(); + codegenProperty.title = schema.getTitle(); + String example = toExampleValue(schema); if(!"null".equals(example)) { codegenProperty.example = example; } - codegenProperty.defaultValue = toDefaultValue(propertySchema); - codegenProperty.defaultValueWithParam = toDefaultValueWithParam(name, propertySchema); - codegenProperty.jsonSchema = Json.pretty(propertySchema); - codegenProperty.nullable = Boolean.TRUE.equals(propertySchema.getNullable()); - codegenProperty.getVendorExtensions().put(CodegenConstants.IS_NULLABLE_EXT_NAME, Boolean.TRUE.equals(propertySchema.getNullable())); - if (propertySchema.getReadOnly() != null) { - codegenProperty.getVendorExtensions().put(CodegenConstants.IS_READ_ONLY_EXT_NAME, propertySchema.getReadOnly()); - } - if (propertySchema.getXml() != null) { - if (propertySchema.getXml().getAttribute() != null) { - codegenProperty.getVendorExtensions().put(CodegenConstants.IS_XML_ATTRIBUTE_EXT_NAME, propertySchema.getXml().getAttribute()); + codegenProperty.defaultValue = toDefaultValue(schema); + codegenProperty.defaultValueWithParam = toDefaultValueWithParam(name, schema); + codegenProperty.jsonSchema = Json.pretty(schema); + codegenProperty.nullable = Boolean.TRUE.equals(schema.getNullable()); + codegenProperty.getVendorExtensions().put(CodegenConstants.IS_NULLABLE_EXT_NAME, Boolean.TRUE.equals(schema.getNullable())); + if (schema.getReadOnly() != null) { + codegenProperty.getVendorExtensions().put(CodegenConstants.IS_READ_ONLY_EXT_NAME, schema.getReadOnly()); + } + if (schema.getXml() != null) { + if (schema.getXml().getAttribute() != null) { + codegenProperty.getVendorExtensions().put(CodegenConstants.IS_XML_ATTRIBUTE_EXT_NAME, schema.getXml().getAttribute()); } - codegenProperty.xmlPrefix = propertySchema.getXml().getPrefix(); - codegenProperty.xmlName = propertySchema.getXml().getName(); - codegenProperty.xmlNamespace = propertySchema.getXml().getNamespace(); + codegenProperty.xmlPrefix = schema.getXml().getPrefix(); + codegenProperty.xmlName = schema.getXml().getName(); + codegenProperty.xmlNamespace = schema.getXml().getNamespace(); } - if (propertySchema.getExtensions() != null && !propertySchema.getExtensions().isEmpty()) { - codegenProperty.getVendorExtensions().putAll(propertySchema.getExtensions()); + if (schema.getExtensions() != null && !schema.getExtensions().isEmpty()) { + codegenProperty.getVendorExtensions().putAll(schema.getExtensions()); } + } - final String type = getSchemaType(propertySchema); + protected void processPropertySchemaTypes(String name, CodegenProperty codegenProperty, Schema propertySchema) { if (propertySchema instanceof IntegerSchema) { codegenProperty.getVendorExtensions().put(CodegenConstants.IS_NUMERIC_EXT_NAME, Boolean.TRUE); if(SchemaTypeUtil.INTEGER64_FORMAT.equals(propertySchema.getFormat())) { @@ -1640,7 +1658,6 @@ public CodegenProperty fromProperty(String name, Schema propertySchema) { codegenProperty.allowableValues = allowableValues; } } - if (propertySchema instanceof StringSchema) { codegenProperty.maxLength = propertySchema.getMaxLength(); codegenProperty.minLength = propertySchema.getMinLength(); @@ -1711,20 +1728,9 @@ public CodegenProperty fromProperty(String name, Schema propertySchema) { codegenProperty.getVendorExtensions().put(CodegenConstants.IS_DATE_TIME_EXT_NAME, Boolean.TRUE); handlePropertySchema(propertySchema, codegenProperty); } - codegenProperty.datatype = getTypeDeclaration(propertySchema); - codegenProperty.dataFormat = propertySchema.getFormat(); - - // this can cause issues for clients which don't support enums - boolean isEnum = getBooleanValue(codegenProperty, IS_ENUM_EXT_NAME); - if (isEnum) { - codegenProperty.datatypeWithEnum = toEnumName(codegenProperty); - codegenProperty.enumName = toEnumName(codegenProperty); - } else { - codegenProperty.datatypeWithEnum = codegenProperty.datatype; - } - - codegenProperty.baseType = getSchemaType(propertySchema); + } + protected void processPropertySchemaContainerTypes(CodegenProperty codegenProperty, Schema propertySchema, String type) { if (propertySchema instanceof ArraySchema) { codegenProperty.getVendorExtensions().put(CodegenConstants.IS_CONTAINER_EXT_NAME, Boolean.TRUE); codegenProperty.getVendorExtensions().put(CodegenConstants.IS_LIST_CONTAINER_EXT_NAME, Boolean.TRUE); @@ -1780,7 +1786,6 @@ public CodegenProperty fromProperty(String name, Schema propertySchema) { } setNonArrayMapProperty(codegenProperty, type); } - return codegenProperty; } private void handleMinMaxValues(Schema propertySchema, CodegenProperty codegenProperty) { @@ -2113,17 +2118,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation } List parameters = operation.getParameters(); - CodegenParameter bodyParam = null; - List allParams = new ArrayList<>(); - List bodyParams = new ArrayList<>(); - List pathParams = new ArrayList<>(); - List queryParams = new ArrayList<>(); - List headerParams = new ArrayList<>(); - List cookieParams = new ArrayList<>(); - List formParams = new ArrayList<>(); - List requiredParams = new ArrayList<>(); - - List codegenContents = new ArrayList<>(); + final OperationParameters operationParameters = new OperationParameters(); RequestBody body = operation.getRequestBody(); if (body != null) { @@ -2184,20 +2179,20 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation } // todo: this segment is only to support the "older" template design. it should be removed once all templates are updated with the new {{#contents}} tag. formParameter.getVendorExtensions().put(CodegenConstants.IS_FORM_PARAM_EXT_NAME, Boolean.TRUE); - formParams.add(formParameter.copy()); + operationParameters.addFormParam(formParameter.copy()); if (body.getRequired() != null && body.getRequired()) { - requiredParams.add(formParameter.copy()); + operationParameters.addRequiredParam(formParameter.copy()); } - allParams.add(formParameter); + operationParameters.addAllParams(formParameter); } - codegenContents.add(codegenContent); + operationParameters.addCodegenContents(codegenContent); } } else { - bodyParam = fromRequestBody(body, schemaName, schema, schemas, imports); + CodegenParameter bodyParam = fromRequestBody(body, schemaName, schema, schemas, imports); + operationParameters.setBodyParam(bodyParam); if (foundSchemas.isEmpty()) { - // todo: this segment is only to support the "older" template design. it should be removed once all templates are updated with the new {{#contents}} tag. - bodyParams.add(bodyParam.copy()); - allParams.add(bodyParam); + operationParameters.addBodyParams(bodyParam.copy()); + operationParameters.addAllParams(bodyParam); } else { boolean alreadyAdded = false; for (Schema usedSchema : foundSchemas) { @@ -2210,7 +2205,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation } } foundSchemas.add(schema); - codegenContents.add(codegenContent); + operationParameters.addCodegenContents(codegenContent); } } } @@ -2220,53 +2215,30 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation if (StringUtils.isNotBlank(param.get$ref())) { param = getParameterFromRef(param.get$ref(), openAPI); } - CodegenParameter codegenParameter = fromParameter(param, imports); - allParams.add(codegenParameter); - // Issue #2561 (neilotoole) : Moved setting of isParam flags - // from here to fromParameter(). - if (param instanceof QueryParameter || "query".equalsIgnoreCase(param.getIn())) { - queryParams.add(codegenParameter.copy()); - } else if (param instanceof PathParameter || "path".equalsIgnoreCase(param.getIn())) { - pathParams.add(codegenParameter.copy()); - } else if (param instanceof HeaderParameter || "header".equalsIgnoreCase(param.getIn())) { - headerParams.add(codegenParameter.copy()); - } else if (param instanceof CookieParameter || "cookie".equalsIgnoreCase(param.getIn())) { - cookieParams.add(codegenParameter.copy()); - } - if (codegenParameter.required) { - requiredParams.add(codegenParameter.copy()); + if ((param instanceof QueryParameter || "query".equalsIgnoreCase(param.getIn())) + && param.getStyle() != null && param.getStyle().equals(Parameter.StyleEnum.DEEPOBJECT)) { + operationParameters.parseNestedObjects(param.getName(), param.getSchema(), imports, this, openAPI); + continue; } + CodegenParameter codegenParameter = fromParameter(param, imports); + operationParameters.addParameters(param, codegenParameter); } } addOperationImports(codegenOperation, imports); - codegenOperation.bodyParam = bodyParam; + codegenOperation.bodyParam = operationParameters.getBodyParam(); codegenOperation.httpMethod = httpMethod.toUpperCase(); // move "required" parameters in front of "optional" parameters if (sortParamsByRequiredFlag) { - Collections.sort(allParams, new Comparator() { - @Override - public int compare(CodegenParameter one, CodegenParameter another) { - if (one.required == another.required) return 0; - else if (one.required) return -1; - else return 1; - } - }); + operationParameters.sortRequiredAllParams(); } - codegenOperation.allParams = addHasMore(allParams); - codegenOperation.bodyParams = addHasMore(bodyParams); - codegenOperation.pathParams = addHasMore(pathParams); - codegenOperation.queryParams = addHasMore(queryParams); - codegenOperation.headerParams = addHasMore(headerParams); - codegenOperation.cookieParams = addHasMore(cookieParams); - codegenOperation.formParams = addHasMore(formParams); - codegenOperation.requiredParams = addHasMore(requiredParams); + operationParameters.addHasMore(codegenOperation); codegenOperation.externalDocs = operation.getExternalDocs(); - configuresParameterForMediaType(codegenOperation, codegenContents); + configuresParameterForMediaType(codegenOperation, operationParameters.getCodegenContents()); // legacy support codegenOperation.nickname = codegenOperation.operationId; @@ -2366,6 +2338,9 @@ public CodegenResponse fromResponse(String responseCode, ApiResponse response) { } else { codegenResponse.baseType = codegenProperty.baseType; } + if (isFileTypeSchema(responseSchema)) { + codegenResponse.getVendorExtensions().put(CodegenConstants.IS_FILE_EXT_NAME, Boolean.TRUE); + } } codegenResponse.dataType = codegenProperty.datatype; @@ -2541,6 +2516,8 @@ public CodegenParameter fromParameter(Parameter parameter, Set imports) codegenParameter.dataType = codegenProperty.datatype; codegenParameter.dataFormat = codegenProperty.dataFormat; + setParameterJson(codegenParameter, parameterSchema); + if (getBooleanValue(codegenProperty, IS_ENUM_EXT_NAME)) { codegenParameter.datatypeWithEnum = codegenProperty.datatypeWithEnum; codegenParameter.enumName = codegenProperty.enumName; @@ -2998,16 +2975,6 @@ private void addHeaders(ApiResponse response, List target, Map< } } - protected static List addHasMore(List objs) { - if (objs != null) { - for (int i = 0; i < objs.size(); i++) { - objs.get(i).secondaryParam = i > 0; - objs.get(i).getVendorExtensions().put(CodegenConstants.HAS_MORE_EXT_NAME, i < objs.size() - 1); - } - } - return objs; - } - private static Map addHasMore(Map objs) { if (objs != null) { for (int i = 0; i < objs.size() - 1; i++) { @@ -3083,7 +3050,7 @@ public void addParentContainer(CodegenModel codegenModel, String name, Schema sc * @return The underscored version of the word */ public static String underscore(String word) { - String firstPattern = "([A-Z]+)([A-Z][a-z])"; + String firstPattern = "([A-Z]+)([A-Z][a-z][a-z]+)"; String secondPattern = "([a-z\\d])([A-Z])"; String replacementPattern = "$1_$2"; // Replace package separator with slash. @@ -3558,6 +3525,26 @@ public String getGitRepoId() { return gitRepoId; } + + /** + * Git repo Base URL + * + * @return Git repo Base URL + */ + public String getGitRepoBaseURL() { + return gitRepoBaseURL; + } + + /** + * Set Git repo Base URL. + * + * @param gitRepoBaseURL Git repo Base URL + */ + public void setGitRepoBaseURL(String gitRepoBaseURL) { + this.gitRepoBaseURL = gitRepoBaseURL; + } + + /** * Set release note. * @@ -4375,7 +4362,7 @@ protected void configuresParameterForMediaType(CodegenOperation codegenOperation } } ); - addHasMore(content.getParameters()); + OperationParameters.addHasMore(content.getParameters()); } codegenOperation.getContents().addAll(codegenContents); } @@ -4421,6 +4408,29 @@ protected void setParameterNullable(CodegenParameter parameter, CodegenProperty parameter.nullable = property.nullable; } + protected void setParameterJson(CodegenParameter codegenParameter, Schema parameterSchema) { + String contentType = parameterSchema.getExtensions() == null ? null : (String) parameterSchema.getExtensions().get("x-content-type"); + if (contentType != null && contentType.startsWith("application/") && contentType.endsWith("json")) { + // application/json, application/problem+json, application/ld+json, some more? + codegenParameter.isJson = true; + } + } + + protected boolean isFileTypeSchema(Schema schema) { + final Schema fileTypeSchema; + if (StringUtils.isNotBlank(schema.get$ref())) { + fileTypeSchema = OpenAPIUtil.getSchemaFromRefSchema(schema, openAPI); + } else { + fileTypeSchema = schema; + } + if (fileTypeSchema.getProperties() != null) { + final Collection propertySchemas = fileTypeSchema.getProperties().values(); + return propertySchemas.stream().anyMatch(propertySchema -> "string".equalsIgnoreCase(propertySchema.getType()) + && "binary".equalsIgnoreCase(propertySchema.getFormat())); + } + return false; + } + @Override public boolean needsUnflattenedSpec() { return false; diff --git a/src/main/java/io/swagger/codegen/v3/generators/OperationParameters.java b/src/main/java/io/swagger/codegen/v3/generators/OperationParameters.java new file mode 100644 index 0000000000..7cf06a29f1 --- /dev/null +++ b/src/main/java/io/swagger/codegen/v3/generators/OperationParameters.java @@ -0,0 +1,206 @@ +package io.swagger.codegen.v3.generators; + +import io.swagger.codegen.v3.CodegenConstants; +import io.swagger.codegen.v3.CodegenContent; +import io.swagger.codegen.v3.CodegenOperation; +import io.swagger.codegen.v3.CodegenParameter; +import io.swagger.codegen.v3.generators.util.OpenAPIUtil; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.media.ArraySchema; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.parameters.CookieParameter; +import io.swagger.v3.oas.models.parameters.HeaderParameter; +import io.swagger.v3.oas.models.parameters.Parameter; +import io.swagger.v3.oas.models.parameters.PathParameter; +import io.swagger.v3.oas.models.parameters.QueryParameter; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class OperationParameters { + + private CodegenParameter bodyParam = null; + private List allParams = new ArrayList<>(); + private List bodyParams = new ArrayList<>(); + private List pathParams = new ArrayList<>(); + private List queryParams = new ArrayList<>(); + private List headerParams = new ArrayList<>(); + private List cookieParams = new ArrayList<>(); + private List formParams = new ArrayList<>(); + private List requiredParams = new ArrayList<>(); + private List codegenContents = new ArrayList<>(); + + public void setBodyParam(CodegenParameter bodyParam) { + this.bodyParam = bodyParam; + } + + public CodegenParameter getBodyParam() { + return bodyParam; + } + + public List getAllParams() { + return allParams; + } + + public List getBodyParams() { + return bodyParams; + } + + public List getPathParams() { + return pathParams; + } + + public List getQueryParams() { + return queryParams; + } + + public List getHeaderParams() { + return headerParams; + } + + public List getCookieParams() { + return cookieParams; + } + + public List getFormParams() { + return formParams; + } + + public List getRequiredParams() { + return requiredParams; + } + + public List getCodegenContents() { + return codegenContents; + } + + public void addAllParams(CodegenParameter codegenParameter) { + allParams.add(codegenParameter); + } + + public void addBodyParams(CodegenParameter codegenParameter) { + bodyParams.add(codegenParameter); + } + + public void addPathParams(CodegenParameter codegenParameter) { + pathParams.add(codegenParameter); + } + + public void addQueryParams(CodegenParameter codegenParameter) { + queryParams.add(codegenParameter); + } + + public void addHeaderParams(CodegenParameter codegenParameter) { + headerParams.add(codegenParameter); + } + + public void addCookieParams(CodegenParameter codegenParameter) { + cookieParams.add(codegenParameter); + } + + public void addFormParam(CodegenParameter codegenParameter) { + formParams.add(codegenParameter); + } + + public void addRequiredParam(CodegenParameter codegenParameter) { + requiredParams.add(codegenParameter); + } + + public void addCodegenContents(CodegenContent codegenContent) { + codegenContents.add(codegenContent); + } + + public void addParameters(Parameter parameter, CodegenParameter codegenParameter) { + allParams.add(codegenParameter); + + if (parameter instanceof QueryParameter || "query".equalsIgnoreCase(parameter.getIn())) { + queryParams.add(codegenParameter.copy()); + } else if (parameter instanceof PathParameter || "path".equalsIgnoreCase(parameter.getIn())) { + pathParams.add(codegenParameter.copy()); + } else if (parameter instanceof HeaderParameter || "header".equalsIgnoreCase(parameter.getIn())) { + headerParams.add(codegenParameter.copy()); + } else if (parameter instanceof CookieParameter || "cookie".equalsIgnoreCase(parameter.getIn())) { + cookieParams.add(codegenParameter.copy()); + } + if (codegenParameter.required) { + requiredParams.add(codegenParameter.copy()); + } + } + + public void addHasMore(CodegenOperation codegenOperation) { + codegenOperation.allParams = addHasMore(allParams); + codegenOperation.bodyParams = addHasMore(bodyParams); + codegenOperation.pathParams = addHasMore(pathParams); + codegenOperation.queryParams = addHasMore(queryParams); + codegenOperation.headerParams = addHasMore(headerParams); + codegenOperation.cookieParams = addHasMore(cookieParams); + codegenOperation.formParams = addHasMore(formParams); + codegenOperation.requiredParams = addHasMore(requiredParams); + } + + public void sortRequiredAllParams() { + Collections.sort(allParams, (one, another) -> { + if (one.required == another.required) { + return 0; + } else if (one.required) { + return -1; + } else { + return 1; + } + }); + } + + public void parseNestedObjects(String name, Schema schema, Set imports, DefaultCodegenConfig codegenConfig, OpenAPI openAPI) { + schema = OpenAPIUtil.getRefSchemaIfExists(schema, openAPI); + if (schema == null || !isObjectWithProperties(schema)) { + return; + } + final Map properties = schema.getProperties(); + for (String key : properties.keySet()) { + Schema property = properties.get(key); + property = OpenAPIUtil.getRefSchemaIfExists(property, openAPI); + boolean required; + if (schema.getRequired() == null || schema.getRequired().isEmpty()) { + required = false; + } else { + required = schema.getRequired().stream().anyMatch(propertyName -> key.equalsIgnoreCase(propertyName.toString())); + } + final String parameterName; + if (property instanceof ArraySchema) { + parameterName = String.format("%s[%s][]", name, key); + } else { + parameterName = String.format("%s[%s]", name, key); + } + if (isObjectWithProperties(property)) { + parseNestedObjects(parameterName, property, imports, codegenConfig, openAPI); + continue; + } + final Parameter queryParameter = new QueryParameter() + .name(parameterName) + .required(required) + .schema(property); + final CodegenParameter codegenParameter = codegenConfig.fromParameter(queryParameter, imports); + addParameters(queryParameter, codegenParameter); + } + } + + public static List addHasMore(List codegenParameters) { + if (codegenParameters == null || codegenParameters.isEmpty()) { + return codegenParameters; + } + for (int i = 0; i < codegenParameters.size(); i++) { + codegenParameters.get(i).secondaryParam = i > 0; + codegenParameters.get(i).getVendorExtensions().put(CodegenConstants.HAS_MORE_EXT_NAME, i < codegenParameters.size() - 1); + } + return codegenParameters; + } + + private boolean isObjectWithProperties(Schema schema) { + return ("object".equalsIgnoreCase(schema.getType()) || schema.getType() == null) + && schema.getProperties() != null + && !schema.getProperties().isEmpty(); + } +} diff --git a/src/main/java/io/swagger/codegen/v3/generators/SchemaHandler.java b/src/main/java/io/swagger/codegen/v3/generators/SchemaHandler.java index cfcf7e60a6..09f0e13cd9 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/SchemaHandler.java +++ b/src/main/java/io/swagger/codegen/v3/generators/SchemaHandler.java @@ -70,6 +70,18 @@ public List getModels() { } protected CodegenModel processComposedSchema(CodegenModel codegenModel, ComposedSchema composedSchema, Map allModels) { + + final boolean schemaWithNoProperties = codegenModel.vars == null || codegenModel.vars.isEmpty(); + if (schemaWithNoProperties && (composedSchema.getAllOf() == null || composedSchema.getAllOf().isEmpty())) { + if (composedSchema.getOneOf() != null && !composedSchema.getOneOf().isEmpty()) { + this.addInterfaces(composedSchema.getOneOf(), codegenModel, allModels); + } else if (composedSchema.getAnyOf() != null && !composedSchema.getAnyOf().isEmpty()) { + this.addInterfaces(composedSchema.getAnyOf(), codegenModel, allModels); + } + codegenModel.setIsComposedModel(true); + return codegenModel; + } + List schemas = composedSchema.getOneOf(); CodegenModel composedModel = this.createComposedModel(ONE_OF_PREFFIX + codegenModel.getName(), schemas); if (composedModel == null) { @@ -175,7 +187,30 @@ protected void addInterfaces(List schemas, CodegenModel codegenModel, Ma continue; } final String schemaName = ref.substring(ref.lastIndexOf("/") + 1); - this.addInterfaceModel(allModels.get(codegenConfig.toModelName(schemaName)), codegenModel); + + final CodegenModel model = allModels.get(codegenConfig.toModelName(schemaName)); + this.addInterfaceModel(model, codegenModel); + + boolean subTypeAdded = false; + if (codegenModel.getSubTypes() != null) { + subTypeAdded = codegenModel.getSubTypes().stream().anyMatch(existingSubType -> existingSubType.classname.equalsIgnoreCase(model.classname)); + } + if (!subTypeAdded) { + codegenModel.addSubType(model); + } + + if (codegenModel.getVendorExtensions() == null || codegenModel.getVendorExtensions().containsKey("x-discriminator-type")) { + continue; + } + if (codegenModel.getDiscriminator() != null && StringUtils.isNotBlank(codegenModel.getDiscriminator().getPropertyName())) { + Optional optionalProperty = model.vars.stream() + .filter(codegenProperty -> codegenProperty.baseName.equals(codegenModel.getDiscriminator().getPropertyName())).findFirst(); + + optionalProperty.ifPresent(codegenProperty -> { + codegenModel.getVendorExtensions().put("x-discriminator-type", codegenProperty.datatypeWithEnum); + codegenModel.getVendorExtensions().put("x-discriminator-type-getter", codegenConfig.toGetter(codegenModel.getDiscriminator().getPropertyName())); + }); + } } } diff --git a/src/main/java/io/swagger/codegen/v3/generators/dotnet/AbstractCSharpCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/dotnet/AbstractCSharpCodegen.java index 4e3f2665fc..8b846d9a36 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/dotnet/AbstractCSharpCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/dotnet/AbstractCSharpCodegen.java @@ -755,7 +755,7 @@ public String getSchemaType(Schema propertySchema) { String type; if (swaggerType == null) { - swaggerType = StringUtils.EMPTY; // set swagger type to empty string if null + swaggerType = "object"; } // TODO avoid using toLowerCase as typeMapping should be case-sensitive diff --git a/src/main/java/io/swagger/codegen/v3/generators/dotnet/AspNetCoreServerCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/dotnet/AspNetCoreServerCodegen.java index fa25347b96..212a596f41 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/dotnet/AspNetCoreServerCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/dotnet/AspNetCoreServerCodegen.java @@ -8,6 +8,7 @@ import io.swagger.codegen.v3.CodegenSecurity; import io.swagger.codegen.v3.CodegenType; import io.swagger.codegen.v3.SupportingFile; +import io.swagger.codegen.v3.utils.SemVer; import io.swagger.v3.core.util.Json; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.security.SecurityScheme; @@ -30,7 +31,9 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { private static final String ASP_NET_CORE_VERSION_OPTION = "--aspnet-core-version"; private static final String INTERFACE_ONLY_OPTION = "--interface-only"; private static final String INTERFACE_CONTROLLER_OPTION = "--interface-controller"; - private final String DEFAULT_ASP_NET_CORE_VERSION = "3.1"; + private static final String SWASH_BUCKLE_VERSION_OPTION = "swashBuckleVersion"; + private static final String TARGET_FRAMEWORK = "targetFramework"; + private final String DEFAULT_ASP_NET_CORE_VERSION = "7.0"; private String aspNetCoreVersion; @SuppressWarnings("hiding") @@ -162,6 +165,7 @@ public void processOpts() { supportingFiles.add(new SupportingFile("Filters" + File.separator + "GeneratePathParamsValidationFilter.mustache", packageFolder + File.separator + "Filters", "GeneratePathParamsValidationFilter.cs")); supportingFiles.add(new SupportingFile("Startup.mustache", packageFolder, "Startup.cs")); } else { + final SemVer semVer = new SemVer(aspNetCoreVersion); apiTemplateFiles.put("3.0/controller.mustache", ".cs"); addInterfaceControllerTemplate(); @@ -170,7 +174,20 @@ public void processOpts() { supportingFiles.add(new SupportingFile("3.0/Startup.mustache", packageFolder, "Startup.cs")); supportingFiles.add(new SupportingFile("3.0/Program.mustache", packageFolder, "Program.cs")); - if (isThreeDotOneVersion) { + + if (semVer.atLeast("5.0")) { + additionalProperties.put(SWASH_BUCKLE_VERSION_OPTION, "6.4.0"); + supportingFiles.add(new SupportingFile("3.1/Project.csproj.mustache", packageFolder, this.packageName + ".csproj")); + } + if (semVer.atLeast("7.0")) { + additionalProperties.put(TARGET_FRAMEWORK, "net7.0"); + } else if (semVer.atLeast("6.0")) { + additionalProperties.put(TARGET_FRAMEWORK, "net6.0"); + } else if (semVer.atLeast("5.0")) { + additionalProperties.put(TARGET_FRAMEWORK, "net5.0"); + } else if (semVer.atLeast("3.1")) { + additionalProperties.put(SWASH_BUCKLE_VERSION_OPTION, "5.5.1"); + additionalProperties.put(TARGET_FRAMEWORK, "netcoreapp3.1"); supportingFiles.add(new SupportingFile("3.1/Project.csproj.mustache", packageFolder, this.packageName + ".csproj")); } else { supportingFiles.add(new SupportingFile("3.0/Project.csproj.mustache", packageFolder, this.packageName + ".csproj")); @@ -284,7 +301,8 @@ protected void processOperation(CodegenOperation operation) { List contents = operation.getContents() .stream() .filter(codegenContent -> !codegenContent.getIsForm()) - .collect(Collectors.toList()); + .collect( + Collectors.toList()); operation.getContents().clear(); operation.getContents().addAll(contents); } @@ -345,7 +363,7 @@ private void addInterfaceControllerTemplate() { boolean interfaceController = false; if (StringUtils.isNotBlank(interfaceControllerOption)) { interfaceController = Boolean.valueOf(getOptionValue(INTERFACE_CONTROLLER_OPTION)); - } else { + } else { if (additionalProperties.get(INTERFACE_CONTROLLER_OPTION.substring(2)) != null) { interfaceController = Boolean.valueOf(additionalProperties.get(INTERFACE_CONTROLLER_OPTION.substring(2)).toString()); } @@ -378,7 +396,8 @@ private void setAspNetCoreVersion() { } else { this.aspNetCoreVersion = optionValue; } - if (!this.aspNetCoreVersion.equals("2.0") && !this.aspNetCoreVersion.equals("2.1") && !this.aspNetCoreVersion.equals("2.2") && !this.aspNetCoreVersion.equals("3.0")) { + final SemVer semVer = new SemVer(this.aspNetCoreVersion); + if (semVer.compareTo(new SemVer("2.0")) < 0) { LOGGER.error("version '" + this.aspNetCoreVersion + "' is not supported, switching to default version: '" + DEFAULT_ASP_NET_CORE_VERSION + "'"); this.aspNetCoreVersion = DEFAULT_ASP_NET_CORE_VERSION; } diff --git a/src/main/java/io/swagger/codegen/v3/generators/dotnet/CSharpClientCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/dotnet/CSharpClientCodegen.java index 7bacb60a57..9112e9cc3a 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/dotnet/CSharpClientCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/dotnet/CSharpClientCodegen.java @@ -587,6 +587,26 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert super.postProcessModelProperty(model, property); } + @Override + protected void fixUpParentAndInterfaces(CodegenModel codegenModel, Map allModels) { + super.fixUpParentAndInterfaces(codegenModel, allModels); + final CodegenModel parentModel = codegenModel.getParentModel(); + if (parentModel == null || (codegenModel.getReadWriteVars() == null || codegenModel.getReadWriteVars().isEmpty()) || (parentModel.getVars() == null || parentModel.getVars().isEmpty())) { + return; + } + codegenModel.setParentVars(parentModel.getVars()); + parentModel.getVars().forEach(parentProperty -> { + codegenModel.getReadWriteVars().stream() + .filter(codegenProperty -> parentProperty.getName().equalsIgnoreCase(codegenProperty.getName())) + .findFirst() + .ifPresent(codegenProperty -> { + codegenProperty.setDatatype(parentProperty.getDatatype()); + codegenProperty.setDatatypeWithEnum(parentProperty.getDatatypeWithEnum()); + }); + }); + + } + /* * The swagger pattern spec follows the Perl convention and style of modifiers. .NET * does not support this syntax directly so we need to convert the pattern to a .NET compatible diff --git a/src/main/java/io/swagger/codegen/v3/generators/handlebars/StringUtilHelper.java b/src/main/java/io/swagger/codegen/v3/generators/handlebars/StringUtilHelper.java index 89cdd5dcda..ed5af816f0 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/handlebars/StringUtilHelper.java +++ b/src/main/java/io/swagger/codegen/v3/generators/handlebars/StringUtilHelper.java @@ -24,6 +24,15 @@ public String toLowerCase(String string) { return string.toLowerCase(); } + public String toQuotedWord(Object object) { + String string = object.toString(); + if (string.contains("\"")) { + return string; + } else { + return "\"" + string + "\""; + } + } + public String backSlash() { return "\\"; } diff --git a/src/main/java/io/swagger/codegen/v3/generators/handlebars/java/JavaHelper.java b/src/main/java/io/swagger/codegen/v3/generators/handlebars/java/JavaHelper.java index 7c6ba8b2a7..0135f50260 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/handlebars/java/JavaHelper.java +++ b/src/main/java/io/swagger/codegen/v3/generators/handlebars/java/JavaHelper.java @@ -79,20 +79,26 @@ public CharSequence getModelImports(Map templateData, Options op boolean withXml = Boolean.valueOf(String.valueOf(templateData.get("withXml"))); boolean parcelableModel = Boolean.valueOf(String.valueOf(templateData.get("parcelableModel"))); boolean useBeanValidation = Boolean.valueOf(String.valueOf(templateData.get("useBeanValidation"))); + boolean jakarta = Boolean.valueOf(String.valueOf(templateData.get("jakarta"))); if (serializableMode) { builder.append("import java.io.Serializable;\n"); } if (jackson && withXml) { builder.append("import com.fasterxml.jackson.dataformat.xml.annotation.*;\n"); } - if (withXml) { + if (withXml && jakarta) { + builder.append("import jakarta.xml.bind.annotation.*;\n"); + } else if (withXml) { builder.append("import javax.xml.bind.annotation.*;\n"); } if (parcelableModel) { builder.append("import android.os.Parcelable;\n"); builder.append("import android.os.Parcel;\n"); } - if (useBeanValidation) { + if (useBeanValidation && jakarta) { + builder.append("import jakarta.validation.constraints.*;\n"); + builder.append("import jakarta.validation.Valid;\n"); + } else if (useBeanValidation) { builder.append("import javax.validation.constraints.*;\n"); builder.append("import javax.validation.Valid;\n"); } diff --git a/src/main/java/io/swagger/codegen/v3/generators/java/AbstractJavaCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/java/AbstractJavaCodegen.java index e1104ff59c..07aa3cf3f7 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/java/AbstractJavaCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/java/AbstractJavaCodegen.java @@ -1,5 +1,10 @@ package io.swagger.codegen.v3.generators.java; +import static io.swagger.codegen.v3.CodegenConstants.HAS_ENUMS_EXT_NAME; +import static io.swagger.codegen.v3.CodegenConstants.IS_ENUM_EXT_NAME; +import static io.swagger.codegen.v3.generators.features.NotNullAnnotationFeatures.NOT_NULL_JACKSON_ANNOTATION; +import static io.swagger.codegen.v3.generators.handlebars.ExtensionHelper.getBooleanValue; + import com.github.jknack.handlebars.Handlebars; import io.swagger.codegen.v3.CliOption; import io.swagger.codegen.v3.CodegenArgument; @@ -26,11 +31,6 @@ import io.swagger.v3.oas.models.parameters.RequestBody; import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.parser.util.SchemaTypeUtil; -import org.apache.commons.lang3.BooleanUtils; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.File; import java.util.Arrays; import java.util.HashMap; @@ -42,11 +42,10 @@ import java.util.Objects; import java.util.Optional; import java.util.regex.Pattern; - -import static io.swagger.codegen.v3.CodegenConstants.HAS_ENUMS_EXT_NAME; -import static io.swagger.codegen.v3.CodegenConstants.IS_ENUM_EXT_NAME; -import static io.swagger.codegen.v3.generators.features.NotNullAnnotationFeatures.NOT_NULL_JACKSON_ANNOTATION; -import static io.swagger.codegen.v3.generators.handlebars.ExtensionHelper.getBooleanValue; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class AbstractJavaCodegen extends DefaultCodegenConfig { private static Logger LOGGER = LoggerFactory.getLogger(AbstractJavaCodegen.class); @@ -54,13 +53,19 @@ public abstract class AbstractJavaCodegen extends DefaultCodegenConfig { public static final String DEFAULT_LIBRARY = ""; public static final String DATE_LIBRARY = "dateLibrary"; public static final String JAVA8_MODE = "java8"; + public static final String JAVA11_MODE = "java11"; public static final String WITH_XML = "withXml"; public static final String SUPPORT_JAVA6 = "supportJava6"; public static final String ERROR_ON_UNKNOWN_ENUM = "errorOnUnknownEnum"; public static final String CHECK_DUPLICATED_MODEL_NAME = "checkDuplicatedModelName"; + public static final String WIREMOCK_OPTION = "wiremock"; + + public static final String JAKARTA = "jakarta"; + protected String dateLibrary = "threetenbp"; protected boolean java8Mode = false; + protected boolean java11Mode = false; protected boolean withXml = false; protected String invokerPackage = "io.swagger"; protected String groupId = "io.swagger"; @@ -89,6 +94,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegenConfig { protected String apiDocPath = "docs/"; protected String modelDocPath = "docs/"; protected boolean supportJava6= false; + protected boolean jakarta = false; private NotNullAnnotationFeatures notNullOption; public AbstractJavaCodegen() { @@ -165,6 +171,7 @@ public AbstractJavaCodegen() { CliOption dateLibrary = new CliOption(DATE_LIBRARY, "Option. Date library to use"); Map dateOptions = new HashMap(); dateOptions.put("java8", "Java 8 native JSR310 (preferred for jdk 1.8+) - note: this also sets \"" + JAVA8_MODE + "\" to true"); + dateOptions.put("java11", "Java 11 native JSR384 (preferred for jdk 11+) - note: this also sets \"" + JAVA11_MODE + "\" to true"); dateOptions.put("threetenbp", "Backport of JSR310 (preferred for jdk < 1.8)"); dateOptions.put("java8-localdatetime", "Java 8 using LocalDateTime (for legacy app only)"); dateOptions.put("joda", "Joda (for legacy app only)"); @@ -178,7 +185,26 @@ public AbstractJavaCodegen() { java8ModeOptions.put("false", "Various third party libraries as needed"); java8Mode.setEnum(java8ModeOptions); cliOptions.add(java8Mode); + + CliOption java11Mode = new CliOption(JAVA11_MODE, "Option. Use Java11 classes instead of third party equivalents"); + Map java11ModeOptions = new HashMap(); + java11ModeOptions.put("true", "Use Java 11 classes"); + java11ModeOptions.put("false", "Various third party libraries as needed"); + java11Mode.setEnum(java11ModeOptions); + cliOptions.add(java11Mode); + cliOptions.add(CliOption.newBoolean(CHECK_DUPLICATED_MODEL_NAME, "Check if there are duplicated model names (ignoring case)")); + + cliOptions.add(CliOption.newBoolean(WIREMOCK_OPTION, "Use wiremock to generate endpoint calls to mock on generated tests.")); + + cliOptions.add(CliOption.newBoolean(JAKARTA, "Use Jakarta EE (package jakarta.*) instead of Java EE (javax.*)")); + + CliOption jeeSpec = CliOption.newBoolean(JAKARTA, "Use Jakarta EE (package jakarta.*) instead of Java EE (javax.*)"); + Map jeeSpecModeOptions = new HashMap(); + jeeSpecModeOptions.put("true", "Use Jakarta EE (package jakarta.*)"); + jeeSpecModeOptions.put("false", "Use Java EE (javax.*)"); + jeeSpec.setEnum(jeeSpecModeOptions); + cliOptions.add(jeeSpec); } @Override @@ -345,6 +371,11 @@ public void processOpts() { additionalProperties.put(ERROR_ON_UNKNOWN_ENUM, errorOnUnknownEnum); } + if (additionalProperties.containsKey(WIREMOCK_OPTION)) { + final boolean useWireMock = additionalProperties.get(WIREMOCK_OPTION) != null && Boolean.parseBoolean(additionalProperties.get(WIREMOCK_OPTION).toString()); + additionalProperties.put(WIREMOCK_OPTION, useWireMock); + } + if (this instanceof NotNullAnnotationFeatures) { notNullOption = (NotNullAnnotationFeatures)this; if (additionalProperties.containsKey(NOT_NULL_JACKSON_ANNOTATION)) { @@ -424,12 +455,10 @@ public void processOpts() { // used later in recursive import in postProcessingModels importMapping.put("com.fasterxml.jackson.annotation.JsonProperty", "com.fasterxml.jackson.annotation.JsonCreator"); - if(additionalProperties.containsKey(JAVA8_MODE)) { - setJava8Mode(Boolean.parseBoolean(additionalProperties.get(JAVA8_MODE).toString())); - if ( java8Mode ) { - additionalProperties.put("java8", true); - } - } + setJava8Mode(Boolean.parseBoolean(String.valueOf(additionalProperties.get(JAVA8_MODE)))); + additionalProperties.put(JAVA8_MODE, java8Mode); + setJava11Mode(Boolean.parseBoolean(String.valueOf(additionalProperties.get(JAVA11_MODE)))); + additionalProperties.put(JAVA11_MODE, java11Mode); if(additionalProperties.containsKey(WITH_XML)) { setWithXml(Boolean.parseBoolean(additionalProperties.get(WITH_XML).toString())); @@ -440,6 +469,8 @@ public void processOpts() { if (additionalProperties.containsKey(DATE_LIBRARY)) { setDateLibrary(additionalProperties.get("dateLibrary").toString()); + } else if (java8Mode) { + setDateLibrary("java8"); } if ("threetenbp".equals(dateLibrary)) { @@ -470,6 +501,11 @@ public void processOpts() { } else if (dateLibrary.equals("legacy")) { additionalProperties.put("legacyDates", true); } + + if (additionalProperties.containsKey(JAKARTA)) { + setJakarta(Boolean.parseBoolean(String.valueOf(additionalProperties.get(JAKARTA)))); + additionalProperties.put(JAKARTA, jakarta); + } } private void sanitizeConfig() { @@ -1013,20 +1049,26 @@ protected void fixUpParentAndInterfaces(CodegenModel codegenModel, Map parentProperty.name.equals(codegenProperty.name) && !parentProperty.datatype.equals(codegenProperty.datatype)); + .anyMatch(parentProperty -> + (parentProperty.name.equals(codegenProperty.name) || + parentProperty.getGetter().equals(codegenProperty.getGetter()) || + parentProperty.getSetter().equals(codegenProperty.getSetter()) && + !parentProperty.datatype.equals(codegenProperty.datatype))); if (hasConflict) { codegenProperty.name = toVarName(codegenModel.name + "_" + codegenProperty.name); + codegenProperty.nameInCamelCase = camelize(codegenProperty.name, false); codegenProperty.getter = toGetter(codegenProperty.name); - codegenProperty.setter = toGetter(codegenProperty.name); + codegenProperty.setter = toSetter(codegenProperty.name); break; } parentModel = parentModel.parentModel; @@ -1534,6 +1576,14 @@ public void setJava8Mode(boolean enabled) { this.java8Mode = enabled; } + public void setJava11Mode(boolean java11Mode) { + this.java11Mode = java11Mode; + } + + public void setJakarta(boolean jakarta) { + this.jakarta = jakarta; + } + @Override public String escapeQuotationMark(String input) { // remove " to avoid code injection @@ -1627,11 +1677,6 @@ public void setLanguageArguments(List languageArguments) { super.setLanguageArguments(languageArguments); } - @Override - public boolean defaultIgnoreImportMappingOption() { - return true; - } - @Override public boolean checkAliasModel() { return true; diff --git a/src/main/java/io/swagger/codegen/v3/generators/java/AbstractJavaJAXRSServerCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/java/AbstractJavaJAXRSServerCodegen.java index f0dc44eb4c..5db5d36182 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/java/AbstractJavaJAXRSServerCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/java/AbstractJavaJAXRSServerCodegen.java @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.io.File; import static io.swagger.codegen.v3.generators.handlebars.ExtensionHelper.getBooleanValue; @@ -75,6 +76,10 @@ public CodegenType getTag() { public void processOpts() { super.processOpts(); + if (java11Mode) { + additionalProperties.put(JAKARTA, jakarta = true); + } + if (additionalProperties.containsKey(CodegenConstants.IMPL_FOLDER)) { implFolder = (String) additionalProperties.get(CodegenConstants.IMPL_FOLDER); } @@ -224,11 +229,11 @@ public String apiFilename(String templateName, String tag) { String result = super.apiFilename(templateName, tag); if ( templateName.endsWith("Impl.mustache") ) { - int ix = result.lastIndexOf('/'); + int ix = result.lastIndexOf(File.separatorChar); result = result.substring(0, ix) + "/impl" + result.substring(ix, result.length() - 5) + "ServiceImpl.java"; result = result.replace(apiFileFolder(), implFileFolder(implFolder)); } else if ( templateName.endsWith("Factory.mustache") ) { - int ix = result.lastIndexOf('/'); + int ix = result.lastIndexOf(File.separatorChar); result = result.substring(0, ix) + "/factories" + result.substring(ix, result.length() - 5) + "ServiceFactory.java"; result = result.replace(apiFileFolder(), implFileFolder(implFolder)); } else if ( templateName.endsWith("Service.mustache") ) { diff --git a/src/main/java/io/swagger/codegen/v3/generators/java/JavaClientCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/java/JavaClientCodegen.java index 2c0dbd7a0a..fbb1481470 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/java/JavaClientCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/java/JavaClientCodegen.java @@ -90,7 +90,9 @@ public JavaClientCodegen() { supportedLibraries.put("jersey1", "HTTP client: Jersey client 1.19.4. JSON processing: Jackson 2.10.1. Enable gzip request encoding using '-DuseGzipFeature=true'."); supportedLibraries.put("feign", "HTTP client: OpenFeign 9.4.0. JSON processing: Jackson 2.10.1"); supportedLibraries.put("jersey2", "HTTP client: Jersey client 2.26. JSON processing: Jackson 2.10.1"); + supportedLibraries.put("jersey3", "HTTP client: Jersey client 3.0.10. JSON processing: Jackson 2.10.2"); supportedLibraries.put("okhttp-gson", "HTTP client: OkHttp 2.7.5. JSON processing: Gson 2.8.1. Enable Parcelable models on Android using '-DparcelableModel=true'. Enable gzip request encoding using '-DuseGzipFeature=true'."); + supportedLibraries.put("okhttp4-gson", "HTTP client: OkHttp 4.10.0. JSON processing: Gson 2.10.1. Enable Parcelable models on Android using '-DparcelableModel=true'. Enable gzip request encoding using '-DuseGzipFeature=true'."); supportedLibraries.put(RETROFIT_1, "HTTP client: OkHttp 2.7.5. JSON processing: Gson 2.3.1 (Retrofit 1.9.0). IMPORTANT NOTE: retrofit1.x is no longer actively maintained so please upgrade to 'retrofit2' instead."); supportedLibraries.put(RETROFIT_2, "HTTP client: OkHttp 3.8.0. JSON processing: Gson 2.6.1 (Retrofit 2.3.0). Enable the RxJava adapter using '-DuseRxJava[2]=true'. (RxJava 1.x or 2.x)"); supportedLibraries.put("resttemplate", "HTTP client: Spring RestTemplate 4.3.9-RELEASE. JSON processing: Jackson 2.9.9"); @@ -122,6 +124,14 @@ public String getHelp() { @Override public void processOpts() { + if (RETROFIT_1.equalsIgnoreCase(library)) { + dateLibrary = "joda"; + } + if ("jersey3".equalsIgnoreCase(library)) { + dateLibrary = "java8"; + additionalProperties.put(JAKARTA, true); + } + super.processOpts(); if (additionalProperties.containsKey(USE_RX_JAVA)) { @@ -176,7 +186,11 @@ public void processOpts() { //Common files writeOptional(outputFolder, new SupportingFile("pom.mustache", "", "pom.xml")); writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md")); - writeOptional(outputFolder, new SupportingFile("build.gradle.mustache", "", "build.gradle")); + if (java11Mode) { + writeOptional(outputFolder, new SupportingFile("build.gradle.java11.mustache", "", "build.gradle")); + } else { + writeOptional(outputFolder, new SupportingFile("build.gradle.mustache", "", "build.gradle")); + } writeOptional(outputFolder, new SupportingFile("build.sbt.mustache", "", "build.sbt")); writeOptional(outputFolder, new SupportingFile("settings.gradle.mustache", "", "settings.gradle")); writeOptional(outputFolder, new SupportingFile("gradle.properties.mustache", "", "gradle.properties")); @@ -223,7 +237,7 @@ public void processOpts() { additionalProperties.put("jackson", "true"); supportingFiles.add(new SupportingFile("ParamExpander.mustache", invokerFolder, "ParamExpander.java")); supportingFiles.add(new SupportingFile("EncodingUtils.mustache", invokerFolder, "EncodingUtils.java")); - } else if ("okhttp-gson".equals(getLibrary()) || StringUtils.isEmpty(getLibrary())) { + } else if ("okhttp-gson".equals(getLibrary()) || "okhttp4-gson".equals(getLibrary()) || StringUtils.isEmpty(getLibrary())) { // the "okhttp-gson" library template requires "ApiCallback.mustache" for async call supportingFiles.add(new SupportingFile("ApiCallback.mustache", invokerFolder, "ApiCallback.java")); supportingFiles.add(new SupportingFile("ApiResponse.mustache", invokerFolder, "ApiResponse.java")); @@ -239,7 +253,7 @@ public void processOpts() { if ("retrofit2".equals(getLibrary()) && !usePlayWS) { supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java")); } - } else if ("jersey2".equals(getLibrary()) || "resteasy".equals(getLibrary())) { + } else if ("jersey3".equals(getLibrary()) || "jersey2".equals(getLibrary()) || "resteasy".equals(getLibrary())) { supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java")); additionalProperties.put("jackson", "true"); } else if("jersey1".equals(getLibrary())) { diff --git a/src/main/java/io/swagger/codegen/v3/generators/java/JavaJAXRSCXFCDIServerCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/java/JavaJAXRSCXFCDIServerCodegen.java index 031bd0e102..3e632ba8e6 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/java/JavaJAXRSCXFCDIServerCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/java/JavaJAXRSCXFCDIServerCodegen.java @@ -5,8 +5,6 @@ import io.swagger.codegen.v3.CodegenProperty; import io.swagger.codegen.v3.SupportingFile; import io.swagger.codegen.v3.generators.features.BeanValidationFeatures; -import org.apache.commons.lang3.StringUtils; - import java.io.File; /** @@ -48,7 +46,14 @@ public void processOpts() { super.processOpts(); - importMapping.put("Valid", "javax.validation.Valid"); + if (additionalProperties.containsKey(JAKARTA)) { + setJakarta(convertPropertyToBoolean(JAKARTA)); + } + if (jakarta) { + importMapping.put("Valid", "jakarta.validation.Valid"); + } else { + importMapping.put("Valid", "javax.validation.Valid"); + } // Three API templates to support CDI injection apiTemplateFiles.put("apiService.mustache", ".java"); diff --git a/src/main/java/io/swagger/codegen/v3/generators/java/JavaJerseyDIServerCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/java/JavaJerseyDIServerCodegen.java index eca57e79be..58d748bf69 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/java/JavaJerseyDIServerCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/java/JavaJerseyDIServerCodegen.java @@ -30,7 +30,7 @@ public void addTemplateFiles() { apiTestTemplateFiles.clear(); // TODO: add test template // clear model and api doc template as this codegen - // does not support auto-generated markdown doc at the moment + // does not support auto-generated markdown doc at the moment. // TODO: add doc templates modelDocTemplateFiles.remove("model_doc.mustache"); apiDocTemplateFiles.remove("api_doc.mustache"); diff --git a/src/main/java/io/swagger/codegen/v3/generators/java/JavaVertXServerCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/java/JavaVertXServerCodegen.java new file mode 100644 index 0000000000..6c8ec792f5 --- /dev/null +++ b/src/main/java/io/swagger/codegen/v3/generators/java/JavaVertXServerCodegen.java @@ -0,0 +1,408 @@ +package io.swagger.codegen.v3.generators.java; + +import static io.swagger.codegen.v3.CodegenConstants.HAS_ENUMS_EXT_NAME; +import static io.swagger.codegen.v3.CodegenConstants.IS_ENUM_EXT_NAME; +import static io.swagger.codegen.v3.generators.handlebars.ExtensionHelper.getBooleanValue; + +import com.github.jknack.handlebars.Lambda; +import com.google.common.collect.ImmutableMap; +import io.swagger.codegen.v3.CliOption; +import io.swagger.codegen.v3.CodegenModel; +import io.swagger.codegen.v3.CodegenProperty; +import io.swagger.codegen.v3.CodegenType; +import io.swagger.codegen.v3.SupportingFile; +import io.swagger.codegen.v3.generators.features.BeanValidationFeatures; +import io.swagger.codegen.v3.generators.features.NotNullAnnotationFeatures; +import io.swagger.codegen.v3.generators.handlebars.lambda.UppercaseLambda; +import io.swagger.codegen.v3.utils.URLPathUtil; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.PathItem.HttpMethod; +import io.swagger.v3.oas.models.Paths; +import io.swagger.v3.oas.models.media.Schema; +import java.io.File; +import java.net.URL; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JavaVertXServerCodegen extends AbstractJavaCodegen implements BeanValidationFeatures, NotNullAnnotationFeatures { + + private static final Logger LOGGER = LoggerFactory.getLogger(JavaVertXServerCodegen.class); + + private static final String ROOT_PACKAGE = "rootPackage"; + private static final String VERTICLE_PACKAGE = "verticlePackage"; + private static final String SPEC_LOCATION = "openapi.yaml"; + private static final String OPENAPI_EXTENSION = "x-vertx-event-bus"; + private static final String OPENAPI_EXTENSION_ADDRESS = "address"; + private static final String OPENAPI_EXTENSION_METHOD_NAME = "method"; + private static final String TITLE = "title"; + + public static final String RX_INTERFACE_OPTION = "rxInterface"; + public static final String USE_DATAOBJECT_OPTION = "useDataObject"; + public static final String MOUNT_OPERATION_FROM_OPTION = "mountOperationFrom"; + public static final String MOUNT_OPERATION_FROM_EXTENSIONS = "mountFromExtensions"; + public static final String MOUNT_OPERATION_FROM_INTERFACE = "mountFromInterface"; + public static final String SPEC_LOCATION_OPTION = "specLocation"; + + public static final String USE_FUTURE_OPTION = "useFuture"; + + protected String rootPackage = "io.swagger.server.api"; + protected String apiVerticle; + protected String apiVersion = "1.0.0-SNAPSHOT"; + + protected boolean useDataObject = false; + protected boolean mountFromExtensions = false; + protected boolean mountFromInterface = false; + protected String title = null; + protected boolean useBeanValidation = false; + protected boolean notNullJacksonAnnotation = false; + + /** + * A Java Vert.X generator. It can be configured with CLI options : + *
    + *
  • rxInterface : type Boolean if true, API interfaces are generated with RX and methods return + * Single and Comparable. default : false
  • + * + *
  • useDataObject : type Boolean if true, models objects are generated with @DataObject
  • + * + *
  • mountOperationFrom : type String, define how routes are mounted.
  • + * + *
  • specLocation : define spec location, default as {@link JavaVertXServerCodegen#SPEC_LOCATION}.
  • + * + *
  • useFuture : define use services as future, default false.
  • + *
+ */ + public JavaVertXServerCodegen() { + super(); + + // set the output folder here + outputFolder = "generated-code" + File.separator + "javaVertXServer"; + + apiPackage = rootPackage + ".service"; + apiVerticle = rootPackage + ".verticle"; + modelPackage = rootPackage + ".model"; + + additionalProperties.put(ROOT_PACKAGE, rootPackage); + additionalProperties.put(VERTICLE_PACKAGE, apiVerticle); + + groupId = "io.swagger"; + artifactId = "swagger-java-vertx-server"; + artifactVersion = apiVersion; + + cliOptions.add(CliOption.newBoolean(RX_INTERFACE_OPTION, + "When specified, API interfaces are generated with RX " + + "and methods return Single<> and Comparable.")); + cliOptions.add(CliOption.newBoolean(USE_DATAOBJECT_OPTION, + "When specified, models objects are generated with @DataObject")); + + // add option to mount with operation id ? + CliOption operationsOption = CliOption.newString(MOUNT_OPERATION_FROM_OPTION,"When specified, defines how operations are mounted. Default with @WebApiServiceGen"); + Map mountOperationFromEnum = new HashMap<>(); + mountOperationFromEnum.put(MOUNT_OPERATION_FROM_EXTENSIONS, "Mount operations from extensions with web-api-service module & @WebApiServiceGen. open api contract must define x-vertx-event-bus extension to be mounted"); + mountOperationFromEnum.put(MOUNT_OPERATION_FROM_INTERFACE, "Mount operations from interface with web-api-service module & Interfaces implementing operations. event bus address will be #{tag}.address"); + operationsOption.setEnum(mountOperationFromEnum); + operationsOption.setDefault(MOUNT_OPERATION_FROM_EXTENSIONS); + cliOptions.add(operationsOption); + + CliOption specLocation = CliOption.newString(SPEC_LOCATION_OPTION, + "When specified, define spec location. Default as " + SPEC_LOCATION); + specLocation.setDefault(SPEC_LOCATION); + cliOptions.add(specLocation); + + CliOption useFutureOption = CliOption.newBoolean(USE_FUTURE_OPTION, + "When specified, describe service as future or not. Default as false"); + useFutureOption.setDefault(Boolean.FALSE.toString()); + cliOptions.add(useFutureOption); + + cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations")); + } + + /** + * Configures the type of generator. + * + * @return the CodegenType for this generator + * @see CodegenType + */ + public CodegenType getTag() { + return CodegenType.SERVER; + } + + /** + * Configures a friendly name for the generator. This will be used by the generator to select + * the library with the -l flag. + * + * @return the friendly name for the generator + */ + public String getName() { + return "java-vertx"; + } + + /** + * Returns human-friendly help for the generator. Provide the consumer with help tips, + * parameters here + * + * @return A string value for the help message + */ + public String getHelp() { + return "Generates a java-Vert.X Server library."; + } + + @Override + public String getDefaultTemplateDir() { + return "JavaVertXServer"; + } + + @Override + public void processOpts() { + + if (dateLibrary.equals("legacy")){ + // can't use legacy format + LOGGER.warn("Legacy date library could not be used. Replaced to java8 as default"); + setDateLibrary("java8"); + } + + super.processOpts(); + + modelTemplateFiles.clear(); + modelTemplateFiles.put("model.mustache", ".java"); + + apiTemplateFiles.clear(); + apiTemplateFiles.put("api.mustache", ".java"); + + apiTestTemplateFiles.clear(); + modelDocTemplateFiles.clear(); + apiDocTemplateFiles.clear(); + + if (additionalProperties.containsKey(USE_DATAOBJECT_OPTION)) { + this.useDataObject = (Boolean.valueOf(additionalProperties.get(USE_DATAOBJECT_OPTION).toString())); + } + + + if (additionalProperties.containsKey(MOUNT_OPERATION_FROM_OPTION)) { + if (MOUNT_OPERATION_FROM_INTERFACE.equals(additionalProperties.get(MOUNT_OPERATION_FROM_OPTION))) { + this.mountFromInterface = true; + additionalProperties.put(MOUNT_OPERATION_FROM_INTERFACE, true); + } + } + if (!this.mountFromInterface) { + this.mountFromExtensions = true; + additionalProperties.put(MOUNT_OPERATION_FROM_EXTENSIONS, true); + } + + if (!additionalProperties.containsKey(SPEC_LOCATION_OPTION)) { + additionalProperties.put(SPEC_LOCATION_OPTION, SPEC_LOCATION); + } + + supportingFiles.clear(); + supportingFiles.add(new SupportingFile("MainApiVerticle.mustache", sourceFolder + File.separator + rootPackage.replace(".", File.separator), "MainApiVerticle.java")); + + supportingFiles.add(new SupportingFile("package-info-service.mustache", sourceFolder + File.separator + apiPackage.replace(".", File.separator), "package-info.java")); + + if (this.useDataObject) { + supportingFiles.add(new SupportingFile("package-info-model.mustache", sourceFolder + File.separator + modelPackage.replace(".", File.separator), "package-info.java")); + supportingFiles.add(new SupportingFile("json-mappers.mustache", projectFolder + File.separator + "resources/META-INF/vertx", "json-mappers.properties")); + supportingFiles.add(new SupportingFile("DataObjectMapper.mustache", sourceFolder + File.separator + modelPackage.replace(".", File.separator), "DataObjectMapper.java")); + } + + writeOptional(outputFolder, new SupportingFile("pom.mustache", "", "pom.xml")); + writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md")); + + addHandlebarsLambdas(additionalProperties); + } + + @Override + public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { + super.postProcessModelProperty(model, property); + + boolean isEnum = getBooleanValue(model, IS_ENUM_EXT_NAME); + if (!Boolean.TRUE.equals(isEnum)) { + model.imports.add("JsonProperty"); + boolean hasEnums = getBooleanValue(model, HAS_ENUMS_EXT_NAME); + if (Boolean.TRUE.equals(hasEnums)) { + model.imports.add("JsonValue"); + } + } + + // not use + model.imports.remove("Schema"); + } + + @Override + public CodegenModel fromModel(String name, Schema schema, Map allSchemas) { + CodegenModel codegenModel = super.fromModel(name, schema, allSchemas); + codegenModel.imports.remove("ApiModel"); + codegenModel.imports.remove("ApiModelProperty"); + return codegenModel; + } + + @Override + public void preprocessOpenAPI(OpenAPI openAPI) { + super.preprocessOpenAPI(openAPI); + + final URL urlInfo = URLPathUtil.getServerURL(openAPI); + String port = "8080"; + if (urlInfo != null && urlInfo.getPort() > 0) { + port = String.valueOf(urlInfo.getPort()); + } + + this.additionalProperties.put("serverPort", port); + + // From the title, compute a reasonable name for the package and the API + String title = openAPI.getInfo().getTitle(); + + // Drop any API suffix + title = title.trim().replace(" ", "-"); + if (title.toUpperCase().endsWith("API")) { + title = title.substring(0, title.length() - 3); + } + + title = camelize(sanitizeName(title)); + additionalProperties.put(TITLE, title); + supportingFiles.add(new SupportingFile("apiVerticle.mustache", sourceFolder + File.separator + apiVerticle.replace(".", File.separator), title + "Verticle.java")); + + /* + * manage operation & custom serviceId because operationId field is not + * required and may be empty + */ + Paths paths = openAPI.getPaths(); + if (paths != null) { + for (Entry entry : paths.entrySet()) { + manageOperations(entry.getValue(), entry.getKey()); + } + } + this.additionalProperties.remove("gson"); + } + + public void setUseBeanValidation(boolean useBeanValidation) { + this.useBeanValidation = useBeanValidation; + } + + @Override + public void setNotNullJacksonAnnotation(boolean notNullJacksonAnnotation) { + this.notNullJacksonAnnotation = notNullJacksonAnnotation; + } + + @Override + public boolean isNotNullJacksonAnnotation() { + return notNullJacksonAnnotation; + } + + private void addHandlebarsLambdas(Map objs) { + Map lambdas = new ImmutableMap.Builder() + .put("uppercase", new UppercaseLambda()) + .build(); + + if (objs.containsKey("lambda")) { + LOGGER.warn("An property named 'lambda' already exists. Mustache lambdas renamed from 'lambda' to '_lambda'. " + + "You'll likely need to use a custom template, " + + "see https://github.com/swagger-api/swagger-codegen#modifying-the-client-library-format. "); + objs.put("_lambda", lambdas); + } else { + objs.put("lambda", lambdas); + } + } + + private void manageOperations(PathItem pathItem, String pathname) { + Map operationMap = pathItem.readOperationsMap(); + if (operationMap != null) { + for (Entry entry : operationMap.entrySet()) { + String serviceId = null; + + if (this.mountFromExtensions) { + // read extension "x-vertx-event-bus" to write api service from address, not by tag + // Cases: from vertx doc + // 1. both strings or path extension null: operation extension overrides all + // 2. path extension map and operation extension string: path extension interpreted as delivery options and operation extension as address + // 3. path extension string and operation extension map: path extension interpreted as address + // 4. both maps: extension map overrides path map elements + // 5. operation extension null: path extension overrides all + Object pathExtension = getExtension(pathItem.getExtensions()); + Object operationExtension = getExtension(entry.getValue().getExtensions()); + + String address = null; + + if ((operationExtension instanceof String && pathExtension instanceof String) || pathExtension == null) { + if (operationExtension instanceof String) { + address = (String) operationExtension; + } else if (operationExtension instanceof Map) { + address = (String) ((Map) operationExtension).get(OPENAPI_EXTENSION_ADDRESS); + serviceId = (String) ((Map) operationExtension).get(OPENAPI_EXTENSION_METHOD_NAME); + } + } else if (operationExtension instanceof String && pathExtension instanceof Map) { + address = (((Map) pathExtension).containsKey(OPENAPI_EXTENSION_ADDRESS)) + ? (String) ((Map) pathExtension).get(OPENAPI_EXTENSION_ADDRESS) + : (String) operationExtension; + } else if (operationExtension instanceof Map && pathExtension instanceof String) { + address = (String) pathExtension; + serviceId = (String) ((Map) operationExtension).get(OPENAPI_EXTENSION_METHOD_NAME); + } else if (operationExtension instanceof Map && pathExtension instanceof Map) { + Map busExtension = new LinkedHashMap<>( + (Map) pathExtension); + busExtension.putAll((Map) operationExtension); + address = (String) (busExtension).get(OPENAPI_EXTENSION_ADDRESS); + serviceId = (String) (busExtension).get(OPENAPI_EXTENSION_METHOD_NAME); + } else if (operationExtension == null && pathExtension instanceof String) { + address = (String) pathExtension; + } else if (operationExtension == null && pathExtension instanceof Map) { + address = (String) ((Map) pathExtension).get(OPENAPI_EXTENSION_ADDRESS); + serviceId = (String) ((Map) pathExtension).get(OPENAPI_EXTENSION_METHOD_NAME); + } + + if (null != address) { + entry.getValue().addExtension("x-event-bus-address", address); + // codegen use tag to generate api, so we save tags & replace with event bus address + entry.getValue().setTags(Collections.singletonList(address)); + } else { + LOGGER.warn("event bus address not found on operationId {}, will not be mount", entry.getValue().getOperationId()); + } + } + + if (null == serviceId) { + serviceId = computeServiceId(pathname, entry); + } + entry.getValue().addExtension("x-serviceid", sanitizeOperationId(serviceId)); + } + } + } + + private Object getExtension(Map extensions) { + return null != extensions ? extensions.get(OPENAPI_EXTENSION) : null; + } + + /** + * @see io.vertx.ext.web.openapi.impl.OpenAPI3Utils#sanitizeOperationId + */ + private String sanitizeOperationId(String operationId) { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < operationId.length(); i++) { + char c = operationId.charAt(i); + if (c == '-' || c == ' ' || c == '_') { + try { + while (c == '-' || c == ' ' || c == '_') { + i++; + c = operationId.charAt(i); + } + result.append(Character.toUpperCase(operationId.charAt(i))); + } catch (StringIndexOutOfBoundsException e) { + } + } else { + result.append(c); + } + } + return result.toString(); + } + + private String computeServiceId(String pathname, Entry entry) { + String operationId = entry.getValue().getOperationId(); + return (operationId != null) ? operationId + : entry.getKey().name() + + pathname.replaceAll("-", "_").replaceAll("/", "_").replaceAll("[{}]", ""); + } + +} diff --git a/src/main/java/io/swagger/codegen/v3/generators/java/MicronautCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/java/MicronautCodegen.java index 91c4859f28..41d6d4ad40 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/java/MicronautCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/java/MicronautCodegen.java @@ -1,5 +1,6 @@ package io.swagger.codegen.v3.generators.java; +import com.github.jknack.handlebars.Handlebars; import com.github.jknack.handlebars.Lambda; import com.google.common.collect.ImmutableMap; import io.swagger.codegen.v3.*; @@ -30,10 +31,18 @@ public class MicronautCodegen extends AbstractJavaCodegen implements BeanValidationFeatures, OptionalFeatures { private static Logger LOGGER = LoggerFactory.getLogger(MicronautCodegen.class); + private static final String DEFAULT_LIBRARY = "rxjava3"; + private static final String RXJAVA3_LIBRARY = "rxjava3"; + private static final String RXJAVA2_LIBRARY = "rxjava2"; + private static final String REACTOR_LIBRARY = "reactor"; private static final String TITLE = "title"; private static final String CONFIG_PACKAGE = "configPackage"; private static final String BASE_PACKAGE = "basePackage"; private static final String USE_TAGS = "useTags"; + private static final String USE_RXJAVA = "useRxJava"; + private static final String USE_RXJAVA2 = "useRxJava2"; + private static final String USE_RXJAVA3 = "useRxJava3"; + private static final String USE_REACTOR = "useReactor"; private static final String IMPLICIT_HEADERS = "implicitHeaders"; private static final String SKIP_SUPPORT_FILES = "skipSupportFiles"; @@ -69,16 +78,21 @@ private void init() { cliOptions.add(new CliOption(BASE_PACKAGE, "base package (invokerPackage) for generated code")); cliOptions.add(new CliOption(SKIP_SUPPORT_FILES, "skip support files such as pom.xml, mvnw, etc from code generation.")); cliOptions.add(CliOption.newBoolean(USE_TAGS, "use tags for creating interface and controller classnames")); - cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations")); + + CliOption useBeanValidation = CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations"); + useBeanValidation.setDefault("true"); + cliOptions.add(useBeanValidation); + cliOptions.add(CliOption.newBoolean(IMPLICIT_HEADERS, "Use of @ApiImplicitParams for headers.")); cliOptions.add(CliOption.newBoolean(USE_OPTIONAL, "Use Optional container for optional parameters")); - supportedLibraries.put(DEFAULT_LIBRARY, "Java Micronaut Server application."); + supportedLibraries.put(DEFAULT_LIBRARY, "Java Micronaut Server application with RxJava3 reactive streams implementation"); + supportedLibraries.put(USE_RXJAVA2, "Java Micronaut Server application with RxJava2 reactive streams implementation"); + supportedLibraries.put(REACTOR_LIBRARY, "Java Micronaut Server application with Project Reactor reactive streams implementation"); setLibrary(DEFAULT_LIBRARY); CliOption library = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use"); - library.setDefault(DEFAULT_LIBRARY); library.setEnum(supportedLibraries); library.setDefault(DEFAULT_LIBRARY); cliOptions.add(library); @@ -138,8 +152,8 @@ public void processOpts() { this.setBasePackage((String) additionalProperties.get(BASE_PACKAGE)); } - if (additionalProperties.containsKey(USE_TAGS)) { - this.setUseTags(Boolean.valueOf(additionalProperties.get(USE_TAGS).toString())); + if (additionalProperties.get(USE_TAGS) != null) { + this.setUseTags(Boolean.parseBoolean(additionalProperties.get(USE_TAGS).toString())); } if (additionalProperties.containsKey(USE_BEANVALIDATION)) { @@ -151,21 +165,23 @@ public void processOpts() { } boolean skipSupportFiles = false; - if (additionalProperties.containsKey(SKIP_SUPPORT_FILES)) { - skipSupportFiles = Boolean.valueOf(additionalProperties.get(SKIP_SUPPORT_FILES).toString()); + if (additionalProperties.get(SKIP_SUPPORT_FILES) != null) { + skipSupportFiles = Boolean.parseBoolean(additionalProperties.get(SKIP_SUPPORT_FILES).toString()); } - if (useBeanValidation) { - writePropertyBack(USE_BEANVALIDATION, useBeanValidation); - } + writePropertyBack(USE_BEANVALIDATION, useBeanValidation); - if (additionalProperties.containsKey(IMPLICIT_HEADERS)) { - this.setImplicitHeaders(Boolean.valueOf(additionalProperties.get(IMPLICIT_HEADERS).toString())); + if (additionalProperties.get(IMPLICIT_HEADERS) != null) { + this.setImplicitHeaders(Boolean.parseBoolean(additionalProperties.get(IMPLICIT_HEADERS).toString())); } - if (useOptional) { - writePropertyBack(USE_OPTIONAL, useOptional); + writePropertyBack(USE_OPTIONAL, useOptional); + if (isRxJava2Library()) { + additionalProperties.put(USE_RXJAVA2, true); + } else { + additionalProperties.put(USE_RXJAVA3, isRxJava3Library()); } + additionalProperties.put(USE_REACTOR, isReactorLibrary()); if (!skipSupportFiles) { supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")); @@ -174,7 +190,8 @@ public void processOpts() { supportingFiles.add(new SupportingFile("mvnw.cmd", "", "mvnw.cmd")); supportingFiles.add(new SupportingFile("unsupportedOperationExceptionHandler.mustache", (sourceFolder + File.separator + configPackage).replace(".", File.separator), "UnsupportedOperationExceptionHandler.java")); - supportingFiles.add(new SupportingFile("mainApplication.mustache", (sourceFolder + File.separator).replace(".", File.separator), "MainApplication.java")); + supportingFiles.add(new SupportingFile("mainApplication.mustache", (sourceFolder + File.separator + basePackage).replace(".", File.separator), "MainApplication.java")); + apiTemplateFiles.put("apiController.mustache", "Controller.java"); } addHandlebarsLambdas(additionalProperties); } @@ -529,4 +546,22 @@ public void setUseBeanValidation(boolean useBeanValidation) { public void setUseOptional(boolean useOptional) { this.useOptional = useOptional; } + + @Override + public void addHandlebarHelpers(Handlebars handlebars) { + handlebars.setInfiniteLoops(true); + super.addHandlebarHelpers(handlebars); + } + + private boolean isRxJava2Library() { + return library.equals(RXJAVA2_LIBRARY); + } + + private boolean isRxJava3Library() { + return library.equals(RXJAVA3_LIBRARY); + } + + private boolean isReactorLibrary() { + return library.equals(REACTOR_LIBRARY); + } } diff --git a/src/main/java/io/swagger/codegen/v3/generators/java/SpringCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/java/SpringCodegen.java index c77711db1a..29b7276a4f 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/java/SpringCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/java/SpringCodegen.java @@ -21,7 +21,9 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; -import org.apache.commons.lang3.StringUtils; +import io.swagger.v3.oas.models.media.ArraySchema; +import io.swagger.v3.oas.models.media.MapSchema; +import io.swagger.v3.oas.models.media.Schema; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,7 +31,13 @@ import java.io.IOException; import java.io.Writer; import java.net.URL; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.stream.Collectors; @@ -51,12 +59,15 @@ public class SpringCodegen extends AbstractJavaCodegen implements BeanValidation public static final String USE_TAGS = "useTags"; public static final String SPRING_MVC_LIBRARY = "spring-mvc"; public static final String SPRING_CLOUD_LIBRARY = "spring-cloud"; + public static final String SPRING_BOOT_3_LIBRARY = "spring-boot3"; public static final String IMPLICIT_HEADERS = "implicitHeaders"; public static final String SWAGGER_DOCKET_CONFIG = "swaggerDocketConfig"; public static final String TARGET_OPENFEIGN = "generateForOpenFeign"; public static final String DEFAULT_INTERFACES = "defaultInterfaces"; public static final String SPRING_BOOT_VERSION = "springBootVersion"; public static final String SPRING_BOOT_VERSION_2 = "springBootV2"; + public static final String DATE_PATTERN = "datePattern"; + public static final String DATE_TIME_PATTERN = "dateTimePattern"; public static final String THROWS_EXCEPTION = "throwsException"; @@ -68,6 +79,7 @@ public class SpringCodegen extends AbstractJavaCodegen implements BeanValidation protected boolean delegateMethod = false; protected boolean singleContentTypes = false; protected boolean java8 = false; + protected boolean java11 = false; protected boolean async = false; protected String responseWrapper = ""; protected boolean useTags = false; @@ -112,8 +124,11 @@ public SpringCodegen() { cliOptions.add(CliOption.newBoolean(TARGET_OPENFEIGN,"Generate for usage with OpenFeign (instead of feign)")); cliOptions.add(CliOption.newBoolean(DEFAULT_INTERFACES, "Generate default implementations for interfaces").defaultValue("true")); cliOptions.add(CliOption.newBoolean(THROWS_EXCEPTION, "Throws Exception in operation methods").defaultValue("false")); + cliOptions.add(CliOption.newBoolean(DATE_PATTERN, "use pattern for date parameters").defaultValue("true")); + cliOptions.add(CliOption.newBoolean(DATE_TIME_PATTERN, "use pattern for date time parameters").defaultValue("true")); supportedLibraries.put(DEFAULT_LIBRARY, "Spring-boot Server application using the SpringFox integration."); + supportedLibraries.put(SPRING_BOOT_3_LIBRARY, "Spring-boot v3 Server application."); supportedLibraries.put(SPRING_MVC_LIBRARY, "Spring-MVC Server application using the SpringFox integration."); supportedLibraries.put(SPRING_CLOUD_LIBRARY, "Spring-Cloud-Feign client with Spring-Boot auto-configured settings."); setLibrary(DEFAULT_LIBRARY); @@ -181,10 +196,19 @@ public void processOpts() { if (!additionalProperties.containsKey(DATE_LIBRARY)) { setDateLibrary("java8"); } - } else { - this.defaultInterfaces = false; } + if (additionalProperties.containsKey(JAVA11_MODE)) { + this.setJava11(Boolean.valueOf(additionalProperties.get(JAVA11_MODE).toString())); + } + if (this.java11) { + additionalProperties.put("javaVersion", "11"); + additionalProperties.put("jdk11", "true"); + } + + additionalProperties.put("isJava8or11", this.java8 || this.java11); + this.defaultInterfaces = this.java8 || this.java11; + // set invokerPackage as basePackage if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) { this.setBasePackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE)); @@ -192,6 +216,10 @@ public void processOpts() { LOGGER.info("Set base package to invoker package (" + basePackage + ")"); } + if (isSpringBoot3Library()) { + setDateLibrary("java8"); + } + super.processOpts(); // clear model and api doc template as this codegen @@ -302,7 +330,16 @@ public void processOpts() { supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); if (!this.interfaceOnly) { - + if (isSpringBoot3Library()) { + useOas2 = false; + additionalProperties.remove("threetenbp"); + additionalProperties.put(JAKARTA, jakarta = true); + apiTestTemplateFiles.clear(); + supportingFiles.add(new SupportingFile("homeController.mustache", (sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "HomeController.java")); + supportingFiles.add(new SupportingFile("openAPISpringBoot.mustache", (sourceFolder + File.separator + basePackage).replace(".", java.io.File.separator), "OpenAPISpringBoot.java")); + supportingFiles.add(new SupportingFile("swaggerUiConfiguration.mustache", (sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "SwaggerUiConfiguration.java")); + supportingFiles.add(new SupportingFile("application.mustache", ("src.main.resources").replace(".", java.io.File.separator), "application.properties")); + } if (isDefaultLibrary()) { apiTestTemplateFiles.clear(); supportingFiles.add(new SupportingFile("homeController.mustache", @@ -363,10 +400,16 @@ public void processOpts() { (sourceFolder + File.separator + apiPackage).replace(".", java.io.File.separator), "NotFoundException.java")); supportingFiles.add(new SupportingFile("apiOriginFilter.mustache", (sourceFolder + File.separator + apiPackage).replace(".", java.io.File.separator), "ApiOriginFilter.java")); - supportingFiles.add(new SupportingFile("swaggerDocumentationConfig.mustache", + if (!isSpringBoot3Library()) { + supportingFiles.add(new SupportingFile("swaggerDocumentationConfig.mustache", (sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "SwaggerDocumentationConfig.java")); + } + supportingFiles.add(new SupportingFile("LocalDateConverter.mustache", + (sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "LocalDateConverter.java")); + supportingFiles.add(new SupportingFile("LocalDateTimeConverter.mustache", + (sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "LocalDateTimeConverter.java")); } - } else if ( this.swaggerDocketConfig && !isSpringCloudLibrary()) { + } else if ( this.swaggerDocketConfig && !isSpringCloudLibrary() && !isSpringBoot3Library()) { supportingFiles.add(new SupportingFile("swaggerDocumentationConfig.mustache", (sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "SwaggerDocumentationConfig.java")); } @@ -383,7 +426,7 @@ public void processOpts() { } } - if ((!this.delegatePattern && this.java8) || this.delegateMethod) { + if ((!this.delegatePattern && (this.java8 || this.java11)) || this.delegateMethod) { additionalProperties.put("jdk8-no-delegate", true); } @@ -450,6 +493,19 @@ public void execute(Template.Fragment fragment, Writer writer) throws IOExceptio } } + @Override + public CodegenProperty fromProperty(String name, Schema propertySchema) { + CodegenProperty codegenProperty = super.fromProperty(name, propertySchema); + if (propertySchema != null && propertySchema.get$ref() != null) { + Schema refSchema = OpenAPIUtil.getSchemaFromRefSchema(propertySchema, this.openAPI); + if (refSchema != null && !isObjectSchema(refSchema) && !(refSchema instanceof ArraySchema) && !(refSchema instanceof MapSchema) && refSchema.getEnum() == null) { + setSchemaProperties(name, codegenProperty, refSchema); + processPropertySchemaTypes(name, codegenProperty, refSchema); + } + } + return codegenProperty; + } + @Override public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map> operations) { if((isDefaultLibrary() || isSpringMvcLibrary()) && !useTags) { @@ -718,6 +774,9 @@ private boolean isSpringMvcLibrary() { private boolean isDefaultLibrary() { return library.equals(DEFAULT_LIBRARY); } + private boolean isSpringBoot3Library() { + return library.equals(SPRING_BOOT_3_LIBRARY); + } @Override public Map postProcessSupportingFileData(Map objs) { @@ -800,6 +859,8 @@ public void setSingleContentTypes(boolean singleContentTypes) { public void setJava8(boolean java8) { this.java8 = java8; } + public void setJava11(boolean java11) { this.java11 = java11; } + public void setAsync(boolean async) { this.async = async; } public void setResponseWrapper(String responseWrapper) { this.responseWrapper = responseWrapper; } diff --git a/src/main/java/io/swagger/codegen/v3/generators/kotlin/AbstractKotlinCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/kotlin/AbstractKotlinCodegen.java index f37df9ccb1..d42ae0a90c 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/kotlin/AbstractKotlinCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/kotlin/AbstractKotlinCodegen.java @@ -1,5 +1,6 @@ package io.swagger.codegen.v3.generators.kotlin; +import com.github.jknack.handlebars.helper.ConditionalHelpers; import io.swagger.codegen.v3.CliOption; import io.swagger.codegen.v3.CodegenConstants; import io.swagger.codegen.v3.CodegenModel; @@ -9,6 +10,7 @@ import io.swagger.v3.oas.models.media.MapSchema; import io.swagger.v3.oas.models.media.ObjectSchema; import io.swagger.v3.oas.models.media.Schema; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.github.jknack.handlebars.helper.StringHelpers; @@ -182,6 +184,7 @@ public AbstractKotlinCodegen() { typeMapping.put("binary", "kotlin.Array"); typeMapping.put("Date", "java.time.LocalDate"); typeMapping.put("DateTime", "java.time.LocalDateTime"); + typeMapping.put("ByteArray", "kotlin.ByteArray"); instantiationTypes.put("array", "arrayOf"); instantiationTypes.put("list", "arrayOf"); @@ -508,10 +511,16 @@ public String toVarName(String name) { return super.toVarName(sanitizeKotlinSpecificNames(name)); } + @Override + public String toEnumName(CodegenProperty property) { + return StringUtils.capitalize(property.name); + } + @Override public void addHandlebarHelpers(Handlebars handlebars) { super.addHandlebarHelpers(handlebars); handlebars.registerHelpers(StringHelpers.class); + handlebars.registerHelpers(ConditionalHelpers.class); } /** diff --git a/src/main/java/io/swagger/codegen/v3/generators/kotlin/KotlinClientCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/kotlin/KotlinClientCodegen.java index b55c430108..61509bdd89 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/kotlin/KotlinClientCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/kotlin/KotlinClientCodegen.java @@ -57,12 +57,6 @@ public KotlinClientCodegen() { cliOptions.add(dateLibrary); } - @Override - public void addHandlebarHelpers(Handlebars handlebars) { - super.addHandlebarHelpers(handlebars); - handlebars.registerHelpers(ConditionalHelpers.class); - } - @Override public String getDefaultTemplateDir() { return "kotlin-client"; diff --git a/src/main/java/io/swagger/codegen/v3/generators/nodejs/NodeJSServerCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/nodejs/NodeJSServerCodegen.java index d2814604e3..24a29d3724 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/nodejs/NodeJSServerCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/nodejs/NodeJSServerCodegen.java @@ -10,6 +10,7 @@ import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; +import io.swagger.codegen.v3.generators.OperationParameters; import io.swagger.codegen.v3.utils.URLPathUtil; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; @@ -452,7 +453,7 @@ protected void configuresParameterForMediaType(CodegenOperation codegenOperation addParameters(content, codegenOperation.cookieParams); } for (CodegenContent content : codegenContents) { - addHasMore(content.getParameters()); + OperationParameters.addHasMore(content.getParameters()); } codegenOperation.getContents().addAll(codegenContents); } diff --git a/src/main/java/io/swagger/codegen/v3/generators/php/AbstractPhpCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/php/AbstractPhpCodegen.java index 51dad7e72d..62c8b9f953 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/php/AbstractPhpCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/php/AbstractPhpCodegen.java @@ -251,7 +251,7 @@ public String toSrcPath(String packageName, String basePath) { } @Override - public String escapeReservedWord(String name) { + public String escapeReservedWord(String name) { if(this.reservedWordsMappings().containsKey(name)) { return this.reservedWordsMappings().get(name); } diff --git a/src/main/java/io/swagger/codegen/v3/generators/php/PhpClientCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/php/PhpClientCodegen.java index 682e6cb869..daec128c11 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/php/PhpClientCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/php/PhpClientCodegen.java @@ -2,6 +2,7 @@ import io.swagger.codegen.v3.CliOption; import io.swagger.codegen.v3.CodegenConstants; +import io.swagger.codegen.v3.CodegenModel; import io.swagger.codegen.v3.CodegenOperation; import io.swagger.codegen.v3.CodegenParameter; import io.swagger.codegen.v3.CodegenProperty; @@ -9,25 +10,32 @@ import io.swagger.codegen.v3.CodegenType; import io.swagger.codegen.v3.SupportingFile; import io.swagger.codegen.v3.generators.DefaultCodegenConfig; +import io.swagger.v3.oas.models.media.ArraySchema; +import io.swagger.v3.oas.models.media.BooleanSchema; +import io.swagger.v3.oas.models.media.DateSchema; +import io.swagger.v3.oas.models.media.DateTimeSchema; +import io.swagger.v3.oas.models.media.IntegerSchema; +import io.swagger.v3.oas.models.media.MapSchema; +import io.swagger.v3.oas.models.media.NumberSchema; +import io.swagger.v3.oas.models.media.ObjectSchema; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.media.StringSchema; +import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.parser.util.SchemaTypeUtil; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; -import java.util.Arrays; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.HashSet; import java.util.regex.Matcher; -import io.swagger.v3.oas.models.media.*; -import io.swagger.v3.oas.models.security.SecurityScheme; -import io.swagger.v3.parser.util.SchemaTypeUtil; -import org.apache.commons.lang3.StringUtils; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import static io.swagger.codegen.v3.generators.handlebars.ExtensionHelper.getBooleanValue; public class PhpClientCodegen extends DefaultCodegenConfig { @@ -103,7 +111,6 @@ public PhpClientCodegen() { instantiationTypes.put("array", "array"); instantiationTypes.put("map", "map"); - // provide primitives to mustache template List sortedLanguageSpecificPrimitives= new ArrayList(languageSpecificPrimitives); Collections.sort(sortedLanguageSpecificPrimitives); @@ -144,6 +151,7 @@ public PhpClientCodegen() { cliOptions.add(new CliOption(CodegenConstants.GIT_USER_ID, CodegenConstants.GIT_USER_ID_DESC)); cliOptions.add(new CliOption(COMPOSER_PROJECT_NAME, "The project name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. petstore-client. IMPORTANT NOTE (2016/03): composerProjectName will be deprecated and replaced by gitRepoId in the next swagger-codegen release")); cliOptions.add(new CliOption(CodegenConstants.GIT_REPO_ID, CodegenConstants.GIT_REPO_ID_DESC)); + cliOptions.add(new CliOption(CodegenConstants.GIT_REPO_BASE_URL, CodegenConstants.GIT_REPO_BASE_URL_DESC)); cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, "The version to use in the composer package version field. e.g. 1.2.3")); cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "hides the timestamp when files were generated") .defaultValue(Boolean.TRUE.toString())); @@ -272,6 +280,12 @@ public void processOpts() { additionalProperties.put(CodegenConstants.GIT_REPO_ID, gitRepoId); } + if (additionalProperties.containsKey(CodegenConstants.GIT_REPO_BASE_URL)) { + this.setGitRepoBaseURL((String) additionalProperties.get(CodegenConstants.GIT_REPO_BASE_URL)); + } else { + additionalProperties.put(CodegenConstants.GIT_REPO_BASE_URL, gitRepoBaseURL); + } + if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_VERSION)) { this.setArtifactVersion((String) additionalProperties.get(CodegenConstants.ARTIFACT_VERSION)); } else { @@ -281,6 +295,12 @@ public void processOpts() { if (additionalProperties.containsKey(VARIABLE_NAMING_CONVENTION)) { this.setParameterNamingConvention((String) additionalProperties.get(VARIABLE_NAMING_CONVENTION)); } + if (StringUtils.isBlank(composerVendorName) && additionalProperties.get(CodegenConstants.GIT_USER_ID) != null) { + additionalProperties.put(CodegenConstants.GIT_USER_ID, StringUtils.lowerCase(additionalProperties.get(CodegenConstants.GIT_USER_ID).toString())); + } + if (StringUtils.isBlank(composerProjectName) && additionalProperties.get(CodegenConstants.GIT_REPO_ID) != null) { + additionalProperties.put(CodegenConstants.GIT_REPO_ID, StringUtils.lowerCase(additionalProperties.get(CodegenConstants.GIT_REPO_ID).toString())); + } additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\")); @@ -444,6 +464,12 @@ public void setComposerProjectName(String composerProjectName) { this.composerProjectName = composerProjectName; } + @Override + protected void processMapSchema(CodegenModel codegenModel, String name, Schema schema) { + super.processMapSchema(codegenModel, name, schema); + addVars(codegenModel, schema.getProperties(), schema.getRequired()); + } + @Override public String toVarName(String name) { // sanitize name diff --git a/src/main/java/io/swagger/codegen/v3/generators/python/PythonClientCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/python/PythonClientCodegen.java index eb7ba3b64a..2eadf6071e 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/python/PythonClientCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/python/PythonClientCodegen.java @@ -202,16 +202,18 @@ public void processOpts() { setPackageUrl((String) additionalProperties.get(PACKAGE_URL)); } + final String packageFolder = packageName.replace('.', File.separatorChar); + supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); supportingFiles.add(new SupportingFile("tox.mustache", "", "tox.ini")); supportingFiles.add(new SupportingFile("test-requirements.mustache", "", "test-requirements.txt")); supportingFiles.add(new SupportingFile("requirements.mustache", "", "requirements.txt")); - supportingFiles.add(new SupportingFile("configuration.mustache", packageName, "configuration.py")); - supportingFiles.add(new SupportingFile("__init__package.mustache", packageName, "__init__.py")); - supportingFiles.add(new SupportingFile("__init__model.mustache", packageName + File.separatorChar + modelPackage, "__init__.py")); - supportingFiles.add(new SupportingFile("__init__api.mustache", packageName + File.separatorChar + apiPackage, "__init__.py")); + supportingFiles.add(new SupportingFile("configuration.mustache", packageFolder, "configuration.py")); + supportingFiles.add(new SupportingFile("__init__package.mustache", packageFolder, "__init__.py")); + supportingFiles.add(new SupportingFile("__init__model.mustache", packageFolder + File.separatorChar + modelPackage, "__init__.py")); + supportingFiles.add(new SupportingFile("__init__api.mustache", packageFolder + File.separatorChar + apiPackage, "__init__.py")); if(Boolean.FALSE.equals(excludeTests)) { supportingFiles.add(new SupportingFile("__init__test.mustache", testFolder, "__init__.py")); @@ -220,16 +222,16 @@ public void processOpts() { supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore")); supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml")); supportingFiles.add(new SupportingFile("setup.mustache", "", "setup.py")); - supportingFiles.add(new SupportingFile("api_client.mustache", packageName, "api_client.py")); + supportingFiles.add(new SupportingFile("api_client.mustache", packageFolder, "api_client.py")); if ("asyncio".equals(getLibrary())) { - supportingFiles.add(new SupportingFile("asyncio/rest.mustache", packageName, "rest.py")); + supportingFiles.add(new SupportingFile("asyncio/rest.mustache", packageFolder, "rest.py")); additionalProperties.put("asyncio", "true"); } else if ("tornado".equals(getLibrary())) { - supportingFiles.add(new SupportingFile("tornado/rest.mustache", packageName, "rest.py")); + supportingFiles.add(new SupportingFile("tornado/rest.mustache", packageFolder, "rest.py")); additionalProperties.put("tornado", "true"); } else { - supportingFiles.add(new SupportingFile("rest.mustache", packageName, "rest.py")); + supportingFiles.add(new SupportingFile("rest.mustache", packageFolder, "rest.py")); } modelPackage = packageName + "." + modelPackage; diff --git a/src/main/java/io/swagger/codegen/v3/generators/swift/Swift5Codegen.java b/src/main/java/io/swagger/codegen/v3/generators/swift/Swift5Codegen.java index a7e3118d3a..eeeda01842 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/swift/Swift5Codegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/swift/Swift5Codegen.java @@ -254,7 +254,7 @@ public void processOpts() { if (StringUtils.isBlank(templateDir)) { embeddedTemplateDir = templateDir = getTemplateDir(); } - + // Setup project name if (additionalProperties.containsKey(PROJECT_NAME)) { setProjectName((String) additionalProperties.get(PROJECT_NAME)); @@ -348,9 +348,6 @@ public void processOpts() { supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore")); - - copyFistAllOfProperties = true; - } @Override @@ -852,5 +849,10 @@ private static void reconcileProperties(CodegenModel codegenModel, codegenModel.vars = codegenProperties; } } + + @Override + protected boolean copyFirstAllOfProperties(Schema allOfSchema) { + return false; + } } diff --git a/src/main/java/io/swagger/codegen/v3/generators/typescript/AbstractTypeScriptClientCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/typescript/AbstractTypeScriptClientCodegen.java index eb1c8cf76d..0d173042ae 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/typescript/AbstractTypeScriptClientCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/typescript/AbstractTypeScriptClientCodegen.java @@ -10,9 +10,11 @@ import io.swagger.codegen.v3.generators.util.OpenAPIUtil; import io.swagger.v3.oas.models.media.ArraySchema; import io.swagger.v3.oas.models.media.BooleanSchema; +import io.swagger.v3.oas.models.media.BinarySchema; import io.swagger.v3.oas.models.media.ComposedSchema; import io.swagger.v3.oas.models.media.DateSchema; import io.swagger.v3.oas.models.media.DateTimeSchema; +import io.swagger.v3.oas.models.media.FileSchema; import io.swagger.v3.oas.models.media.IntegerSchema; import io.swagger.v3.oas.models.media.MapSchema; import io.swagger.v3.oas.models.media.NumberSchema; @@ -38,7 +40,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegenConfig { - private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTypeScriptClientCodegen.class); + protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractTypeScriptClientCodegen.class); private static final String UNDEFINED_VALUE = "undefined"; @@ -238,17 +240,24 @@ public CodegenModel fromModel(String name, Schema schema, Map al @Override public String getTypeDeclaration(Schema propertySchema) { - if (propertySchema instanceof ArraySchema) { - Schema inner = ((ArraySchema) propertySchema).getItems(); - return String.format("%s<%s>", getSchemaType(propertySchema), getTypeDeclaration(inner)); - } else if (propertySchema instanceof MapSchema && hasSchemaProperties(propertySchema)) { - Schema inner = (Schema) propertySchema.getAdditionalProperties(); - return String.format("{ [key, string]: %s;}", getTypeDeclaration(inner)); + Schema inner; + if(propertySchema instanceof ArraySchema) { + ArraySchema arraySchema = (ArraySchema)propertySchema; + inner = arraySchema.getItems(); + return this.getSchemaType(propertySchema) + "<" + this.getTypeDeclaration(inner) + ">"; + } else if(propertySchema instanceof MapSchema && hasSchemaProperties(propertySchema)) { + inner = (Schema) propertySchema.getAdditionalProperties(); + return "{ [key: string]: " + this.getTypeDeclaration(inner) + "; }"; } else if (propertySchema instanceof MapSchema && hasTrueAdditionalProperties(propertySchema)) { - Schema inner = new ObjectSchema(); - return String.format("{ [key, string]: %s;}", getTypeDeclaration(inner)); + inner = new ObjectSchema(); + return "{ [key: string]: " + this.getTypeDeclaration(inner) + "; }"; + } else if(propertySchema instanceof FileSchema || propertySchema instanceof BinarySchema) { + return "Blob"; + } else if(propertySchema instanceof ObjectSchema) { + return "any"; + } else { + return super.getTypeDeclaration(propertySchema); } - return super.getTypeDeclaration(propertySchema); } @Override @@ -298,6 +307,10 @@ public String toDefaultValue(Schema propertySchema) { @Override public String getSchemaType(Schema schema) { String swaggerType = super.getSchemaType(schema); + if (swaggerType == null) { + // default to object, see #10496 + swaggerType = "object"; + } if (schema instanceof ComposedSchema) { ComposedSchema composedSchema = (ComposedSchema)schema; if (composedSchema.getAllOf() != null && !composedSchema.getAllOf().isEmpty()) { diff --git a/src/main/java/io/swagger/codegen/v3/generators/typescript/TypeScriptAngularClientCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/typescript/TypeScriptAngularClientCodegen.java index b0b329a1cf..d41e86ae26 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/typescript/TypeScriptAngularClientCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/typescript/TypeScriptAngularClientCodegen.java @@ -46,6 +46,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode public static final String NG_PACKAGR = "useNgPackagr"; public static final String PROVIDED_IN_ROOT ="providedInRoot"; public static final String KEBAB_FILE_NAME ="kebab-file-name"; + public static final String USE_OVERRIDE ="useOverride"; protected String npmName = null; protected String npmVersion = "1.0.0"; @@ -63,6 +64,7 @@ public TypeScriptAngularClientCodegen() { this.cliOptions.add(new CliOption(WITH_INTERFACES, "Setting this property to true will generate interfaces next to the default class implementations.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); this.cliOptions.add(new CliOption(NG_VERSION, "The version of Angular. Default is '4.3'")); this.cliOptions.add(new CliOption(PROVIDED_IN_ROOT, "Use this property to provide Injectables in root (it is only valid in angular version greater or equal to 6.0.0).", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); + this.cliOptions.add(new CliOption(USE_OVERRIDE, "Use this property to place `override` keyword in encoder methods.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); } @Override @@ -160,6 +162,15 @@ public void processOpts() { // Libraries generated with v2.x of ng-packagr will ship with AoT metadata in v4, which is intended for Angular v5 (and Angular v6). additionalProperties.put("useOldNgPackagr", !ngVersion.atLeast("5.0.0")); + // set http client usage + if (ngVersion.atLeast("8.0.0")) { + additionalProperties.put("useHttpClient", true); + } else if (ngVersion.atLeast("4.3.0")) { + additionalProperties.put("useHttpClient", true); + } else { + additionalProperties.put("useHttpClient", false); + } + if (additionalProperties.containsKey(PROVIDED_IN_ROOT) && !ngVersion.atLeast("6.0.0")) { additionalProperties.put(PROVIDED_IN_ROOT,false); } @@ -178,6 +189,11 @@ public void processOpts() { } } + if (additionalProperties.containsKey(USE_OVERRIDE)) { + final boolean useOverride = Boolean.parseBoolean(String.valueOf(additionalProperties.get(USE_OVERRIDE))); + additionalProperties.put(USE_OVERRIDE, useOverride); + } + kebabFileNaming = Boolean.parseBoolean(String.valueOf(additionalProperties.get(KEBAB_FILE_NAME))); } @@ -203,8 +219,7 @@ private void addNpmPackageGeneration(SemVer ngVersion) { this.setNpmVersion(additionalProperties.get(NPM_VERSION).toString()); } - if (additionalProperties.containsKey(SNAPSHOT) - && Boolean.valueOf(additionalProperties.get(SNAPSHOT).toString())) { + if (additionalProperties.containsKey(SNAPSHOT) && Boolean.parseBoolean(additionalProperties.get(SNAPSHOT).toString())) { this.setNpmVersion(npmVersion + "-SNAPSHOT." + SNAPSHOT_SUFFIX_FORMAT.format(new Date())); } additionalProperties.put(NPM_VERSION, npmVersion); @@ -213,38 +228,51 @@ private void addNpmPackageGeneration(SemVer ngVersion) { this.setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString()); } - additionalProperties.put("useRxJS6", true); - additionalProperties.put("useHttpClient", true); additionalProperties.put("useHttpClientPackage", false); - if (ngVersion.atLeast("11.0.0")) { + if (ngVersion.atLeast("15.0.0")) { + additionalProperties.put("tsVersion", ">=4.8.2 <4.10.0"); + additionalProperties.put("rxjsVersion", "7.5.5"); + additionalProperties.put("ngPackagrVersion", "15.0.2"); + additionalProperties.put("zonejsVersion", "0.11.5"); + } else if (ngVersion.atLeast("14.0.0")) { + additionalProperties.put("tsVersion", ">=4.6.0 <=4.8.0"); + additionalProperties.put("rxjsVersion", "7.5.5"); + additionalProperties.put("ngPackagrVersion", "14.0.2"); + additionalProperties.put("zonejsVersion", "0.11.5"); + } else if (ngVersion.atLeast("13.0.0")) { + additionalProperties.put("tsVersion", ">=4.4.2 <4.5.0"); + additionalProperties.put("rxjsVersion", "7.4.0"); + additionalProperties.put("ngPackagrVersion", "13.0.3"); + additionalProperties.put("zonejsVersion", "0.11.4"); + } else if (ngVersion.atLeast("12.0.0")) { + additionalProperties.put("tsVersion", ">=4.3.0 <4.4.0"); + additionalProperties.put("rxjsVersion", "7.4.0"); + additionalProperties.put("ngPackagrVersion", "12.2.1"); + additionalProperties.put("zonejsVersion", "0.11.4"); + } else if (ngVersion.atLeast("11.0.0")) { additionalProperties.put("tsVersion", ">=4.0.0 <4.1.0"); additionalProperties.put("rxjsVersion", "6.6.0"); additionalProperties.put("ngPackagrVersion", "11.0.2"); - additionalProperties.put("tsickleVersion", "0.39.1"); additionalProperties.put("zonejsVersion", "0.11.3"); } else if (ngVersion.atLeast("10.0.0")) { additionalProperties.put("tsVersion", ">=3.9.2 <4.0.0"); additionalProperties.put("rxjsVersion", "6.6.0"); additionalProperties.put("ngPackagrVersion", "10.0.3"); - additionalProperties.put("tsickleVersion", "0.39.1"); additionalProperties.put("zonejsVersion", "0.10.2"); } else if (ngVersion.atLeast("9.0.0")) { additionalProperties.put("tsVersion", ">=3.6.0 <3.8.0"); additionalProperties.put("rxjsVersion", "6.5.3"); additionalProperties.put("ngPackagrVersion", "9.0.1"); - additionalProperties.put("tsickleVersion", "0.38.0"); additionalProperties.put("zonejsVersion", "0.10.2"); } else if (ngVersion.atLeast("8.0.0")) { additionalProperties.put("tsVersion", ">=3.4.0 <3.6.0"); additionalProperties.put("rxjsVersion", "6.5.0"); additionalProperties.put("ngPackagrVersion", "5.4.0"); - additionalProperties.put("tsickleVersion", "0.35.0"); additionalProperties.put("zonejsVersion", "0.9.1"); } else if (ngVersion.atLeast("7.0.0")) { additionalProperties.put("tsVersion", ">=3.1.1 <3.2.0"); additionalProperties.put("rxjsVersion", "6.3.0"); additionalProperties.put("ngPackagrVersion", "5.1.0"); - additionalProperties.put("tsickleVersion", "0.34.0"); additionalProperties.put("zonejsVersion", "0.8.26"); additionalProperties.put("useHttpClientPackage", true); @@ -252,7 +280,6 @@ private void addNpmPackageGeneration(SemVer ngVersion) { additionalProperties.put("tsVersion", ">=2.7.2 and <2.10.0"); additionalProperties.put("rxjsVersion", "6.1.0"); additionalProperties.put("ngPackagrVersion", "3.0.6"); - additionalProperties.put("tsickleVersion", "0.32.1"); additionalProperties.put("zonejsVersion", "0.8.26"); additionalProperties.put("useHttpClientPackage", true); @@ -260,10 +287,8 @@ private void addNpmPackageGeneration(SemVer ngVersion) { additionalProperties.put("tsVersion", ">=2.1.5 and <2.8"); additionalProperties.put("rxjsVersion", "6.1.0"); additionalProperties.put("ngPackagrVersion", "3.0.6"); - additionalProperties.put("tsickleVersion", "0.32.1"); additionalProperties.put("zonejsVersion", "0.8.26"); - additionalProperties.put("useRxJS6", false); additionalProperties.put("useHttpClientPackage", true); } @@ -350,6 +375,24 @@ private boolean isLanguageGenericType(String type) { return false; } + protected void addOperationImports(CodegenOperation codegenOperation, Set operationImports) { + for (String operationImport : operationImports) { + if (operationImport.contains("|")) { + String[] importNames = operationImport.split("\\|"); + for (String importName : importNames) { + importName = importName.trim(); + if (needToImport(importName)) { + codegenOperation.imports.add(importName); + } + } + } else { + if (needToImport(operationImport)) { + codegenOperation.imports.add(operationImport); + } + } + } + } + @Override public void postProcessParameter(CodegenParameter parameter) { super.postProcessParameter(parameter); diff --git a/src/main/java/io/swagger/codegen/v3/generators/typescript/TypeScriptAxiosClientCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/typescript/TypeScriptAxiosClientCodegen.java index 36994c3cf0..8717fcbebc 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/typescript/TypeScriptAxiosClientCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/typescript/TypeScriptAxiosClientCodegen.java @@ -1,10 +1,13 @@ package io.swagger.codegen.v3.generators.typescript; +import io.swagger.codegen.v3.CliOption; import io.swagger.codegen.v3.CodegenConstants; import io.swagger.codegen.v3.CodegenModel; import io.swagger.codegen.v3.CodegenOperation; import io.swagger.codegen.v3.CodegenProperty; import io.swagger.codegen.v3.SupportingFile; +import io.swagger.v3.oas.models.media.BooleanSchema; +import io.swagger.v3.oas.models.media.Schema; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; @@ -14,16 +17,21 @@ import java.util.Map; import java.util.TreeSet; +import static io.swagger.codegen.v3.CodegenConstants.IS_CONTAINER_EXT_NAME; import static io.swagger.codegen.v3.generators.handlebars.ExtensionHelper.getBooleanValue; public class TypeScriptAxiosClientCodegen extends AbstractTypeScriptClientCodegen { public static final String NPM_NAME = "npmName"; + public static final String NPM_VERSION = "npmVersion"; public static final String NPM_REPOSITORY = "npmRepository"; public static final String DEFAULT_API_PACKAGE = "apis"; public static final String DEFAULT_MODEL_PACKAGE = "models"; protected String npmRepository = null; + protected String npmName = null; + protected String npmVersion = "1.0.0"; + private String tsModelPackage = ""; @@ -31,6 +39,15 @@ public TypeScriptAxiosClientCodegen() { super(); importMapping.clear(); outputFolder = "generated-code/typescript-axios"; + LOGGER.info("Template folder: " + this.templateDir()); + LOGGER.info("Template engine: " + this.getTemplateEngine()); + reservedWords.add("query"); + + // Custom CLI options + this.cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package")); + this.cliOptions.add(new CliOption(NPM_VERSION, "The version of your npm package. Defaults to 1.0.0")); + this.cliOptions.add(new CliOption(NPM_REPOSITORY, + "Use this property to set an url your private npm registry in the package.json")); } @Override @@ -43,14 +60,14 @@ public String getHelp() { return "Generates a TypeScript Axios client library."; } - public String getNpmRepository() { - return npmRepository; - } - - public void setNpmRepository(String npmRepository) { - this.npmRepository = npmRepository; - } - + /** + * Creates a relative path to a file or folder. The resulting path is + * relative to the root directory of the final client library. + * + * @param path The path to the file or folder. + * @return A path to the file or folder which is relative to the client + * library root directory. + */ private static String getRelativeToRoot(String path) { StringBuilder sb = new StringBuilder(); int slashCount = path.split("/").length; @@ -99,6 +116,18 @@ public void processOpts() { supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); supportingFiles.add(new SupportingFile("package.mustache", "", "package.json")); supportingFiles.add(new SupportingFile("tsconfig.mustache", "", "tsconfig.json")); + + addNpmPackageGeneration(); + } + + protected void processMapSchema(CodegenModel codegenModel, String name, Schema schema) { + final Map properties = new HashMap<>(schema.getProperties()); + if (schema.getAdditionalProperties() instanceof Schema) { + properties.put("additionalProperties", (Schema) schema.getAdditionalProperties()); + } else if (schema.getAdditionalProperties() instanceof Boolean) { + properties.put("additionalProperties", new BooleanSchema()); + } + addVars(codegenModel, properties, schema.getRequired()); } @Override @@ -162,7 +191,7 @@ public Map postProcessModels(Map objs) { cm.classFilename = cm.classname.replaceAll("([a-z0-9])([A-Z])", "$1-$2").toLowerCase(Locale.ROOT); //processed enum names - cm.imports = new TreeSet(cm.imports); + cm.imports = new TreeSet(cm.imports); // name enum with model name, e.g. StatusEnum => PetStatusEnum for (CodegenProperty var : cm.vars) { if (getBooleanValue(var, CodegenConstants.IS_ENUM_EXT_NAME)) { @@ -191,6 +220,31 @@ public Map postProcessModels(Map objs) { return objs; } + /** + * Extracts npm package fields from `additionalProperties`. These fields + * are provided as custom CLI options. + */ + private void addNpmPackageGeneration() { + // Name of the NPM package + if (additionalProperties.containsKey(NPM_NAME)) { + this.setNpmName(additionalProperties.get(NPM_NAME).toString()); + } + + // NPM package version (SemVer) + if (additionalProperties.containsKey(NPM_VERSION)) { + this.setNpmVersion(additionalProperties.get(NPM_VERSION).toString()); + } + /* Package version has default value. Make internal version and + * additionalProperties version consistent. + */ + additionalProperties.put(NPM_VERSION, npmVersion); + + // NPM registry the package is pushed to + if (additionalProperties.containsKey(NPM_REPOSITORY)) { + this.setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString()); + } + } + /** * Overriding toRegularExpression() to avoid escapeText() being called, * as it would return a broken regular expression if any escaped character / metacharacter were present. @@ -214,4 +268,44 @@ public String toApiFilename(String name) { public String getDefaultTemplateDir() { return "typescript-axios"; } + + /** + * Gets the name of the generated NPM package. + * + * @return The NPM package name. + */ + public String getNpmName() { + return this.npmName; + } + + public void setNpmName(String npmName) { + this.npmName = npmName; + } + + /** + * Gets the generated NPM package SemVer string. + * + * @return The package version. + */ + public String getNpmVersion() { + return this.npmVersion; + } + + public void setNpmVersion(String npmVersion) { + this.npmVersion = npmVersion; + } + + /** + * Gets the name of the NPM registry the package is published to. + * + * @return The NPM registry name. + */ + public String getNpmRepository() { + return this.npmRepository; + } + + public void setNpmRepository(String npmRepository) { + this.npmRepository = npmRepository; + } + } diff --git a/src/main/java/io/swagger/codegen/v3/generators/util/OpenAPIUtil.java b/src/main/java/io/swagger/codegen/v3/generators/util/OpenAPIUtil.java index f6a47bc7b9..da3c7f2dff 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/util/OpenAPIUtil.java +++ b/src/main/java/io/swagger/codegen/v3/generators/util/OpenAPIUtil.java @@ -22,7 +22,9 @@ public static void addPropertiesFromRef(OpenAPI openAPI, Schema refSchema, Codeg if (schema == null) { return; } - codegenProperty.pattern = schema.getPattern(); + if (StringUtils.isBlank(codegenProperty.pattern)) { + codegenProperty.pattern = schema.getPattern(); + } codegenProperty.minLength = schema.getMinLength(); codegenProperty.maxLength = schema.getMaxLength(); if (codegenProperty.pattern != null || codegenProperty.minLength != null || codegenProperty.maxLength != null) { @@ -51,6 +53,17 @@ public static Schema getSchemaFromName(String name, OpenAPI openAPI) { return mapSchema.get(name); } + public static Schema getRefSchemaIfExists(Schema schema, OpenAPI openAPI) { + if (schema == null) { + return null; + } + if (StringUtils.isBlank(schema.get$ref()) || openAPI == null || openAPI.getComponents() == null) { + return schema; + } + final String name = getSimpleRef(schema.get$ref()); + return getSchemaFromName(name, openAPI); + } + public static Schema getSchemaFromRefSchema(Schema refSchema, OpenAPI openAPI) { if (StringUtils.isBlank(refSchema.get$ref())) { return null; diff --git a/src/main/resources/META-INF/services/io.swagger.codegen.v3.CodegenConfig b/src/main/resources/META-INF/services/io.swagger.codegen.v3.CodegenConfig index 69ee5fda50..2adb275cf1 100644 --- a/src/main/resources/META-INF/services/io.swagger.codegen.v3.CodegenConfig +++ b/src/main/resources/META-INF/services/io.swagger.codegen.v3.CodegenConfig @@ -17,6 +17,7 @@ io.swagger.codegen.v3.generators.java.JavaJerseyServerCodegen io.swagger.codegen.v3.generators.java.JavaJerseyDIServerCodegen io.swagger.codegen.v3.generators.java.JavaResteasyEapServerCodegen io.swagger.codegen.v3.generators.java.JavaResteasyServerCodegen +io.swagger.codegen.v3.generators.java.JavaVertXServerCodegen io.swagger.codegen.v3.generators.java.MicronautCodegen io.swagger.codegen.v3.generators.java.SpringCodegen io.swagger.codegen.v3.generators.nodejs.NodeJSServerCodegen diff --git a/src/main/resources/handlebars/Java/ApiClient.mustache b/src/main/resources/handlebars/Java/ApiClient.mustache index a30bdb1dfa..8002803fb2 100644 --- a/src/main/resources/handlebars/Java/ApiClient.mustache +++ b/src/main/resources/handlebars/Java/ApiClient.mustache @@ -29,8 +29,14 @@ import com.sun.jersey.api.client.WebResource.Builder; import com.sun.jersey.multipart.FormDataMultiPart; import com.sun.jersey.multipart.file.FileDataBodyPart; +{{#jakarta}} +import jakarta.ws.rs.core.Response.Status.Family; +import jakarta.ws.rs.core.MediaType; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.Response.Status.Family; import javax.ws.rs.core.MediaType; +{{/jakarta}} import java.util.Collection; import java.util.Collections; diff --git a/src/main/resources/handlebars/Java/BeanValidationException.mustache b/src/main/resources/handlebars/Java/BeanValidationException.mustache index ab8ef30b69..9bb486a758 100644 --- a/src/main/resources/handlebars/Java/BeanValidationException.mustache +++ b/src/main/resources/handlebars/Java/BeanValidationException.mustache @@ -1,9 +1,14 @@ package {{invokerPackage}}; import java.util.Set; - +{{#jakarta}} +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ValidationException; +{{/jakarta}} +{{^jakarta}} import javax.validation.ConstraintViolation; import javax.validation.ValidationException; +{{/jakarta}} public class BeanValidationException extends ValidationException { /** diff --git a/src/main/resources/handlebars/Java/api_test.mustache b/src/main/resources/handlebars/Java/api_test.mustache index c9a25efeef..8c13fe4577 100644 --- a/src/main/resources/handlebars/Java/api_test.mustache +++ b/src/main/resources/handlebars/Java/api_test.mustache @@ -2,12 +2,19 @@ package {{package}}; -import {{invokerPackage}}.ApiException; {{#imports}}import {{import}}; {{/imports}} import org.junit.Test; import org.junit.Ignore; +{{#wiremock}} +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import java.net.HttpURLConnection; +import org.junit.AfterClass; +import org.junit.BeforeClass; +{{/wiremock}} + {{^fullJavaUtil}} import java.util.ArrayList; import java.util.HashMap; @@ -15,6 +22,10 @@ import java.util.List; import java.util.Map; {{/fullJavaUtil}} +{{#wiremock}} +import static com.github.tomakehurst.wiremock.client.WireMock.*; +{{/wiremock}} + /** * API tests for {{classname}} */ @@ -22,6 +33,32 @@ import java.util.Map; public class {{classname}}Test { private final {{classname}} api = new {{classname}}(); + {{#wiremock}} + private static WireMockServer wireMockServer; + + public {{classname}}Test() { + api.getApiClient().setBasePath("http://localhost:" + wireMockServer.port()); + } + + @BeforeClass + public static void setUp() { + wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().dynamicPort()); + wireMockServer.start(); + configureFor(wireMockServer.port()); + {{#operations}} + {{#operation}} + stubFor({{toLowerCase httpMethod}}(urlPathMatching("{{{path}}}")) + .willReturn(aResponse() + .withStatus(HttpURLConnection.HTTP_OK))); + {{/operation}} + {{/operations}} + } + + @AfterClass + public static void tearDown() { + wireMockServer.stop(); + } + {{/wiremock}} {{#operations}} {{#operation}} @@ -32,11 +69,11 @@ public class {{classname}}Test { * * {{notes}} * - * @throws ApiException + * @throws Exception * if the Api call fails */ @Test - public void {{operationId}}Test() throws ApiException { + public void {{operationId}}Test() throws Exception { {{#parameters}} {{{dataType}}} {{paramName}} = null; {{/parameters}} diff --git a/src/main/resources/handlebars/Java/build.gradle.java11.mustache b/src/main/resources/handlebars/Java/build.gradle.java11.mustache new file mode 100644 index 0000000000..3b86cfec6f --- /dev/null +++ b/src/main/resources/handlebars/Java/build.gradle.java11.mustache @@ -0,0 +1,76 @@ +plugins { + id 'java' + id 'maven-publish' +} + +repositories { + mavenLocal() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +ext { + swagger_annotations_version = "{{#useOas2}}1.5.24{{/useOas2}}{{^useOas2}}2.0.0{{/useOas2}}" + jackson_version = "{{^threetenbp}}2.11.4{{/threetenbp}}{{#threetenbp}}2.6.4{{/threetenbp}}" + jersey_version = "{{#jakarta}}3.1.0{{/jakarta}}{{^jakarta}}1.19.4{{/jakarta}}" + jodatime_version = "2.10.5" + junit_version = "4.13.1" +} + +dependencies { + {{#useOas2}} + implementation "io.swagger:swagger-annotations:$swagger_annotations_version" + {{/useOas2}} + {{^useOas2}} + implementation "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" + {{/useOas2}} + implementation "com.sun.jersey:jersey-client:$jersey_version" + implementation "com.sun.jersey.contribs:jersey-multipart:$jersey_version" + implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version" + {{#joda}} + implementation "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" + {{/joda}} + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version"} + {{#threetenbp}} + implementation "com.github.joschi.jackson:jackson-datatype-threetenbp:$jackson_version" + {{/threetenbp}} + implementation 'com.sun.xml.ws:jaxws-rt:{{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}2.3.3{{/jakarta}}' + testImplementation "junit:junit:$junit_version" + {{#wiremock}} + testImplementation "com.github.tomakehurst:wiremock:2.27.2" + {{/wiremock}} +} + +group = '{{groupId}}' +version = '{{artifactVersion}}' +description = '{{artifactDescription}}' + +java.sourceCompatibility = 11 +java.targetCompatibility = 11 + +tasks.register('testsJar', Jar) { + archiveClassifier = 'tests' + from(sourceSets.test.output) +} + +java { + withSourcesJar() + withJavadocJar() +} + +publishing { + publications { + maven(MavenPublication) { + from(components.java) + artifact(testsJar) + } + } +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} diff --git a/src/main/resources/handlebars/Java/build.gradle.mustache b/src/main/resources/handlebars/Java/build.gradle.mustache index 34cb09be17..c33edecc5c 100644 --- a/src/main/resources/handlebars/Java/build.gradle.mustache +++ b/src/main/resources/handlebars/Java/build.gradle.mustache @@ -6,7 +6,7 @@ version = '{{artifactVersion}}' buildscript { repositories { - jcenter() + mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:2.3.+' @@ -15,7 +15,7 @@ buildscript { } repositories { - jcenter() + mavenCentral() } @@ -54,7 +54,12 @@ if(hasProperty('target') && target == 'android') { } dependencies { + {{#jakarta}} + provided 'jakarta.annotation:jakarta.annotation-api:2.1.1' + {{/jakarta}} + {{^jakarta}} provided 'javax.annotation:jsr250-api:1.0' + {{/jakarta}} } } @@ -82,7 +87,7 @@ if(hasProperty('target') && target == 'android') { } else { apply plugin: 'java' - apply plugin: 'maven' + apply plugin: 'maven-publish' {{#java8}} sourceCompatibility = JavaVersion.VERSION_1_8 @@ -93,9 +98,12 @@ if(hasProperty('target') && target == 'android') { targetCompatibility = JavaVersion.VERSION_1_7 {{/java8}} - install { - repositories.mavenInstaller { - pom.artifactId = '{{artifactId}}' + publishing { + publications { + maven(MavenPublication) { + artifactId = '{{artifactId}}' + from components.java + } } } @@ -112,36 +120,36 @@ ext { {{^useOas2}} swagger_annotations_version = "2.0.0" {{/useOas2}} - jackson_version = "{{^threetenbp}}2.10.1{{/threetenbp}}{{#threetenbp}}2.6.4{{/threetenbp}}" - jersey_version = "1.19.4" + jackson_version = "2.10.1" + jersey_version = "{{#jakarta}}3.1.0{{/jakarta}}{{^jakarta}}1.19.4{{/jakarta}}" jodatime_version = "2.9.9" junit_version = "4.12" } dependencies { {{#useOas2}} - compile "io.swagger:swagger-annotations:$swagger_annotations_version" + implementation "io.swagger:swagger-annotations:$swagger_annotations_version" {{/useOas2}} {{^useOas2}} - compile "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" + implementation "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" {{/useOas2}} - compile "com.sun.jersey:jersey-client:$jersey_version" - compile "com.sun.jersey.contribs:jersey-multipart:$jersey_version" - compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" - compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" - compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" - compile "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version" + implementation "com.sun.jersey:jersey-client:$jersey_version" + implementation "com.sun.jersey.contribs:jersey-multipart:$jersey_version" + implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version" {{#joda}} - compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" {{/joda}} {{#java8}} - compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" {{/java8}} {{#threetenbp}} - compile "com.github.joschi.jackson:jackson-datatype-threetenbp:$jackson_version" + implementation "com.github.joschi.jackson:jackson-datatype-threetenbp:2.6.4" {{/threetenbp}} {{^java8}} - compile "com.brsanthu:migbase64:2.2" + implementation "com.brsanthu:migbase64:2.2" {{/java8}} - testCompile "junit:junit:$junit_version" + testImplementation "junit:junit:$junit_version" } diff --git a/src/main/resources/handlebars/Java/generatedAnnotation.mustache b/src/main/resources/handlebars/Java/generatedAnnotation.mustache index a47b6faa85..c6c0883bcb 100644 --- a/src/main/resources/handlebars/Java/generatedAnnotation.mustache +++ b/src/main/resources/handlebars/Java/generatedAnnotation.mustache @@ -1 +1 @@ -{{^hideGenerationTimestamp}}@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} \ No newline at end of file +{{^hideGenerationTimestamp}}@{{#jakarta}}jakarta{{/jakarta}}{{^jakarta}}javax{{/jakarta}}.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} diff --git a/src/main/resources/handlebars/Java/gradle-wrapper.jar b/src/main/resources/handlebars/Java/gradle-wrapper.jar index 2c6137b878..d64cd49177 100644 Binary files a/src/main/resources/handlebars/Java/gradle-wrapper.jar and b/src/main/resources/handlebars/Java/gradle-wrapper.jar differ diff --git a/src/main/resources/handlebars/Java/gradle-wrapper.properties.mustache b/src/main/resources/handlebars/Java/gradle-wrapper.properties.mustache index b7a3647395..1af9e0930b 100644 --- a/src/main/resources/handlebars/Java/gradle-wrapper.properties.mustache +++ b/src/main/resources/handlebars/Java/gradle-wrapper.properties.mustache @@ -1,6 +1,7 @@ -#Tue May 17 23:08:05 CST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-bin.zip diff --git a/src/main/resources/handlebars/Java/interface.mustache b/src/main/resources/handlebars/Java/interface.mustache index becc0c5549..0d08bbe545 100644 --- a/src/main/resources/handlebars/Java/interface.mustache +++ b/src/main/resources/handlebars/Java/interface.mustache @@ -1,6 +1,26 @@ +{{#jackson}} +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +{{/jackson}} /** * {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} */ +{{#jackson}} +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "type") +@JsonSubTypes({ + {{#subTypes}} + @JsonSubTypes.Type(value = {{classname}}.class, name = "{{classname}}"){{^@last}},{{/@last}} + {{/subTypes}} +}) +{{/jackson}} public interface {{{classname}}} { +{{#vendorExtensions}} +{{#x-discriminator-type-getter}} + {{x-discriminator-type}} {{x-discriminator-type-getter}}(); +{{/x-discriminator-type-getter}} +{{/vendorExtensions}} } diff --git a/src/main/resources/handlebars/Java/libraries/feign/ApiClient.mustache b/src/main/resources/handlebars/Java/libraries/feign/ApiClient.mustache index 99153a2fcd..48d038345a 100644 --- a/src/main/resources/handlebars/Java/libraries/feign/ApiClient.mustache +++ b/src/main/resources/handlebars/Java/libraries/feign/ApiClient.mustache @@ -53,7 +53,7 @@ public class ApiClient { this(); for(String authName : authNames) { {{#hasAuthMethods}} - RequestInterceptor auth; + RequestInterceptor auth = null; {{#authMethods}}if ("{{name}}".equals(authName)) { {{#is this 'basic'}} auth = new HttpBasicAuth(); diff --git a/src/main/resources/handlebars/Java/libraries/feign/api.mustache b/src/main/resources/handlebars/Java/libraries/feign/api.mustache index ccefd3fcb3..4b7bd85243 100644 --- a/src/main/resources/handlebars/Java/libraries/feign/api.mustache +++ b/src/main/resources/handlebars/Java/libraries/feign/api.mustache @@ -40,10 +40,10 @@ public interface {{classname}} extends ApiClient.Api { @RequestLine("{{httpMethod}} {{{path}}}{{#hasQueryParams}}?{{/hasQueryParams}}{{#queryParams}}{{baseName}}={{braces "left"}}{{paramName}}{{braces "right"}}{{#has this 'more'}}&{{/has}}{{/queryParams}}") @Headers({ {{#vendorExtensions.x-contentType}} - "Content-Type: {{vendorExtensions.x-contentType}}", + "Content-Type: {{{vendorExtensions.x-contentType}}}", {{/vendorExtensions.x-contentType}} {{#vendorExtensions.x-accepts}} - "Accept: {{vendorExtensions.x-accepts}}", + "Accept: {{{vendorExtensions.x-accepts}}}", {{/vendorExtensions.x-accepts}} {{^vendorExtensions.x-accepts}} "Accept: */*", @@ -85,13 +85,13 @@ public interface {{classname}} extends ApiClient.Api { @RequestLine("{{httpMethod}} {{{path}}}?{{#queryParams}}{{baseName}}={{braces "left"}}{{paramName}}{{braces "right"}}{{#has this 'more'}}&{{/has}}{{/queryParams}}") @Headers({ {{#vendorExtensions.x-contentType}} - "Content-Type: {{vendorExtensions.x-contentType}}", + "Content-Type: {{{vendorExtensions.x-contentType}}}", {{/vendorExtensions.x-contentType}} {{^vendorExtensions.x-contentType}} "Content-Type: */*", {{/vendorExtensions.x-contentType}} {{#vendorExtensions.x-accepts}} - "Accept: {{vendorExtensions.x-accepts}}", + "Accept: {{{vendorExtensions.x-accepts}}}", {{/vendorExtensions.x-accepts}} {{#headerParams}} "{{baseName}}: {{braces "left"}}{{paramName}}{{braces "right"}}"{{#has this 'more'}},{{/has}} diff --git a/src/main/resources/handlebars/Java/libraries/feign/api_test.mustache b/src/main/resources/handlebars/Java/libraries/feign/api_test.mustache index 7423032672..6317437e47 100644 --- a/src/main/resources/handlebars/Java/libraries/feign/api_test.mustache +++ b/src/main/resources/handlebars/Java/libraries/feign/api_test.mustache @@ -6,6 +6,13 @@ import {{invokerPackage}}.ApiClient; import org.junit.Before; import org.junit.Test; +{{#wiremock}} +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import java.net.HttpURLConnection; +import org.junit.AfterClass; +{{/wiremock}} + {{^fullJavaUtil}} import java.util.ArrayList; import java.util.HashMap; @@ -13,6 +20,10 @@ import java.util.List; import java.util.Map; {{/fullJavaUtil}} +{{#wiremock}} +import static com.github.tomakehurst.wiremock.client.WireMock.*; +{{/wiremock}} + /** * API tests for {{classname}} */ @@ -20,10 +31,33 @@ public class {{classname}}Test { private {{classname}} api; + {{#wiremock}} + private static WireMockServer wireMockServer; + + @Before + public void setup() { + wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().dynamicPort()); + wireMockServer.start(); + configureFor(wireMockServer.port()); + api = new ApiClient().setBasePath("http://localhost:" + wireMockServer.port()).buildClient({{classname}}.class); + {{#operations}}{{#operation}} + stubFor({{toLowerCase httpMethod}}(urlPathMatching("{{{path}}}")) + .willReturn(aResponse() + .withStatus(HttpURLConnection.HTTP_OK))); + {{/operation}}{{/operations}} + } + + @AfterClass + public static void tearDown() { + wireMockServer.stop(); + } + {{/wiremock}} + {{^wiremock}} @Before public void setup() { api = new ApiClient().buildClient({{classname}}.class); } + {{/wiremock}} {{#operations}}{{#operation}}{{#contents}}{{#@first}} /** diff --git a/src/main/resources/handlebars/Java/libraries/feign/auth/OAuth.mustache b/src/main/resources/handlebars/Java/libraries/feign/auth/OAuth.mustache index 6be36b5b91..ede95edce7 100644 --- a/src/main/resources/handlebars/Java/libraries/feign/auth/OAuth.mustache +++ b/src/main/resources/handlebars/Java/libraries/feign/auth/OAuth.mustache @@ -87,19 +87,19 @@ public class OAuth implements RequestInterceptor { } // If first time, get the token if (expirationTimeMillis == null || System.currentTimeMillis() >= expirationTimeMillis) { - updateAccessToken(); + updateAccessToken(template); } if (getAccessToken() != null) { template.header("Authorization", "Bearer " + getAccessToken()); } } - public synchronized void updateAccessToken() { + public synchronized void updateAccessToken(RequestTemplate template) { OAuthJSONAccessTokenResponse accessTokenResponse; try { accessTokenResponse = oauthClient.accessToken(tokenRequestBuilder.buildBodyMessage()); } catch (Exception e) { - throw new RetryableException(e.getMessage(), e,null); + throw new RetryableException(400, e.getMessage(), template.request().httpMethod(), e, null, template.request()); } if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) { setAccessToken(accessTokenResponse.getAccessToken(), accessTokenResponse.getExpiresIn()); diff --git a/src/main/resources/handlebars/Java/libraries/feign/build.gradle.java11.mustache b/src/main/resources/handlebars/Java/libraries/feign/build.gradle.java11.mustache new file mode 100644 index 0000000000..4807c37713 --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/feign/build.gradle.java11.mustache @@ -0,0 +1,90 @@ +plugins { + id 'java' + id 'maven-publish' +} + +repositories { + mavenLocal() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +ext { + swagger_annotations_version = "{{#useOas2}}1.5.24{{/useOas2}}{{^useOas2}}2.0.0{{/useOas2}}" + jackson_version = "2.11.4" + {{#threetenbp}} + threepane_version = "2.6.4" + {{/threetenbp}} + feign_version = "11.6" + feign_form_version = "3.8.0" + junit_version = "4.13.1" + oltu_version = "1.0.2" +} + +dependencies { + {{#useOas2}} + implementation "io.swagger:swagger-annotations:$swagger_annotations_version" + {{/useOas2}} + {{^useOas2}} + implementation "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" + {{/useOas2}} + implementation "io.github.openfeign:feign-core:$feign_version" + implementation "io.github.openfeign:feign-jackson:$feign_version" + implementation "io.github.openfeign:feign-slf4j:$feign_version" + implementation "io.github.openfeign.form:feign-form:$feign_form_version" + implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + {{#joda}} + implementation "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" + {{/joda}} + {{#java8}} + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" + {{/java8}} + {{#threetenbp}} + implementation "com.github.joschi.jackson:jackson-datatype-threetenbp:$threepane_version" + {{/threetenbp}} + implementation("org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version") { + exclude group: 'org.json', module: 'json' + } + implementation "org.json:json:20180130" + implementation "com.brsanthu:migbase64:2.2" + implementation "com.sun.xml.ws:jaxws-rt:{{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}2.3.3{{/jakarta}}" + testImplementation "junit:junit:$junit_version" + testImplementation "com.squareup.okhttp3:mockwebserver:3.6.0" + testImplementation "org.assertj:assertj-core:1.7.1" + {{#wiremock}} + testImplementation "com.github.tomakehurst:wiremock:2.27.2" + {{/wiremock}} +} + +group = '{{groupId}}' +version = '{{artifactVersion}}' +description = '{{artifactDescription}}' + +java.sourceCompatibility = 11 +java.targetCompatibility = 11 + +tasks.register('testsJar', Jar) { + archiveClassifier = 'tests' + from(sourceSets.test.output) +} + +java { + withSourcesJar() + withJavadocJar() +} + +publishing { + publications { + maven(MavenPublication) { + from(components.java) + artifact(testsJar) + } + } +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} diff --git a/src/main/resources/handlebars/Java/libraries/feign/build.gradle.mustache b/src/main/resources/handlebars/Java/libraries/feign/build.gradle.mustache index 07b70c841d..e1e3d019dc 100644 --- a/src/main/resources/handlebars/Java/libraries/feign/build.gradle.mustache +++ b/src/main/resources/handlebars/Java/libraries/feign/build.gradle.mustache @@ -6,7 +6,7 @@ version = '{{artifactVersion}}' buildscript { repositories { - jcenter() + mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:2.3.+' @@ -15,7 +15,7 @@ buildscript { } repositories { - jcenter() + mavenCentral() } @@ -54,7 +54,12 @@ if(hasProperty('target') && target == 'android') { } dependencies { + {{#jakarta}} + provided 'jakarta.annotation:jakarta.annotation-api:2.1.1' + {{/jakarta}} + {{^jakarta}} provided 'javax.annotation:jsr250-api:1.0' + {{/jakarta}} } } @@ -82,14 +87,17 @@ if(hasProperty('target') && target == 'android') { } else { apply plugin: 'java' - apply plugin: 'maven' + apply plugin: 'maven-publish' sourceCompatibility = JavaVersion.VERSION_{{^java8}}1_7{{/java8}}{{#java8}}1_8{{/java8}} targetCompatibility = JavaVersion.VERSION_{{^java8}}1_7{{/java8}}{{#java8}}1_8{{/java8}} - install { - repositories.mavenInstaller { - pom.artifactId = '{{artifactId}}' + publishing { + publications { + maven(MavenPublication) { + artifactId = '{{artifactId}}' + from components.java + } } } @@ -110,36 +118,39 @@ ext { {{#threetenbp}} threepane_version = "2.6.4" {{/threetenbp}} - feign_version = "9.4.0" - feign_form_version = "2.1.0" + feign_version = "11.6" + feign_form_version = "3.8.0" junit_version = "4.12" oltu_version = "1.0.2" } dependencies { {{#useOas2}} - compile "io.swagger:swagger-annotations:$swagger_annotations_version" + implementation "io.swagger:swagger-annotations:$swagger_annotations_version" {{/useOas2}} {{^useOas2}} - compile "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" + implementation "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" {{/useOas2}} - compile "com.netflix.feign:feign-core:$feign_version" - compile "com.netflix.feign:feign-jackson:$feign_version" - compile "com.netflix.feign:feign-slf4j:$feign_version" - compile "io.github.openfeign.form:feign-form:$feign_form_version" - compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" - compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" - compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + implementation "io.github.openfeign:feign-core:$feign_version" + implementation "io.github.openfeign:feign-jackson:$feign_version" + implementation "io.github.openfeign:feign-slf4j:$feign_version" + implementation "io.github.openfeign.form:feign-form:$feign_form_version" + implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version" {{#joda}} - compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" {{/joda}} {{#java8}} - compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" {{/java8}} {{#threetenbp}} - compile "com.github.joschi.jackson:jackson-datatype-threetenbp:$threepane_version" + implementation "com.github.joschi.jackson:jackson-datatype-threetenbp:$threepane_version" {{/threetenbp}} - compile "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version" - compile "com.brsanthu:migbase64:2.2" - testCompile "junit:junit:$junit_version" + implementation ("org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version") { + exclude group: "org.json", module: "json" + } + implementation "org.json:json:20180130" + implementation "com.brsanthu:migbase64:2.2" + testImplementation "junit:junit:$junit_version" } diff --git a/src/main/resources/handlebars/Java/libraries/feign/pom.mustache b/src/main/resources/handlebars/Java/libraries/feign/pom.mustache index b6d531a652..28a263643b 100644 --- a/src/main/resources/handlebars/Java/libraries/feign/pom.mustache +++ b/src/main/resources/handlebars/Java/libraries/feign/pom.mustache @@ -117,7 +117,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.4 + 3.2.0 attach-javadocs @@ -165,6 +165,22 @@
+ {{#java11}} + + jdk11 + + [11,) + + + + com.sun.xml.ws + jaxws-rt + {{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}2.3.3{{/jakarta}} + pom + + + + {{/java11}} @@ -277,9 +293,17 @@ 1.7.1 test + {{#wiremock}} + + com.github.tomakehurst + wiremock + 2.27.2 + test + + {{/wiremock}} - {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} ${java.version} ${java.version} {{#useOas2}} @@ -288,9 +312,9 @@ {{^useOas2}} 2.0.0 {{/useOas2}} - 9.4.0 - 2.1.0 - 2.10.1 + 11.6 + 3.8.0 + 2.15.2 {{#threetenbp}} 2.6.4 {{/threetenbp}} diff --git a/src/main/resources/handlebars/Java/libraries/jersey2/ApiClient.mustache b/src/main/resources/handlebars/Java/libraries/jersey2/ApiClient.mustache index ae57563b55..46a113c45d 100644 --- a/src/main/resources/handlebars/Java/libraries/jersey2/ApiClient.mustache +++ b/src/main/resources/handlebars/Java/libraries/jersey2/ApiClient.mustache @@ -1,5 +1,18 @@ package {{invokerPackage}}; +{{#jakarta}} +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.Form; +import jakarta.ws.rs.core.GenericType; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; @@ -10,6 +23,7 @@ import javax.ws.rs.core.GenericType; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +{{/jakarta}} import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.client.ClientProperties; diff --git a/src/main/resources/handlebars/Java/libraries/jersey2/JSON.mustache b/src/main/resources/handlebars/Java/libraries/jersey2/JSON.mustache index 911391a6ba..e094645607 100644 --- a/src/main/resources/handlebars/Java/libraries/jersey2/JSON.mustache +++ b/src/main/resources/handlebars/Java/libraries/jersey2/JSON.mustache @@ -17,7 +17,12 @@ import com.fasterxml.jackson.datatype.threetenbp.ThreeTenModule; import java.text.DateFormat; +{{#jakarta}} +import jakarta.ws.rs.ext.ContextResolver; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.ext.ContextResolver; +{{/jakarta}} {{>generatedAnnotation}} public class JSON implements ContextResolver { diff --git a/src/main/resources/handlebars/Java/libraries/jersey2/api.mustache b/src/main/resources/handlebars/Java/libraries/jersey2/api.mustache index a2538f0e32..6e0dda863e 100644 --- a/src/main/resources/handlebars/Java/libraries/jersey2/api.mustache +++ b/src/main/resources/handlebars/Java/libraries/jersey2/api.mustache @@ -5,7 +5,12 @@ import {{invokerPackage}}.ApiClient; import {{invokerPackage}}.Configuration; import {{invokerPackage}}.Pair; +{{#jakarta}} +import jakarta.ws.rs.core.GenericType; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.GenericType; +{{/jakarta}} {{#imports}}import {{import}}; {{/imports}} diff --git a/src/main/resources/handlebars/Java/libraries/jersey2/build.gradle.java11.mustache b/src/main/resources/handlebars/Java/libraries/jersey2/build.gradle.java11.mustache new file mode 100644 index 0000000000..a4ccb154df --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/jersey2/build.gradle.java11.mustache @@ -0,0 +1,78 @@ +plugins { + id 'java' + id 'maven-publish' +} + +repositories { + mavenLocal() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +ext { + swagger_annotations_version = "{{#useOas2}}1.5.24{{/useOas2}}{{^useOas2}}2.0.0{{/useOas2}}" + jackson_version = "2.6.4" + jersey_version = "{{#jakarta}}3.1.0{{/jakarta}}{{^jakarta}}2.29.1{{/jakarta}}" + junit_version = "4.13.1" +} + +dependencies { + {{#useOas2}} + implementation "io.swagger:swagger-annotations:$swagger_annotations_version" + {{/useOas2}} + {{^useOas2}} + implementation "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" + {{/useOas2}} + implementation "org.glassfish.jersey.core:jersey-client:$jersey_version" + implementation "org.glassfish.jersey.media:jersey-media-multipart:$jersey_version" + implementation "org.glassfish.jersey.media:jersey-media-json-jackson:$jersey_version" + implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + {{#withXml}} + implementation "org.glassfish.jersey.media:jersey-media-jaxb:$jersey_version" + {{/withXml}} + {{#joda}} + implementation "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" + {{/joda}} + implementation "org.glassfish.jersey.inject:jersey-hk2:$jersey_version" + {{#threetenbp}} + implementation "com.github.joschi.jackson:jackson-datatype-threetenbp:$jackson_version" + {{/threetenbp}} + implementation "com.brsanthu:migbase64:2.2" + testImplementation "junit:junit:$junit_version" + {{#wiremock}} + testImplementation "com.github.tomakehurst:wiremock:2.27.2" + {{/wiremock}} +} + +group = '{{groupId}}' +version = '{{artifactVersion}}' +description = '{{artifactDescription}}' + +java.sourceCompatibility = 11 +java.targetCompatibility = 11 + +tasks.register('testsJar', Jar) { + archiveClassifier = 'tests' + from(sourceSets.test.output) +} + +java { + withSourcesJar() + withJavadocJar() +} + +publishing { + publications { + maven(MavenPublication) { + from(components.java) + artifact(testsJar) + } + } +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} diff --git a/src/main/resources/handlebars/Java/libraries/jersey2/build.gradle.mustache b/src/main/resources/handlebars/Java/libraries/jersey2/build.gradle.mustache index 759a1603bc..a89549d687 100644 --- a/src/main/resources/handlebars/Java/libraries/jersey2/build.gradle.mustache +++ b/src/main/resources/handlebars/Java/libraries/jersey2/build.gradle.mustache @@ -6,7 +6,7 @@ version = '{{artifactVersion}}' buildscript { repositories { - jcenter() + mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:2.3.+' @@ -15,7 +15,7 @@ buildscript { } repositories { - jcenter() + mavenCentral() } @@ -54,7 +54,12 @@ if(hasProperty('target') && target == 'android') { } dependencies { + {{#jakarta}} + provided 'jakarta.annotation:jakarta.annotation-api:2.1.1' + {{/jakarta}} + {{^jakarta}} provided 'javax.annotation:jsr250-api:1.0' + {{/jakarta}} } } @@ -82,7 +87,7 @@ if(hasProperty('target') && target == 'android') { } else { apply plugin: 'java' - apply plugin: 'maven' + apply plugin: 'maven-publish' {{#java8}} sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 @@ -92,9 +97,12 @@ if(hasProperty('target') && target == 'android') { targetCompatibility = JavaVersion.VERSION_1_7 {{/java8}} - install { - repositories.mavenInstaller { - pom.artifactId = '{{artifactId}}' + publishing { + publications { + maven(MavenPublication) { + artifactId = '{{artifactId}}' + from components.java + } } } @@ -112,7 +120,7 @@ ext { swagger_annotations_version = "2.0.0" {{/useOas2}} jackson_version = "2.10.1" - jersey_version = "2.26" + jersey_version = "{{#jakarta}}3.1.0{{/jakarta}}{{^jakarta}}2.26{{/jakarta}}" {{#supportJava6}} commons_io_version=2.5 commons_lang3_version=3.6 @@ -122,32 +130,32 @@ ext { dependencies { {{#useOas2}} - compile "io.swagger:swagger-annotations:$swagger_annotations_version" + implementation "io.swagger:swagger-annotations:$swagger_annotations_version" {{/useOas2}} {{^useOas2}} - compile "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" + implementation "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" {{/useOas2}} - compile "org.glassfish.jersey.core:jersey-client:$jersey_version" - compile "org.glassfish.jersey.media:jersey-media-multipart:$jersey_version" - compile "org.glassfish.jersey.media:jersey-media-json-jackson:$jersey_version" - compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" - compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" - compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + implementation "org.glassfish.jersey.core:jersey-client:$jersey_version" + implementation "org.glassfish.jersey.media:jersey-media-multipart:$jersey_version" + implementation "org.glassfish.jersey.media:jersey-media-json-jackson:$jersey_version" + implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version" {{#joda}} - compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" {{/joda}} {{#java8}} - compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" {{/java8}} {{#supportJava6}} - compile "commons-io:commons-io:$commons_io_version" - compile "org.apache.commons:commons-lang3:$commons_lang3_version" + implementation "commons-io:commons-io:$commons_io_version" + implementation "org.apache.commons:commons-lang3:$commons_lang3_version" {{/supportJava6}} {{#threetenbp}} - compile "com.github.joschi.jackson:jackson-datatype-threetenbp:$jackson_version" + implementation "com.github.joschi.jackson:jackson-datatype-threetenbp:2.6.4" {{/threetenbp}} {{^java8}} - compile "com.brsanthu:migbase64:2.2" + implementation "com.brsanthu:migbase64:2.2" {{/java8}} - testCompile "junit:junit:$junit_version" + testImplementation "junit:junit:$junit_version" } diff --git a/src/main/resources/handlebars/Java/libraries/jersey2/pom.mustache b/src/main/resources/handlebars/Java/libraries/jersey2/pom.mustache index f42c1f434a..02381182fa 100644 --- a/src/main/resources/handlebars/Java/libraries/jersey2/pom.mustache +++ b/src/main/resources/handlebars/Java/libraries/jersey2/pom.mustache @@ -132,7 +132,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.4 + 3.2.0 attach-javadocs @@ -289,12 +289,22 @@ {{/supportJava6}} {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + {{/jakarta}} + {{^jakarta}} javax.validation validation-api 1.1.0.Final provided + {{/jakarta}} {{/useBeanValidation}} @@ -303,6 +313,14 @@ ${junit-version} test + {{#wiremock}} + + com.github.tomakehurst + wiremock + 2.27.2 + test + + {{/wiremock}} {{#useOas2}} @@ -319,7 +337,7 @@ 2.5 3.6 {{/supportJava6}} - {{^threetenbp}}2.10.1{{/threetenbp}}{{#threetenbp}}2.6.4{{/threetenbp}} + {{^threetenbp}}2.15.2{{/threetenbp}}{{#threetenbp}}2.6.4{{/threetenbp}} 1.0.0 4.13.1 diff --git a/src/main/resources/handlebars/Java/libraries/jersey3/ApiClient.mustache b/src/main/resources/handlebars/Java/libraries/jersey3/ApiClient.mustache new file mode 100644 index 0000000000..8ff2f3ad82 --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/jersey3/ApiClient.mustache @@ -0,0 +1,806 @@ +package {{invokerPackage}}; + +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.Form; +import jakarta.ws.rs.core.GenericType; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.ClientProperties; +import org.glassfish.jersey.client.HttpUrlConnectorProvider; +import org.glassfish.jersey.jackson.JacksonFeature; +import org.glassfish.jersey.logging.LoggingFeature; +import org.glassfish.jersey.media.multipart.FormDataBodyPart; +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.MultiPart; +import org.glassfish.jersey.media.multipart.MultiPartFeature; + +import java.io.IOException; +import java.io.InputStream; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Map.Entry; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; +import java.util.Date; +import java.util.TimeZone; + +import java.net.URLEncoder; + +import java.io.File; +import java.io.UnsupportedEncodingException; + +import java.text.DateFormat; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import {{invokerPackage}}.auth.Authentication; +import {{invokerPackage}}.auth.HttpBasicAuth; +import {{invokerPackage}}.auth.ApiKeyAuth; +import {{invokerPackage}}.auth.OAuth; + +{{>generatedAnnotation}} +public class ApiClient { + protected Map defaultHeaderMap = new HashMap<>(); + protected String basePath = "{{{basePath}}}"; + protected boolean debugging = false; + protected int connectionTimeout = 0; + private int readTimeout = 0; + + protected Client httpClient; + protected JSON json; + protected String tempFolderPath = null; + + protected Map authentications; + + protected int statusCode; + protected Map> responseHeaders; + + protected DateFormat dateFormat; + + public ApiClient() { + json = new JSON(); + httpClient = buildHttpClient(debugging); + + this.dateFormat = new RFC3339DateFormat(); + + // Set default User-Agent. + setUserAgent("{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}Swagger-Codegen/{{{artifactVersion}}}/java{{/httpUserAgent}}"); + + // Setup authentications (key: authentication name, value: authentication). + authentications = new HashMap<>();{{#authMethods}}{{#is this 'basic'}} + authentications.put("{{name}}", new HttpBasicAuth());{{/is}}{{#is this 'api-key'}} + authentications.put("{{name}}", new ApiKeyAuth({{#is this 'key-in-header'}}"header"{{/is}}{{#isNot this 'key-in-header'}}"query"{{/isNot}}, "{{keyParamName}}"));{{/is}}{{#is this 'oauth'}} + authentications.put("{{name}}", new OAuth());{{/is}}{{#is this 'bearer'}} + authentications.put("{{name}}", new OAuth());{{/is}}{{/authMethods}} + // Prevent the authentications from being modified. + authentications = Collections.unmodifiableMap(authentications); + } + + /** + * Gets the JSON instance to do JSON serialization and deserialization. + * @return JSON + */ + public JSON getJSON() { + return json; + } + + public Client getHttpClient() { + return httpClient; + } + + public ApiClient setHttpClient(Client httpClient) { + this.httpClient = httpClient; + return this; + } + + public String getBasePath() { + return basePath; + } + + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + /** + * Gets the status code of the previous request + * @return Status code + */ + public int getStatusCode() { + return statusCode; + } + + /** + * Gets the response headers of the previous request + * @return Response headers + */ + public Map> getResponseHeaders() { + return responseHeaders; + } + + /** + * Get authentications (key: authentication name, value: authentication). + * @return Map of authentication object + */ + public Map getAuthentications() { + return authentications; + } + + /** + * Get authentication for the given name. + * + * @param authName The authentication name + * @return The authentication, null if not found + */ + public Authentication getAuthentication(String authName) { + return authentications.get(authName); + } + + /** + * Helper method to set username for the first HTTP basic authentication. + * @param username Username + */ + public void setUsername(String username) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setUsername(username); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set password for the first HTTP basic authentication. + * @param password Password + */ + public void setPassword(String password) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setPassword(password); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set API key value for the first API key authentication. + * @param apiKey API key + */ + public void setApiKey(String apiKey) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKey(apiKey); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set API key prefix for the first API key authentication. + * @param apiKeyPrefix API key prefix + */ + public void setApiKeyPrefix(String apiKeyPrefix) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set access token for the first OAuth2 authentication. + * @param accessToken Access token + */ + public void setAccessToken(String accessToken) { + for (Authentication auth : authentications.values()) { + if (auth instanceof OAuth) { + ((OAuth) auth).setAccessToken(accessToken); + return; + } + } + throw new RuntimeException("No OAuth2 authentication configured!"); + } + + /** + * Set the User-Agent header's value (by adding to the default header map). + * @param userAgent Http user agent + * @return API client + */ + public ApiClient setUserAgent(String userAgent) { + addDefaultHeader("User-Agent", userAgent); + return this; + } + + /** + * Add a default header. + * + * @param key The header's key + * @param value The header's value + * @return API client + */ + public ApiClient addDefaultHeader(String key, String value) { + defaultHeaderMap.put(key, value); + return this; + } + + /** + * Check that whether debugging is enabled for this API client. + * @return True if debugging is switched on + */ + public boolean isDebugging() { + return debugging; + } + + /** + * Enable/disable debugging for this API client. + * + * @param debugging To enable (true) or disable (false) debugging + * @return API client + */ + public ApiClient setDebugging(boolean debugging) { + this.debugging = debugging; + // Rebuild HTTP Client according to the new "debugging" value. + this.httpClient = buildHttpClient(debugging); + return this; + } + + /** + * The path of temporary folder used to store downloaded files from endpoints + * with file response. The default value is null, i.e. using + * the system's default tempopary folder. + * + * @return Temp folder path + */ + public String getTempFolderPath() { + return tempFolderPath; + } + + /** + * Set temp folder path + * @param tempFolderPath Temp folder path + * @return API client + */ + public ApiClient setTempFolderPath(String tempFolderPath) { + this.tempFolderPath = tempFolderPath; + return this; + } + + /** + * Connect timeout (in milliseconds). + * @return Connection timeout + */ + public int getConnectTimeout() { + return connectionTimeout; + } + + /** + * Set the connect timeout (in milliseconds). + * A value of 0 means no timeout, otherwise values must be between 1 and + * {@link Integer#MAX_VALUE}. + * @param connectionTimeout Connection timeout in milliseconds + * @return API client + */ + public ApiClient setConnectTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout; + httpClient.property(ClientProperties.CONNECT_TIMEOUT, connectionTimeout); + return this; + } + + /** + * read timeout (in milliseconds). + * @return Read timeout + */ + public int getReadTimeout() { + return readTimeout; + } + + /** + * Set the read timeout (in milliseconds). + * A value of 0 means no timeout, otherwise values must be between 1 and + * {@link Integer#MAX_VALUE}. + * @param readTimeout Read timeout in milliseconds + * @return API client + */ + public ApiClient setReadTimeout(int readTimeout) { + this.readTimeout = readTimeout; + httpClient.property(ClientProperties.READ_TIMEOUT, readTimeout); + return this; + } + + /** + * Get the date format used to parse/format date parameters. + * @return Date format + */ + public DateFormat getDateFormat() { + return dateFormat; + } + + /** + * Set the date format used to parse/format date parameters. + * @param dateFormat Date format + * @return API client + */ + public ApiClient setDateFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + // also set the date format for model (de)serialization with Date properties + this.json.setDateFormat((DateFormat) dateFormat.clone()); + return this; + } + + /** + * Parse the given string into Date object. + * @param str String + * @return Date + */ + public Date parseDate(String str) { + try { + return dateFormat.parse(str); + } catch (java.text.ParseException e) { + throw new RuntimeException(e); + } + } + + /** + * Format the given Date object into string. + * @param date Date + * @return Date in string format + */ + public String formatDate(Date date) { + return dateFormat.format(date); + } + + /** + * Format the given parameter object into string. + * @param param Object + * @return Object in string format + */ + public String parameterToString(Object param) { + if (param == null) { + return ""; + } else if (param instanceof Date) { + return formatDate((Date) param); + } else if (param instanceof Collection) { + StringBuilder b = new StringBuilder(); + for(Object o : (Collection)param) { + if(b.length() > 0) { + b.append(','); + } + b.append(String.valueOf(o)); + } + return b.toString(); + } else { + return String.valueOf(param); + } + } + + /* + * Format to {@code Pair} objects. + * @param collectionFormat Collection format + * @param name Name + * @param value Value + * @return List of pairs + */ + public List parameterToPairs(String collectionFormat, String name, Object value){ + List params = new ArrayList<>(); + + // preconditions + if (name == null || name.isEmpty() || value == null) { + return params; + } + + Collection valueCollection; + if (value instanceof Collection) { + valueCollection = (Collection) value; + } else { + params.add(new Pair(name, parameterToString(value))); + return params; + } + + if (valueCollection.isEmpty()){ + return params; + } + + // get the collection format (default: csv) + String format = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); + + // create the params based on the collection format + if ("multi".equals(format)) { + for (Object item : valueCollection) { + params.add(new Pair(name, parameterToString(item))); + } + return params; + } + + String delimiter = ","; + + if ("csv".equals(format)) { + delimiter = ","; + } else if ("ssv".equals(format)) { + delimiter = " "; + } else if ("tsv".equals(format)) { + delimiter = "\t"; + } else if ("pipes".equals(format)) { + delimiter = "|"; + } + + StringBuilder sb = new StringBuilder() ; + for (Object item : valueCollection) { + sb.append(delimiter); + sb.append(parameterToString(item)); + } + params.add(new Pair(name, sb.substring(1))); + return params; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * "* / *" is also default to JSON + * @param mime MIME + * @return True if the MIME type is JSON + */ + public boolean isJsonMime(String mime) { + String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$"; + return mime != null && (mime.matches(jsonMime) || mime.equals("*/*")); + } + + /** + * Select the Accept header's value from the given accepts array: + * if JSON exists in the given array, use it; + * otherwise use all of them (joining into a string) + * + * @param accepts The accepts array to select from + * @return The Accept header to use. If the given array is empty, + * null will be returned (not to set the Accept header explicitly). + */ + public String selectHeaderAccept(String[] accepts) { + if (accepts.length == 0) { + return null; + } + for (String accept : accepts) { + if (isJsonMime(accept)) { + return accept; + } + } + return StringUtil.join(accepts, ","); + } + + /** + * Select the Content-Type header's value from the given array: + * if JSON exists in the given array, use it; + * otherwise use the first one of the array. + * + * @param contentTypes The Content-Type array to select from + * @return The Content-Type header to use. If the given array is empty, + * JSON will be used. + */ + public String selectHeaderContentType(String[] contentTypes) { + if (contentTypes.length == 0) { + return "application/json"; + } + for (String contentType : contentTypes) { + if (isJsonMime(contentType)) { + return contentType; + } + } + return contentTypes[0]; + } + + /** + * Escape the given string to be used as URL query value. + * @param str String + * @return Escaped string + */ + public String escapeString(String str) { + try { + return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20"); + } catch (UnsupportedEncodingException e) { + return str; + } + } + + /** + * Serialize the given Java object into string entity according the given + * Content-Type (only JSON is supported for now). + * @param obj Object + * @param formParams Form parameters + * @param contentType Context type + * @return Entity + * @throws ApiException API exception + */ + public Entity serialize(Object obj, Map formParams, String contentType) throws ApiException { + Entity entity; + if (contentType.startsWith("multipart/form-data")) { + MultiPart multiPart = new MultiPart(); + for (Entry param: formParams.entrySet()) { + if (param.getValue() instanceof File) { + File file = (File) param.getValue(); + FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey()) + .fileName(file.getName()).size(file.length()).build(); + multiPart.bodyPart(new FormDataBodyPart(contentDisp, file, MediaType.APPLICATION_OCTET_STREAM_TYPE)); + } else { + FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey()).build(); + multiPart.bodyPart(new FormDataBodyPart(contentDisp, parameterToString(param.getValue()))); + } + } + entity = Entity.entity(multiPart, MediaType.MULTIPART_FORM_DATA_TYPE); + } else if (contentType.startsWith("application/x-www-form-urlencoded")) { + Form form = new Form(); + for (Entry param: formParams.entrySet()) { + form.param(param.getKey(), parameterToString(param.getValue())); + } + entity = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE); + } else { + // We let jersey handle the serialization + entity = Entity.entity(obj, contentType); + } + return entity; + } + + /** + * Deserialize response body to Java object according to the Content-Type. + * @param Type + * @param response Response + * @param returnType Return type + * @return Deserialize object + * @throws ApiException API exception + */ + @SuppressWarnings("unchecked") + public T deserialize(Response response, GenericType returnType) throws ApiException { + if (response == null || returnType == null) { + return null; + } + + if ("byte[]".equals(returnType.toString())) { + // Handle binary response (byte array). + return (T) response.readEntity(byte[].class); + } else if (returnType.getRawType() == File.class) { + // Handle file downloading. + T file = (T) downloadFileFromResponse(response); + return file; + } + String contentType = null; + List contentTypes = response.getHeaders().get("Content-Type"); + if (contentTypes != null && !contentTypes.isEmpty()) { + contentType = String.valueOf(contentTypes.get(0)); + } + if (contentType == null) { + throw new ApiException(500, "missing Content-Type in response"); + } + return response.readEntity(returnType); + } + + /** + * Download file from the given response. + * @param response Response + * @return File + * @throws ApiException If fail to read file content from response and write to disk + */ + public File downloadFileFromResponse(Response response) throws ApiException { + try { + File file = prepareDownloadFile(response); + Files.copy(response.readEntity(InputStream.class), file.toPath(), StandardCopyOption.REPLACE_EXISTING); + return file; + } catch (IOException e) { + throw new ApiException(e); + } + } + + public File prepareDownloadFile(Response response) throws IOException { + String filename = null; + String contentDisposition = (String) response.getHeaders().getFirst("Content-Disposition"); + if (contentDisposition != null && !"".equals(contentDisposition)) { + // Get filename from the Content-Disposition header. + Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?"); + Matcher matcher = pattern.matcher(contentDisposition); + if (matcher.find()) { + filename = matcher.group(1); + } + } + String prefix; + String suffix = null; + if (filename == null) { + prefix = "download-"; + suffix = ""; + } else { + int pos = filename.lastIndexOf('.'); + if (pos == -1) { + prefix = filename + "-"; + } else { + prefix = filename.substring(0, pos) + "-"; + suffix = filename.substring(pos); + } + // File.createTempFile requires the prefix to be at least three characters long + if (prefix.length() < 3) { + prefix = "download-"; + } + } + if (tempFolderPath == null) { + return Files.createTempFile(prefix, suffix).toFile(); + } else { + return Files.createTempFile(Paths.get(tempFolderPath), prefix, suffix).toFile(); + } + } + + /** + * Invoke API by sending HTTP request with the given options. + * + * @param Type + * @param path The sub-path of the HTTP URL + * @param method The request method, one of "GET", "POST", "PUT", "HEAD" and "DELETE" + * @param queryParams The query parameters + * @param body The request body object + * @param headerParams The header parameters + * @param formParams The form parameters + * @param accept The request's Accept header + * @param contentType The request's Content-Type header + * @param authNames The authentications to apply + * @param returnType The return type into which to deserialize the response + * @return The response body in type of string + * @throws ApiException API exception + */ + public T invokeAPI(String path, String method, List queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames, GenericType returnType) throws ApiException { + updateParamsForAuth(authNames, queryParams, headerParams); + + // Not using `.target(this.basePath).path(path)` below, + // to support (constant) query string in `path`, e.g. "/posts?draft=1" + WebTarget target = httpClient.target(this.basePath + path); + + if (queryParams != null) { + for (Pair queryParam : queryParams) { + if (queryParam.getValue() != null) { + target = target.queryParam(queryParam.getName(), queryParam.getValue()); + } + } + } + Invocation.Builder invocationBuilder = target.request(); + if (accept != null) { + invocationBuilder = invocationBuilder.accept(accept); + } + for (Entry entry : headerParams.entrySet()) { + String value = entry.getValue(); + if (value != null) { + invocationBuilder = invocationBuilder.header(entry.getKey(), value); + } + } + for (Entry entry : defaultHeaderMap.entrySet()) { + String key = entry.getKey(); + if (!headerParams.containsKey(key)) { + String value = entry.getValue(); + if (value != null) { + invocationBuilder = invocationBuilder.header(key, value); + } + } + } + Entity entity = serialize(body, formParams, contentType); + + Response response = null; + try { + if ("GET".equals(method)) { + response = invocationBuilder.get(); + } else if ("POST".equals(method)) { + response = invocationBuilder.post(entity); + } else if ("PUT".equals(method)) { + response = invocationBuilder.put(entity); + } else if ("DELETE".equals(method)) { + response = invocationBuilder.delete(); + } else if ("PATCH".equals(method)) { + response = invocationBuilder.method("PATCH", entity); + } else if ("HEAD".equals(method)) { + response = invocationBuilder.head(); + } else { + throw new ApiException(500, "unknown method type " + method); + } + + statusCode = response.getStatusInfo().getStatusCode(); + responseHeaders = buildResponseHeaders(response); + + if (response.getStatus() == Status.NO_CONTENT.getStatusCode()) { + return null; + } else if (response.getStatusInfo().getFamily() == Status.Family.SUCCESSFUL) { + if (returnType == null) { + return null; + } else { + return deserialize(response, returnType); + } + } else { + String message = "error"; + String respBody = null; + if (response.hasEntity()) { + try { + respBody = String.valueOf(response.readEntity(String.class)); + message = respBody; + } catch (RuntimeException e) { + // e.printStackTrace(); + } + } + throw new ApiException( + response.getStatus(), + message, + buildResponseHeaders(response), + respBody); + } + } finally { + try { + response.close(); + } catch (Exception e) { + // it's not critical, since the response object is local in method invokeAPI; that's fine, just continue + } + } + } + + /** + * Build the Client used to make HTTP requests. + * @param debugging Debug setting + * @return Client + */ + protected Client buildHttpClient(boolean debugging) { + final ClientConfig clientConfig = new ClientConfig(); + clientConfig.register(MultiPartFeature.class); + clientConfig.register(json); + clientConfig.register(JacksonFeature.class); + clientConfig.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true); + if (debugging) { + clientConfig.register(new LoggingFeature(java.util.logging.Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME), java.util.logging.Level.INFO, LoggingFeature.Verbosity.PAYLOAD_ANY, 1024*50 /* Log payloads up to 50K */)); + clientConfig.property(LoggingFeature.LOGGING_FEATURE_VERBOSITY, LoggingFeature.Verbosity.PAYLOAD_ANY); + // Set logger to ALL + java.util.logging.Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME).setLevel(java.util.logging.Level.ALL); + } + performAdditionalClientConfiguration(clientConfig); + return ClientBuilder.newClient(clientConfig); + } + + protected void performAdditionalClientConfiguration(ClientConfig clientConfig) { + // No-op extension point + } + + protected Map> buildResponseHeaders(Response response) { + Map> responseHeaders = new HashMap<>(); + for (Entry> entry: response.getHeaders().entrySet()) { + List values = entry.getValue(); + List headers = new ArrayList<>(); + for (Object o : values) { + headers.add(String.valueOf(o)); + } + responseHeaders.put(entry.getKey(), headers); + } + return responseHeaders; + } + + /** + * Update query and header parameters based on authentication settings. + * + * @param authNames The authentications to apply + */ + protected void updateParamsForAuth(String[] authNames, List queryParams, Map headerParams) { + for (String authName : authNames) { + Authentication auth = authentications.get(authName); + if (auth == null) { + throw new RuntimeException("Authentication undefined: " + authName); + } + auth.applyToParams(queryParams, headerParams); + } + } +} diff --git a/src/main/resources/handlebars/Java/libraries/jersey3/JSON.mustache b/src/main/resources/handlebars/Java/libraries/jersey3/JSON.mustache new file mode 100644 index 0000000000..928832f182 --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/jersey3/JSON.mustache @@ -0,0 +1,38 @@ +package {{invokerPackage}}; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import java.text.DateFormat; + +import jakarta.ws.rs.ext.ContextResolver; + +{{>generatedAnnotation}} +public class JSON implements ContextResolver { + private ObjectMapper mapper; + + public JSON() { + mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); + mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); + mapper.setDateFormat(new RFC3339DateFormat()); + mapper.registerModule(new JavaTimeModule()); + } + + /** + * Set the date format for JSON (de)serialization with Date properties. + * @param dateFormat Date format + */ + public void setDateFormat(DateFormat dateFormat) { + mapper.setDateFormat(dateFormat); + } + + @Override + public ObjectMapper getContext(Class type) { + return mapper; + } +} diff --git a/src/main/resources/handlebars/Java/libraries/jersey3/api.mustache b/src/main/resources/handlebars/Java/libraries/jersey3/api.mustache new file mode 100644 index 0000000000..9024d15a92 --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/jersey3/api.mustache @@ -0,0 +1,118 @@ +package {{package}};//jersey3 + +import {{invokerPackage}}.ApiException; +import {{invokerPackage}}.ApiClient; +import {{invokerPackage}}.Configuration; +import {{invokerPackage}}.Pair; + +import jakarta.ws.rs.core.GenericType; + +{{#imports}}import {{import}}; +{{/imports}} + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +{{>generatedAnnotation}} +{{#operations}} +public class {{classname}} { + private ApiClient {{localVariablePrefix}}apiClient; + + public {{classname}}() { + this(Configuration.getDefaultApiClient()); + } + + public {{classname}}(ApiClient apiClient) { + this.{{localVariablePrefix}}apiClient = apiClient; + } + + public ApiClient getApiClient() { + return {{localVariablePrefix}}apiClient; + } + + public void setApiClient(ApiClient apiClient) { + this.{{localVariablePrefix}}apiClient = apiClient; + } + + {{#operation}} + {{#contents}} + /** + * {{summary}} + * {{notes}} + {{#parameters}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} + {{/parameters}} + {{#returnType}} + * @return {{returnType}} + {{/returnType}} + * @throws ApiException if fails to make API call + {{#isDeprecated}} + * @deprecated + {{/isDeprecated}} + {{#externalDocs}} + * {{description}} + * @see {{summary}} Documentation + {{/externalDocs}} + */ + {{#isDeprecated}} + @Deprecated + {{/isDeprecated}} + public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#parameters}}{{{dataType}}} {{paramName}}{{#has this 'more'}}, {{/has}}{{/parameters}}) throws ApiException { + Object {{localVariablePrefix}}localVarPostBody = {{^isForm}}{{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}{{/isForm}}{{#isForm}}null{{/isForm}}; + {{#parameters}} + {{#required}} + // verify the required parameter '{{paramName}}' is set + if ({{paramName}} == null) { + throw new ApiException(400, "Missing the required parameter '{{paramName}}' when calling {{operationId}}"); + } + {{/required}} + {{/parameters}} + // create path and map variables + String {{localVariablePrefix}}localVarPath = "{{{path}}}"{{#pathParams}} + .replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}}; + + // query params + {{javaUtilPrefix}}List {{localVariablePrefix}}localVarQueryParams = new {{javaUtilPrefix}}ArrayList(); + {{javaUtilPrefix}}Map {{localVariablePrefix}}localVarHeaderParams = new {{javaUtilPrefix}}HashMap(); + {{javaUtilPrefix}}Map {{localVariablePrefix}}localVarFormParams = new {{javaUtilPrefix}}HashMap(); + + {{#queryParams}} + {{localVariablePrefix}}localVarQueryParams.addAll({{localVariablePrefix}}apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}})); + {{/queryParams}} + + {{#headerParams}} + if ({{paramName}} != null) { + {{localVariablePrefix}}localVarHeaderParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}})); + } + {{/headerParams}} + {{#isForm}} + {{#formParams}} + if ({{paramName}} != null) + {{localVariablePrefix}}localVarFormParams.put("{{baseName}}", {{paramName}}); + {{/formParams}} + {{/isForm}} + + final String[] {{localVariablePrefix}}localVarAccepts = { + {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} + }; + final String {{localVariablePrefix}}localVarAccept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}localVarAccepts); + final String[] {{localVariablePrefix}}localVarContentTypes = { + {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} + }; + final String {{localVariablePrefix}}localVarContentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}localVarContentTypes); + + String[] {{localVariablePrefix}}localVarAuthNames = new String[] { {{#authMethods}}"{{name}}"{{#has this 'more'}}, {{/has}}{{/authMethods}} }; + + {{#returnType}} + GenericType<{{{returnType}}}> {{localVariablePrefix}}localVarReturnType = new GenericType<{{{returnType}}}>() {}; + return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAccept, {{localVariablePrefix}}localVarContentType, {{localVariablePrefix}}localVarAuthNames, {{localVariablePrefix}}localVarReturnType); + {{/returnType}}{{^returnType}} + {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAccept, {{localVariablePrefix}}localVarContentType, {{localVariablePrefix}}localVarAuthNames, null); + {{/returnType}} + } + {{/contents}} + {{/operation}} +} +{{/operations}} diff --git a/src/main/resources/handlebars/Java/libraries/jersey3/build.gradle.mustache b/src/main/resources/handlebars/Java/libraries/jersey3/build.gradle.mustache new file mode 100644 index 0000000000..88426fa8d3 --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/jersey3/build.gradle.mustache @@ -0,0 +1,66 @@ +plugins { + id 'java' + id 'maven-publish' +} + +repositories { + mavenLocal() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +ext { + swagger_annotations_version = "2.2.8" + jackson_version = "2.14.2" + jersey_version = "3.1.1" + junit_version = "4.13.2" +} + +dependencies { + implementation "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" + implementation "org.glassfish.jersey.core:jersey-client:$jersey_version" + implementation "org.glassfish.jersey.media:jersey-media-multipart:$jersey_version" + implementation "org.glassfish.jersey.media:jersey-media-json-jackson:$jersey_version" + implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + {{#withXml}} + implementation "org.glassfish.jersey.media:jersey-media-jaxb:$jersey_version" + {{/withXml}} + implementation "org.glassfish.jersey.inject:jersey-hk2:$jersey_version" + testImplementation "junit:junit:$junit_version" + {{#wiremock}} + testImplementation "com.github.tomakehurst:wiremock:2.27.2" + {{/wiremock}} +} + +group = '{{groupId}}' +version = '{{artifactVersion}}' +description = '{{artifactDescription}}' + +java.sourceCompatibility = 1.8 +java.targetCompatibility = 1.8 + +tasks.register('testsJar', Jar) { + archiveClassifier = 'tests' + from(sourceSets.test.output) +} + +java { + withSourcesJar() + withJavadocJar() +} + +publishing { + publications { + maven(MavenPublication) { + from(components.java) + artifact(testsJar) + } + } +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} diff --git a/src/main/resources/handlebars/Java/libraries/jersey3/build.sbt.mustache b/src/main/resources/handlebars/Java/libraries/jersey3/build.sbt.mustache new file mode 100644 index 0000000000..5c9a87d31a --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/jersey3/build.sbt.mustache @@ -0,0 +1,44 @@ +lazy val root = (project in file(".")). + settings( + organization := "{{groupId}}", + name := "{{artifactId}}", + version := "{{artifactVersion}}", + scalaVersion := "2.11.4", + scalacOptions ++= Seq("-feature"), + javacOptions in compile ++= Seq("-Xlint:deprecation"), + publishArtifact in (Compile, packageDoc) := false, + resolvers += Resolver.mavenLocal, + libraryDependencies ++= Seq( + {{#useOas2}} + "io.swagger" % "swagger-annotations" % "1.5.15", + {{/useOas2}} + {{^useOas2}} + "io.swagger.core.v3" % "swagger-annotations" % "2.0.0", + {{/useOas2}} + "org.glassfish.jersey.core" % "jersey-client" % "2.29.1", + "org.glassfish.jersey.media" % "jersey-media-multipart" % "2.29.1", + "org.glassfish.jersey.media" % "jersey-media-json-jackson" % "2.29.1", + "org.glassfish.jersey.inject" % "jersey-hk2" % "2.29.1", + "com.fasterxml.jackson.core" % "jackson-core" % "{{^threetenbp}}2.10.1{{/threetenbp}}{{#threetenbp}}2.6.4{{/threetenbp}}" % "compile", + "com.fasterxml.jackson.core" % "jackson-annotations" % "{{^threetenbp}}2.10.1{{/threetenbp}}{{#threetenbp}}2.6.4{{/threetenbp}}" % "compile", + "com.fasterxml.jackson.core" % "jackson-databind" % "{{^threetenbp}}2.10.1{{/threetenbp}}{{#threetenbp}}2.6.4{{/threetenbp}}" % "compile", + {{#joda}} + "com.fasterxml.jackson.datatype" % "jackson-datatype-joda" % "2.10.1" % "compile", + {{/joda}} + {{#java8}} + "com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % "2.10.1" % "compile", + {{/java8}} + {{#threetenbp}} + "com.github.joschi.jackson" % "jackson-datatype-threetenbp" % "2.6.4" % "compile", + {{/threetenbp}} + {{^java8}} + "com.brsanthu" % "migbase64" % "2.2", + {{/java8}} + {{#supportJava6}} + "org.apache.commons" % "commons-lang3" % "3.6", + "commons-io" % "commons-io" % "2.5", + {{/supportJava6}} + "junit" % "junit" % "4.12" % "test", + "com.novocode" % "junit-interface" % "0.10" % "test" + ) + ) diff --git a/src/main/resources/handlebars/Java/libraries/jersey3/pom.mustache b/src/main/resources/handlebars/Java/libraries/jersey3/pom.mustache new file mode 100644 index 0000000000..9b8e24f875 --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/jersey3/pom.mustache @@ -0,0 +1,269 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{artifactVersion}} + {{artifactUrl}} + {{artifactDescription}} + + {{scmConnection}} + {{scmDeveloperConnection}} + {{scmUrl}} + + + 2.2.0 + + + + + {{licenseName}} + {{licenseUrl}} + repo + + + + + + {{developerName}} + {{developerEmail}} + {{developerOrganization}} + {{developerOrganizationUrl}} + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.6 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + 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-compiler-plugin + 3.6.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + + + + + sign-artifacts + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + + + + io.swagger.core.v3 + swagger-annotations + ${swagger-core-version} + + + + + org.glassfish.jersey.core + jersey-client + ${jersey-version} + + + org.glassfish.jersey.media + jersey-media-multipart + ${jersey-version} + + + org.glassfish.jersey.media + jersey-media-json-jackson + ${jersey-version} + + + org.glassfish.jersey.inject + jersey-hk2 + 2.29.1 + + + + + com.fasterxml.jackson.core + jackson-core + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-version} + + {{#withXml}} + + + org.glassfish.jersey.media + jersey-media-jaxb + ${jersey-version} + + {{/withXml}} + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson-version} + + {{#useBeanValidation}} + + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + {{/useBeanValidation}} + + + junit + junit + ${junit-version} + test + + {{#wiremock}} + + com.github.tomakehurst + wiremock + 2.27.2 + test + + {{/wiremock}} + + + 2.2.8 + 3.0.10 + 2.15.2 + 1.0.0 + 4.13.2 + + diff --git a/src/main/resources/handlebars/Java/libraries/okhttp-gson/JSON.mustache b/src/main/resources/handlebars/Java/libraries/okhttp-gson/JSON.mustache index 7ca5a7859a..02b2fa04ed 100644 --- a/src/main/resources/handlebars/Java/libraries/okhttp-gson/JSON.mustache +++ b/src/main/resources/handlebars/Java/libraries/okhttp-gson/JSON.mustache @@ -61,6 +61,7 @@ public class JSON { public static GsonBuilder createGson() { GsonFireBuilder fireBuilder = new GsonFireBuilder() {{#parent}} + {{#discriminator}} .registerTypeSelector({{classname}}.class, new TypeSelector<{{classname}}>() { @Override public Class getClassForElement(JsonElement readElement) { @@ -108,6 +109,7 @@ public class JSON { } } }) + {{/discriminator}} {{/parent}} ; return fireBuilder.createGsonBuilder(); diff --git a/src/main/resources/handlebars/Java/libraries/okhttp-gson/api.mustache b/src/main/resources/handlebars/Java/libraries/okhttp-gson/api.mustache index eb25fa7d62..b1033181f5 100644 --- a/src/main/resources/handlebars/Java/libraries/okhttp-gson/api.mustache +++ b/src/main/resources/handlebars/Java/libraries/okhttp-gson/api.mustache @@ -19,13 +19,26 @@ import com.google.gson.reflect.TypeToken; import java.io.IOException; {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{#performBeanValidation}} +{{#jakarta}} +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.ValidatorFactory; +import jakarta.validation.executable.ExecutableValidator; +{{/jakarta}} +{{^jakarta}} import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.ValidatorFactory; import javax.validation.executable.ExecutableValidator; +{{/jakarta}} import java.util.Set; import java.lang.reflect.Method; import java.lang.reflect.Type; @@ -248,4 +261,4 @@ public class {{classname}} { {{/contents}} {{/operation}} } -{{/operations}} \ No newline at end of file +{{/operations}} diff --git a/src/main/resources/handlebars/Java/libraries/okhttp-gson/build.gradle.java11.mustache b/src/main/resources/handlebars/Java/libraries/okhttp-gson/build.gradle.java11.mustache new file mode 100644 index 0000000000..8208643f6a --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/okhttp-gson/build.gradle.java11.mustache @@ -0,0 +1,65 @@ +plugins { + id 'java' + id 'maven-publish' +} + +repositories { + mavenLocal() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +dependencies { + {{#useOas2}} + implementation 'io.swagger:swagger-annotations:1.5.24' + {{/useOas2}} + {{^useOas2}} + implementation "io.swagger.core.v3:swagger-annotations:2.0.0" + {{/useOas2}} + implementation 'com.squareup.okhttp:okhttp:2.7.5' + implementation 'com.squareup.okhttp:logging-interceptor:2.7.5' + implementation 'com.google.code.gson:gson:2.8.1' + implementation 'io.gsonfire:gson-fire:1.8.0' + {{#joda}} + implementation 'joda-time:joda-time:2.9.9' + {{/joda}} + {{#threetenbp}} + implementation 'org.threeten:threetenbp:1.3.5' + {{/threetenbp}} + implementation 'com.sun.xml.ws:jaxws-rt:{{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}2.3.3{{/jakarta}}' + testImplementation 'junit:junit:4.13.1' + {{#wiremock}} + testImplementation "com.github.tomakehurst:wiremock:2.27.2" + {{/wiremock}} +} + +group = '{{groupId}}' +version = '{{artifactVersion}}' +description = '{{artifactDescription}}' + +java.sourceCompatibility = 11 +java.targetCompatibility = 11 + +tasks.register('testsJar', Jar) { + archiveClassifier = 'tests' + from(sourceSets.test.output) +} + +java { + withSourcesJar() + withJavadocJar() +} + +publishing { + publications { + maven(MavenPublication) { + from(components.java) + artifact(testsJar) + } + } +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} diff --git a/src/main/resources/handlebars/Java/libraries/okhttp-gson/build.gradle.mustache b/src/main/resources/handlebars/Java/libraries/okhttp-gson/build.gradle.mustache index 2bb4b26834..589b4e4efd 100644 --- a/src/main/resources/handlebars/Java/libraries/okhttp-gson/build.gradle.mustache +++ b/src/main/resources/handlebars/Java/libraries/okhttp-gson/build.gradle.mustache @@ -6,7 +6,7 @@ version = '{{artifactVersion}}' buildscript { repositories { - jcenter() + mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:2.3.+' @@ -15,7 +15,7 @@ buildscript { } repositories { - jcenter() + mavenCentral() } @@ -54,7 +54,12 @@ if(hasProperty('target') && target == 'android') { } dependencies { + {{#jakarta}} + provided 'jakarta.annotation:jakarta.annotation-api:2.1.1' + {{/jakarta}} + {{^jakarta}} provided 'javax.annotation:jsr250-api:1.0' + {{/jakarta}} } } @@ -82,14 +87,17 @@ if(hasProperty('target') && target == 'android') { } else { apply plugin: 'java' - apply plugin: 'maven' + apply plugin: 'maven-publish' sourceCompatibility = JavaVersion.VERSION_{{^java8}}1_7{{/java8}}{{#java8}}1_8{{/java8}} targetCompatibility = JavaVersion.VERSION_{{^java8}}1_7{{/java8}}{{#java8}}1_8{{/java8}} - install { - repositories.mavenInstaller { - pom.artifactId = '{{artifactId}}' + publishing { + publications { + maven(MavenPublication) { + artifactId = '{{artifactId}}' + from components.java + } } } @@ -101,20 +109,20 @@ if(hasProperty('target') && target == 'android') { dependencies { {{#useOas2}} - compile 'io.swagger:swagger-annotations:1.5.15' + implementation 'io.swagger:swagger-annotations:1.5.15' {{/useOas2}} {{^useOas2}} - compile 'io.swagger.core.v3:swagger-annotations:2.0.0' + implementation 'io.swagger.core.v3:swagger-annotations:2.0.0' {{/useOas2}} - compile 'com.squareup.okhttp:okhttp:2.7.5' - compile 'com.squareup.okhttp:logging-interceptor:2.7.5' - compile 'com.google.code.gson:gson:2.8.1' - compile 'io.gsonfire:gson-fire:1.8.3' + implementation 'com.squareup.okhttp:okhttp:2.7.5' + implementation 'com.squareup.okhttp:logging-interceptor:2.7.5' + implementation 'com.google.code.gson:gson:2.8.1' + implementation 'io.gsonfire:gson-fire:1.8.3' {{#joda}} - compile 'joda-time:joda-time:2.9.9' + implementation 'joda-time:joda-time:2.9.9' {{/joda}} {{#threetenbp}} - compile 'org.threeten:threetenbp:1.3.5' + implementation 'org.threeten:threetenbp:1.3.5' {{/threetenbp}} - testCompile 'junit:junit:4.12' + testImplementation 'junit:junit:4.12' } diff --git a/src/main/resources/handlebars/Java/libraries/okhttp-gson/pom.mustache b/src/main/resources/handlebars/Java/libraries/okhttp-gson/pom.mustache index d9a8887cdf..40141310da 100644 --- a/src/main/resources/handlebars/Java/libraries/okhttp-gson/pom.mustache +++ b/src/main/resources/handlebars/Java/libraries/okhttp-gson/pom.mustache @@ -118,7 +118,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.4 + 3.2.0 attach-javadocs @@ -166,6 +166,22 @@ + {{#java11}} + + jdk11 + + [11,) + + + + com.sun.xml.ws + jaxws-rt + {{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}2.3.3{{/jakarta}} + pom + + + + {{/java11}} @@ -238,25 +254,44 @@ {{/supportJava6}} {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + {{/jakarta}} + {{^jakarta}} - javax.validation - validation-api - 1.1.0.Final - provided + javax.validation + validation-api + 1.1.0.Final + provided + {{/jakarta}} {{/useBeanValidation}} {{#performBeanValidation}} org.hibernate hibernate-validator - 5.4.1.Final + {{#jakarta}}8.0.0.Final{{/jakarta}}{{^jakarta}}5.4.1.Final{{/jakarta}} + {{#jakarta}} + + jakarta.el + jakarta.el-api + 5.0.1 + + {{/jakarta}} + {{^jakarta}} javax.el el-api 2.2 + {{/jakarta}} {{/performBeanValidation}} {{#parcelableModel}} @@ -274,9 +309,17 @@ ${junit-version} test + {{#wiremock}} + + com.github.tomakehurst + wiremock + 2.27.2 + test + + {{/wiremock}} - {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} ${java.version} ${java.version} {{#useOas2}} diff --git a/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ApiCallback.mustache b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ApiCallback.mustache new file mode 100644 index 0000000000..4cc99a76ec --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ApiCallback.mustache @@ -0,0 +1,51 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +import java.io.IOException; + +import java.util.Map; +import java.util.List; + +/** + * Callback for asynchronous API call. + * + * @param The return type + */ +public interface ApiCallback { + /** + * This is called when the API call fails. + * + * @param e The exception causing the failure + * @param statusCode Status code of the response if available, otherwise it would be 0 + * @param responseHeaders Headers of the response if available, otherwise it would be null + */ + void onFailure(ApiException e, int statusCode, Map> responseHeaders); + + /** + * This is called when the API call succeeded. + * + * @param result The result deserialized from response + * @param statusCode Status code of the response + * @param responseHeaders Headers of the response + */ + void onSuccess(T result, int statusCode, Map> responseHeaders); + + /** + * This is called when the API upload processing. + * + * @param bytesWritten bytes Written + * @param contentLength content length of request body + * @param done write end + */ + void onUploadProgress(long bytesWritten, long contentLength, boolean done); + + /** + * This is called when the API downlond processing. + * + * @param bytesRead bytes Read + * @param contentLength content lenngth of the response + * @param done Read end + */ + void onDownloadProgress(long bytesRead, long contentLength, boolean done); +} diff --git a/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ApiClient.mustache b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ApiClient.mustache new file mode 100644 index 0000000000..7b42211558 --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ApiClient.mustache @@ -0,0 +1,1029 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +import okhttp3.*; +import okhttp3.internal.http.HttpMethod; +import okhttp3.logging.HttpLoggingInterceptor; +import okhttp3.logging.HttpLoggingInterceptor.Level; +import okio.BufferedSink; +import okio.Okio; +{{#joda}} +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.joda.time.format.DateTimeFormatter; +{{/joda}} +{{#threetenbp}} +import org.threeten.bp.LocalDate; +import org.threeten.bp.OffsetDateTime; +import org.threeten.bp.format.DateTimeFormatter; +{{/threetenbp}} + +import javax.net.ssl.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.lang.reflect.Type; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.SecureRandom; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.text.DateFormat; +{{#java8}} +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +{{/java8}} +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import {{invokerPackage}}.auth.Authentication; +import {{invokerPackage}}.auth.HttpBasicAuth; +import {{invokerPackage}}.auth.ApiKeyAuth; +import {{invokerPackage}}.auth.OAuth; + +public class ApiClient { + + private String basePath = "{{{basePath}}}"; + private boolean debugging = false; + private Map defaultHeaderMap = new HashMap(); + private String tempFolderPath = null; + + private Map authentications; + + private DateFormat dateFormat; + private DateFormat datetimeFormat; + private boolean lenientDatetimeFormat; + private int dateLength; + + private OkHttpClient httpClient; + private JSON json; + + private HttpLoggingInterceptor loggingInterceptor; + + /* + * Constructor for ApiClient + */ + public ApiClient() { + httpClient = new OkHttpClient(); + + {{#useGzipFeature}} + // Enable gzip request compression + httpClient.interceptors().add(new GzipRequestInterceptor()); + {{/useGzipFeature}} + + json = new JSON(); + + // Set default User-Agent. + setUserAgent("{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}Swagger-Codegen/{{{artifactVersion}}}/java{{/httpUserAgent}}"); + + // Setup authentications (key: authentication name, value: authentication). + authentications = new HashMap();{{#authMethods}}{{#isBasic}} + authentications.put("{{name}}", new HttpBasicAuth());{{/isBasic}}{{#isApiKey}} + authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}} + authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{#isBearer}} + authentications.put("{{name}}", new OAuth());{{/isBearer}}{{/authMethods}} + // Prevent the authentications from being modified. + authentications = Collections.unmodifiableMap(authentications); + } + + /** + * Get base path + * + * @return Baes path + */ + public String getBasePath() { + return basePath; + } + + /** + * Set base path + * + * @param basePath Base path of the URL (e.g {{{basePath}}} + * @return An instance of OkHttpClient + */ + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + /** + * Get HTTP client + * Use to update with modification for e.g. setHttpClient(getHttpClient.newBuilder().readTimeout(5, TimeUnit.SECONDS).build()) + * @return An instance of OkHttpClient + */ + public OkHttpClient getHttpClient() { + return httpClient; + } + + /** + * Set HTTP client + * Update with a modified instance using for e.g. setHttpClient(getHttpClient.newBuilder().readTimeout(5, TimeUnit.SECONDS).build()) + * @param httpClient An instance of OkHttpClient + * @return Api Client + */ + public ApiClient setHttpClient(OkHttpClient httpClient) { + this.httpClient = httpClient; + return this; + } + + /** + * Get JSON + * + * @return JSON object + */ + public JSON getJSON() { + return json; + } + + /** + * Set JSON + * + * @param json JSON object + * @return Api client + */ + public ApiClient setJSON(JSON json) { + this.json = json; + return this; + } + + public DateFormat getDateFormat() { + return dateFormat; + } + + public ApiClient setDateFormat(DateFormat dateFormat) { + this.json.setDateFormat(dateFormat); + return this; + } + + public ApiClient setSqlDateFormat(DateFormat dateFormat) { + this.json.setSqlDateFormat(dateFormat); + return this; + } + + {{#joda}} + public ApiClient setDateTimeFormat(DateTimeFormatter dateFormat) { + this.json.setDateTimeFormat(dateFormat); + return this; + } + + public ApiClient setLocalDateFormat(DateTimeFormatter dateFormat) { + this.json.setLocalDateFormat(dateFormat); + return this; + } + + {{/joda}} + {{#jsr310}} + public ApiClient setOffsetDateTimeFormat(DateTimeFormatter dateFormat) { + this.json.setOffsetDateTimeFormat(dateFormat); + return this; + } + + public ApiClient setLocalDateFormat(DateTimeFormatter dateFormat) { + this.json.setLocalDateFormat(dateFormat); + return this; + } + + {{/jsr310}} + public ApiClient setLenientOnJson(boolean lenientOnJson) { + this.json.setLenientOnJson(lenientOnJson); + return this; + } + + /** + * Get authentications (key: authentication name, value: authentication). + * + * @return Map of authentication objects + */ + public Map getAuthentications() { + return authentications; + } + + /** + * Get authentication for the given name. + * + * @param authName The authentication name + * @return The authentication, null if not found + */ + public Authentication getAuthentication(String authName) { + return authentications.get(authName); + } + + /** + * Helper method to set username for the first HTTP basic authentication. + * + * @param username Username + */ + public void setUsername(String username) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setUsername(username); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set password for the first HTTP basic authentication. + * + * @param password Password + */ + public void setPassword(String password) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setPassword(password); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set API key value for the first API key authentication. + * + * @param apiKey API key + */ + public void setApiKey(String apiKey) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKey(apiKey); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set API key prefix for the first API key authentication. + * + * @param apiKeyPrefix API key prefix + */ + public void setApiKeyPrefix(String apiKeyPrefix) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set access token for the first OAuth2 authentication. + * + * @param accessToken Access token + */ + public void setAccessToken(String accessToken) { + for (Authentication auth : authentications.values()) { + if (auth instanceof OAuth) { + ((OAuth) auth).setAccessToken(accessToken); + return; + } + } + throw new RuntimeException("No OAuth2 authentication configured!"); + } + + /** + * Set the User-Agent header's value (by adding to the default header map). + * + * @param userAgent HTTP request's user agent + * @return ApiClient + */ + public ApiClient setUserAgent(String userAgent) { + addDefaultHeader("User-Agent", userAgent); + return this; + } + + /** + * Add a default header. + * + * @param key The header's key + * @param value The header's value + * @return ApiClient + */ + public ApiClient addDefaultHeader(String key, String value) { + defaultHeaderMap.put(key, value); + return this; + } + + /** + * Check that whether debugging is enabled for this API client. + * + * @return True if debugging is enabled, false otherwise. + */ + public boolean isDebugging() { + return debugging; + } + + /** + * Enable/disable debugging for this API client. + * + * @param debugging To enable (true) or disable (false) debugging + * @return ApiClient + */ + public ApiClient setDebugging(boolean debugging) { + if (debugging != this.debugging) { + if (debugging) { + loggingInterceptor = new HttpLoggingInterceptor(); + loggingInterceptor.setLevel(Level.BODY); + httpClient.interceptors().add(loggingInterceptor); + } else { + httpClient.interceptors().remove(loggingInterceptor); + loggingInterceptor = null; + } + } + this.debugging = debugging; + return this; + } + + /** + * The path of temporary folder used to store downloaded files from endpoints + * with file response. The default value is null, i.e. using + * the system's default tempopary folder. + * + * @see createTempFile + * @return Temporary folder path + */ + public String getTempFolderPath() { + return tempFolderPath; + } + + /** + * Set the temporary folder path (for downloading files) + * + * @param tempFolderPath Temporary folder path + * @return ApiClient + */ + public ApiClient setTempFolderPath(String tempFolderPath) { + this.tempFolderPath = tempFolderPath; + return this; + } + + /** + * Format the given parameter object into string. + * + * @param param Parameter + * @return String representation of the parameter + */ + public String parameterToString(Object param) { + if (param == null) { + return ""; + } else if (param instanceof Date {{#joda}}|| param instanceof DateTime || param instanceof LocalDate{{/joda}}{{#jsr310}}|| param instanceof OffsetDateTime || param instanceof LocalDate{{/jsr310}}) { + //Serialize to json string and remove the " enclosing characters + String jsonStr = json.serialize(param); + return jsonStr.substring(1, jsonStr.length() - 1); + } else if (param instanceof Collection) { + StringBuilder b = new StringBuilder(); + for (Object o : (Collection)param) { + if (b.length() > 0) { + b.append(","); + } + b.append(String.valueOf(o)); + } + return b.toString(); + } else { + return String.valueOf(param); + } + } + + /** + * Formats the specified query parameter to a list containing a single {@code Pair} object. + * + * Note that {@code value} must not be a collection. + * + * @param name The name of the parameter. + * @param value The value of the parameter. + * @return A list containing a single {@code Pair} object. + */ + public List parameterToPair(String name, Object value) { + List params = new ArrayList<>(); + + // preconditions + if (name == null || name.isEmpty() || value == null || value instanceof Collection) return params; + + params.add(new Pair(name, parameterToString(value))); + return params; + } + + /** + * Formats the specified collection query parameters to a list of {@code Pair} objects. + * + * Note that the values of each of the returned Pair objects are percent-encoded. + * + * @param collectionFormat The collection format of the parameter. + * @param name The name of the parameter. + * @param value The value of the parameter. + * @return A list of {@code Pair} objects. + */ + public List parameterToPairs(String collectionFormat, String name, Collection value) { + List params = new ArrayList<>(); + + // preconditions + if (name == null || name.isEmpty() || value == null || value.isEmpty()) { + return params; + } + + // create the params based on the collection format + if ("multi".equals(collectionFormat)) { + for (Object item : value) { + params.add(new Pair(name, escapeString(parameterToString(item)))); + } + return params; + } + + // collectionFormat is assumed to be "csv" by default + String delimiter = ","; + + // escape all delimiters except commas, which are URI reserved + // characters + if ("ssv".equals(collectionFormat)) { + delimiter = escapeString(" "); + } else if ("tsv".equals(collectionFormat)) { + delimiter = escapeString("\t"); + } else if ("pipes".equals(collectionFormat)) { + delimiter = escapeString("|"); + } + + StringBuilder sb = new StringBuilder() ; + for (Object item : value) { + sb.append(delimiter); + sb.append(escapeString(parameterToString(item))); + } + + params.add(new Pair(name, sb.substring(delimiter.length()))); + + return params; + } + + /** + * Sanitize filename by removing path. + * e.g. ../../sun.gif becomes sun.gif + * + * @param filename The filename to be sanitized + * @return The sanitized filename + */ + public String sanitizeFilename(String filename) { + return filename.replaceAll(".*[/\\\\]", ""); + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * "* / *" is also default to JSON + * @param mime MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public boolean isJsonMime(String mime) { + String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$"; + return mime != null && (mime.matches(jsonMime) || mime.equals("*/*")); + } + + /** + * Select the Accept header's value from the given accepts array: + * if JSON exists in the given array, use it; + * otherwise use all of them (joining into a string) + * + * @param accepts The accepts array to select from + * @return The Accept header to use. If the given array is empty, + * null will be returned (not to set the Accept header explicitly). + */ + public String selectHeaderAccept(String[] accepts) { + if (accepts.length == 0) { + return null; + } + for (String accept : accepts) { + if (isJsonMime(accept)) { + return accept; + } + } + return StringUtil.join(accepts, ","); + } + + /** + * Select the Content-Type header's value from the given array: + * if JSON exists in the given array, use it; + * otherwise use the first one of the array. + * + * @param contentTypes The Content-Type array to select from + * @return The Content-Type header to use. If the given array is empty, + * or matches "any", JSON will be used. + */ + public String selectHeaderContentType(String[] contentTypes) { + if (contentTypes.length == 0 || contentTypes[0].equals("*/*")) { + return "application/json"; + } + for (String contentType : contentTypes) { + if (isJsonMime(contentType)) { + return contentType; + } + } + return contentTypes[0]; + } + + /** + * Escape the given string to be used as URL query value. + * + * @param str String to be escaped + * @return Escaped string + */ + public String escapeString(String str) { + try { + return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20"); + } catch (UnsupportedEncodingException e) { + return str; + } + } + + /** + * Deserialize response body to Java object, according to the return type and + * the Content-Type response header. + * + * @param Type + * @param response HTTP response + * @param returnType The type of the Java object + * @return The deserialized Java object + * @throws ApiException If fail to deserialize response body, i.e. cannot read response body + * or the Content-Type of the response is not supported. + */ + @SuppressWarnings("unchecked") + private T deserialize(Response response, Type returnType) throws ApiException { + if (response == null || returnType == null) { + return null; + } + + if ("byte[]".equals(returnType.toString())) { + // Handle binary response (byte array). + try { + return (T) response.body().bytes(); + } catch (IOException e) { + throw new ApiException(e); + } + } else if (returnType.equals(File.class)) { + // Handle file downloading. + return (T) downloadFileFromResponse(response); + } + + String respBody; + try { + if (response.body() != null) + respBody = response.body().string(); + else + respBody = null; + } catch (IOException e) { + throw new ApiException(e); + } + + if (respBody == null || "".equals(respBody)) { + return null; + } + + String contentType = response.headers().get("Content-Type"); + if (contentType == null) { + // ensuring a default content type + contentType = "application/json"; + } + if (isJsonMime(contentType)) { + return json.deserialize(respBody, returnType); + } else if (returnType.equals(String.class)) { + // Expecting string, return the raw response body. + return (T) respBody; + } else { + throw new ApiException( + "Content type \"" + contentType + "\" is not supported for type: " + returnType, + response.code(), + response.headers().toMultimap(), + respBody); + } + } + + /** + * Serialize the given Java object into request body according to the object's + * class and the request Content-Type. + * + * @param obj The Java object + * @param contentType The request Content-Type + * @return The serialized request body + * @throws ApiException If fail to serialize the given object + */ + private RequestBody serialize(Object obj, String contentType) throws ApiException { + if (obj instanceof byte[]) { + // Binary (byte array) body parameter support. + return RequestBody.create((byte[]) obj, MediaType.parse(contentType)); + } else if (obj instanceof File) { + // File body parameter support. + return RequestBody.create((File) obj, MediaType.parse(contentType)); + } else if (isJsonMime(contentType)) { + String content; + if (obj != null) { + content = json.serialize(obj); + } else { + content = null; + } + return RequestBody.create(content, MediaType.parse(contentType)); + } else { + throw new ApiException("Content type \"" + contentType + "\" is not supported"); + } + } + + /** + * Download file from the given response. + * + * @param response An instance of the Response object + * @throws ApiException If fail to read file content from response and write to disk + * @return Downloaded file + */ + public File downloadFileFromResponse(Response response) throws ApiException { + try { + File file = prepareDownloadFile(response); + BufferedSink sink = Okio.buffer(Okio.sink(file)); + sink.writeAll(response.body().source()); + sink.close(); + return file; + } catch (IOException e) { + throw new ApiException(e); + } + } + + /** + * Prepare file for download + * + * @param response An instance of the Response object + * @throws IOException If fail to prepare file for download + * @return Prepared file for the download + */ + public File prepareDownloadFile(Response response) throws IOException { + String filename = null; + String contentDisposition = response.header("Content-Disposition"); + if (contentDisposition != null && !"".equals(contentDisposition)) { + // Get filename from the Content-Disposition header. + Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?"); + Matcher matcher = pattern.matcher(contentDisposition); + if (matcher.find()) { + filename = sanitizeFilename(matcher.group(1)); + } + } + + String prefix = null; + String suffix = null; + if (filename == null) { + prefix = "download-"; + suffix = ""; + } else { + int pos = filename.lastIndexOf("."); + if (pos == -1) { + prefix = filename + "-"; + } else { + prefix = filename.substring(0, pos) + "-"; + suffix = filename.substring(pos); + } + // File.createTempFile requires the prefix to be at least three characters long + if (prefix.length() < 3) + prefix = "download-"; + } + + if (tempFolderPath == null) + return Files.createTempFile(prefix, suffix).toFile(); + else + return Files.createTempFile(Paths.get(tempFolderPath), prefix, suffix).toFile(); + } + + /** + * {@link #execute(Call, Type)} + * + * @param Type + * @param call An instance of the Call object + * @throws ApiException If fail to execute the call + * @return ApiResponse<T> + */ + public ApiResponse execute(Call call) throws ApiException { + return execute(call, null); + } + + /** + * Execute HTTP call and deserialize the HTTP response body into the given return type. + * + * @param returnType The return type used to deserialize HTTP response body + * @param The return type corresponding to (same with) returnType + * @param call Call + * @return ApiResponse object containing response status, headers and + * data, which is a Java object deserialized from response body and would be null + * when returnType is null. + * @throws ApiException If fail to execute the call + */ + public ApiResponse execute(Call call, Type returnType) throws ApiException { + try { + Response response = call.execute(); + T data = handleResponse(response, returnType); + return new ApiResponse(response.code(), response.headers().toMultimap(), data); + } catch (IOException e) { + throw new ApiException(e); + } + } + + /** + * {@link #executeAsync(Call, Type, ApiCallback)} + * + * @param Type + * @param call An instance of the Call object + * @param callback ApiCallback<T> + */ + public void executeAsync(Call call, ApiCallback callback) { + executeAsync(call, null, callback); + } + + /** + * Execute HTTP call asynchronously. + * + * @see #execute(Call, Type) + * @param Type + * @param call The callback to be executed when the API call finishes + * @param returnType Return type + * @param callback ApiCallback + */ + @SuppressWarnings("unchecked") + public void executeAsync(Call call, final Type returnType, final ApiCallback callback) { + call.enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + callback.onFailure(new ApiException(e), 0, null); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + T result; + try { + result = (T) handleResponse(response, returnType); + } catch (ApiException e) { + callback.onFailure(e, response.code(), response.headers().toMultimap()); + return; + } + callback.onSuccess(result, response.code(), response.headers().toMultimap()); + } + }); + } + + /** + * Handle the given response, return the deserialized object when the response is successful. + * + * @param Type + * @param response Response + * @param returnType Return type + * @throws ApiException If the response has a unsuccessful status code or + * fail to deserialize the response body + * @return Type + */ + private T handleResponse(Response response, Type returnType) throws ApiException { + if (response.isSuccessful()) { + if (returnType == null || response.code() == 204) { + // returning null if the returnType is not defined, + // or the status code is 204 (No Content) + if (response.body() != null) { + response.body().close(); + } + return null; + } else { + return deserialize(response, returnType); + } + } else { + String respBody = null; + if (response.body() != null) { + try { + respBody = response.body().string(); + } catch (IOException e) { + throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap()); + } + } + throw new ApiException(response.message(), response.code(), response.headers().toMultimap(), respBody); + } + } + + /** + * Build HTTP call with the given options. + * + * @param path The sub-path of the HTTP URL + * @param method The request method, one of "GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH" and "DELETE" + * @param queryParams The query parameters + * @param collectionQueryParams The collection query parameters + * @param body The request body object + * @param headerParams The header parameters + * @param formParams The form parameters + * @param authNames The authentications to apply + * @param progressRequestListener Progress request listener + * @return The HTTP call + * @throws ApiException If fail to serialize the request body object + */ + public Call buildCall(String path, String method, List queryParams, List collectionQueryParams, Object body, Map headerParams, Map formParams, String[] authNames, ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException { + Request request = buildRequest(path, method, queryParams, collectionQueryParams, body, headerParams, formParams, authNames, progressRequestListener); + + return httpClient.newCall(request); + } + + /** + * Build an HTTP request with the given options. + * + * @param path The sub-path of the HTTP URL + * @param method The request method, one of "GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH" and "DELETE" + * @param queryParams The query parameters + * @param collectionQueryParams The collection query parameters + * @param body The request body object + * @param headerParams The header parameters + * @param formParams The form parameters + * @param authNames The authentications to apply + * @param progressRequestListener Progress request listener + * @return The HTTP request + * @throws ApiException If fail to serialize the request body object + */ + public Request buildRequest(String path, String method, List queryParams, List collectionQueryParams, Object body, Map headerParams, Map formParams, String[] authNames, ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException { + updateParamsForAuth(authNames, queryParams, headerParams); + + final String url = buildUrl(path, queryParams, collectionQueryParams); + final Request.Builder reqBuilder = new Request.Builder().url(url); + processHeaderParams(headerParams, reqBuilder); + + String contentType = (String) headerParams.get("Content-Type"); + // ensuring a default content type + if (contentType == null) { + contentType = "application/json"; + } + + RequestBody reqBody; + if (!HttpMethod.permitsRequestBody(method)) { + reqBody = null; + } else if ("application/x-www-form-urlencoded".equals(contentType)) { + reqBody = buildRequestBodyFormEncoding(formParams); + } else if ("multipart/form-data".equals(contentType)) { + reqBody = buildRequestBodyMultipart(formParams); + } else if (body == null) { + if ("DELETE".equals(method)) { + // allow calling DELETE without sending a request body + reqBody = null; + } else { + // use an empty request body (for POST, PUT and PATCH) + reqBody = RequestBody.create("", MediaType.parse(contentType)); + } + } else { + reqBody = serialize(body, contentType); + } + + Request request = null; + + if(progressRequestListener != null && reqBody != null) { + ProgressRequestBody progressRequestBody = new ProgressRequestBody(reqBody, progressRequestListener); + request = reqBuilder.method(method, progressRequestBody).build(); + } else { + request = reqBuilder.method(method, reqBody).build(); + } + + return request; + } + + /** + * Build full URL by concatenating base path, the given sub path and query parameters. + * + * @param path The sub path + * @param queryParams The query parameters + * @param collectionQueryParams The collection query parameters + * @return The full URL + */ + private String buildUrl(String path, List queryParams, List collectionQueryParams) { + final StringBuilder url = new StringBuilder(); + url.append(basePath).append(path); + + if (queryParams != null && !queryParams.isEmpty()) { + // support (constant) query string in `path`, e.g. "/posts?draft=1" + String prefix = path.contains("?") ? "&" : "?"; + for (Pair param : queryParams) { + if (param.getValue() != null) { + if (prefix != null) { + url.append(prefix); + prefix = null; + } else { + url.append("&"); + } + String value = parameterToString(param.getValue()); + url.append(escapeString(param.getName())).append("=").append(escapeString(value)); + } + } + } + + if (collectionQueryParams != null && !collectionQueryParams.isEmpty()) { + String prefix = url.toString().contains("?") ? "&" : "?"; + for (Pair param : collectionQueryParams) { + if (param.getValue() != null) { + if (prefix != null) { + url.append(prefix); + prefix = null; + } else { + url.append("&"); + } + String value = parameterToString(param.getValue()); + // collection query parameter value already escaped as part of parameterToPairs + url.append(escapeString(param.getName())).append("=").append(value); + } + } + } + + return url.toString(); + } + + /** + * Set header parameters to the request builder, including default headers. + * + * @param headerParams Header parameters in the ofrm of Map + * @param reqBuilder Reqeust.Builder + */ + private void processHeaderParams(Map headerParams, Request.Builder reqBuilder) { + for (Entry param : headerParams.entrySet()) { + reqBuilder.header(param.getKey(), parameterToString(param.getValue())); + } + for (Entry header : defaultHeaderMap.entrySet()) { + if (!headerParams.containsKey(header.getKey())) { + reqBuilder.header(header.getKey(), parameterToString(header.getValue())); + } + } + } + + /** + * Update query and header parameters based on authentication settings. + * + * @param authNames The authentications to apply + * @param queryParams List of query parameters + * @param headerParams Map of header parameters + */ + private void updateParamsForAuth(String[] authNames, List queryParams, Map headerParams) { + for (String authName : authNames) { + Authentication auth = authentications.get(authName); + if (auth == null) throw new RuntimeException("Authentication undefined: " + authName); + auth.applyToParams(queryParams, headerParams); + } + } + + /** + * Build a form-encoding request body with the given form parameters. + * + * @param formParams Form parameters in the form of Map + * @return RequestBody + */ + private RequestBody buildRequestBodyFormEncoding(Map formParams) { + FormBody.Builder formBuilder = new FormBody.Builder(); + for (Entry param : formParams.entrySet()) { + formBuilder.add(param.getKey(), parameterToString(param.getValue())); + } + return formBuilder.build(); + } + + /** + * Build a multipart (file uploading) request body with the given form parameters, + * which could contain text fields and file fields. + * + * @param formParams Form parameters in the form of Map + * @return RequestBody + */ + private RequestBody buildRequestBodyMultipart(Map formParams) { + MultipartBody.Builder mpBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM); + for (Entry param : formParams.entrySet()) { + if (param.getValue() instanceof File) { + File file = (File) param.getValue(); + Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + param.getKey() + "\"; filename=\"" + file.getName() + "\""); + MediaType mediaType = MediaType.parse(guessContentTypeFromFile(file)); + mpBuilder.addPart(partHeaders, RequestBody.create(mediaType, file)); + } else { + Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + param.getKey() + "\""); + mpBuilder.addPart(partHeaders, RequestBody.create(parameterToString(param.getValue()), null)); + } + } + return mpBuilder.build(); + } + + /** + * Guess Content-Type header from the given file (defaults to "application/octet-stream"). + * + * @param file The given file + * @return The guessed Content-Type + */ + private String guessContentTypeFromFile(File file) { + String contentType = URLConnection.guessContentTypeFromName(file.getName()); + if (contentType == null) { + return "application/octet-stream"; + } else { + return contentType; + } + } + +} diff --git a/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ApiResponse.mustache b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ApiResponse.mustache new file mode 100644 index 0000000000..3909393697 --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ApiResponse.mustache @@ -0,0 +1,48 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +import java.util.List; +import java.util.Map; + +/** + * API response returned by API call. + * + * @param The type of data that is deserialized from response body + */ +public class ApiResponse { + final private int statusCode; + final private Map> headers; + final private T data; + + /** + * @param statusCode The status code of HTTP response + * @param headers The headers of HTTP response + */ + public ApiResponse(int statusCode, Map> headers) { + this(statusCode, headers, null); + } + + /** + * @param statusCode The status code of HTTP response + * @param headers The headers of HTTP response + * @param data The object deserialized from response bod + */ + public ApiResponse(int statusCode, Map> headers, T data) { + this.statusCode = statusCode; + this.headers = headers; + this.data = data; + } + + public int getStatusCode() { + return statusCode; + } + + public Map> getHeaders() { + return headers; + } + + public T getData() { + return data; + } +} diff --git a/src/main/resources/handlebars/Java/libraries/okhttp4-gson/GzipRequestInterceptor.mustache b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/GzipRequestInterceptor.mustache new file mode 100644 index 0000000000..27c536c21a --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/GzipRequestInterceptor.mustache @@ -0,0 +1,70 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +import okhttp3.*; +import okio.Buffer; +import okio.BufferedSink; +import okio.GzipSink; +import okio.Okio; + +import java.io.IOException; + +/** + * Encodes request bodies using gzip. + * + * Taken from https://github.com/square/okhttp/issues/350 + */ +class GzipRequestInterceptor implements Interceptor { + @Override public Response intercept(Chain chain) throws IOException { + Request originalRequest = chain.request(); + if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) { + return chain.proceed(originalRequest); + } + + Request compressedRequest = originalRequest.newBuilder() + .header("Content-Encoding", "gzip") + .method(originalRequest.method(), forceContentLength(gzip(originalRequest.body()))) + .build(); + return chain.proceed(compressedRequest); + } + + private RequestBody forceContentLength(final RequestBody requestBody) throws IOException { + final Buffer buffer = new Buffer(); + requestBody.writeTo(buffer); + return new RequestBody() { + @Override + public MediaType contentType() { + return requestBody.contentType(); + } + + @Override + public long contentLength() { + return buffer.size(); + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + sink.write(buffer.snapshot()); + } + }; + } + + private RequestBody gzip(final RequestBody body) { + return new RequestBody() { + @Override public MediaType contentType() { + return body.contentType(); + } + + @Override public long contentLength() { + return -1; // We don't know the compressed length in advance! + } + + @Override public void writeTo(BufferedSink sink) throws IOException { + BufferedSink gzipSink = Okio.buffer(new GzipSink(sink)); + body.writeTo(gzipSink); + gzipSink.close(); + } + }; + } +} \ No newline at end of file diff --git a/src/main/resources/handlebars/Java/libraries/okhttp4-gson/JSON.mustache b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/JSON.mustache new file mode 100644 index 0000000000..02b2fa04ed --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/JSON.mustache @@ -0,0 +1,528 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import io.gsonfire.GsonFireBuilder; +import io.gsonfire.PostProcessor; +import io.gsonfire.TypeSelector; +import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapter; +import com.google.gson.internal.bind.util.ISO8601Utils; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +{{#joda}} +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.DateTimeFormatterBuilder; +import org.joda.time.format.ISODateTimeFormat; +{{/joda}} +{{#threetenbp}} +import org.threeten.bp.LocalDate; +import org.threeten.bp.OffsetDateTime; +import org.threeten.bp.format.DateTimeFormatter; +{{/threetenbp}} + +{{#hasModel}}import {{modelPackage}}.*;{{/hasModel}} + +import java.io.IOException; +import java.io.StringReader; +import java.lang.reflect.Type; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.ParsePosition; +{{#java8}} +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +{{/java8}} +import java.util.Date; +import java.util.Map; +import java.util.HashMap; + +public class JSON { + private Gson gson; + private boolean isLenientOnJson = false; + private DateTypeAdapter dateTypeAdapter = new DateTypeAdapter(); + private SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter(); + {{#joda}} + private DateTimeTypeAdapter dateTimeTypeAdapter = new DateTimeTypeAdapter(); + private LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter(); + {{/joda}} + {{#jsr310}} + private OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter(); + private LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter(); + {{/jsr310}} + + public static GsonBuilder createGson() { + GsonFireBuilder fireBuilder = new GsonFireBuilder() + {{#parent}} + {{#discriminator}} + .registerTypeSelector({{classname}}.class, new TypeSelector<{{classname}}>() { + @Override + public Class getClassForElement(JsonElement readElement) { + Map> classByDiscriminatorValue = new HashMap<>(); + {{#if discriminator.mapping}} + {{#each discriminator.mapping}} + classByDiscriminatorValue.put("{{@key}}".toUpperCase(), {{this}}.class); + {{/each}} + {{else}} + {{#children}} + classByDiscriminatorValue.put("{{name}}".toUpperCase(), {{classname}}.class); + {{/children}} + classByDiscriminatorValue.put("{{classname}}".toUpperCase(), {{classname}}.class); + {{/if}} + return getClassByDiscriminator( + classByDiscriminatorValue, + getDiscriminatorValue(readElement, "{{discriminator.propertyName}}")); + } + }) + .registerPostProcessor({{classname}}.class, new PostProcessor<{{classname}}>() { + @Override + public void postDeserialize({{classname}} result, JsonElement src, Gson gson) { + + } + + @Override + public void postSerialize(JsonElement result, {{classname}} src, Gson gson) { + Map, String> discriminatorValueByClass = new HashMap<>(); + {{#if discriminator.mapping}} + {{#each discriminator.mapping}} + discriminatorValueByClass.put({{this}}.class, "{{@key}}"); + {{/each}} + {{else}} + {{#children}} + discriminatorValueByClass.put({{classname}}.class, "{{name}}"); + {{/children}} + discriminatorValueByClass.put({{classname}}.class, "{{classname}}"); + {{/if}} + if(result instanceof JsonObject) + { + if(!((JsonObject) result).has("{{discriminator.propertyName}}")) + { + ((JsonObject) result).addProperty("{{discriminator.propertyName}}", discriminatorValueByClass.get(src.getClass())); + } + } + } + }) + {{/discriminator}} + {{/parent}} + ; + return fireBuilder.createGsonBuilder(); + } + + private static String getDiscriminatorValue(JsonElement readElement, String discriminatorField) { + JsonElement element = readElement.getAsJsonObject().get(discriminatorField); + if(null == element) { + throw new IllegalArgumentException("missing discriminator field: <" + discriminatorField + ">"); + } + return element.getAsString(); + } + + private static Class getClassByDiscriminator(Map> classByDiscriminatorValue, String discriminatorValue) { + Class clazz = classByDiscriminatorValue.get(discriminatorValue.toUpperCase()); + if(null == clazz) { + throw new IllegalArgumentException("cannot determine model class of name: <" + discriminatorValue + ">"); + } + return clazz; + } + + public JSON() { + gson = createGson() + .registerTypeAdapter(Date.class, dateTypeAdapter) + .registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter) + {{#joda}} + .registerTypeAdapter(DateTime.class, dateTimeTypeAdapter) + .registerTypeAdapter(LocalDate.class, localDateTypeAdapter) + {{/joda}} + {{#jsr310}} + .registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter) + .registerTypeAdapter(LocalDate.class, localDateTypeAdapter) + {{/jsr310}} + .create(); + } + + /** + * Get Gson. + * + * @return Gson + */ + public Gson getGson() { + return gson; + } + + /** + * Set Gson. + * + * @param gson Gson + * @return JSON + */ + public JSON setGson(Gson gson) { + this.gson = gson; + return this; + } + + public JSON setLenientOnJson(boolean lenientOnJson) { + isLenientOnJson = lenientOnJson; + return this; + } + + /** + * Serialize the given Java object into JSON string. + * + * @param obj Object + * @return String representation of the JSON + */ + public String serialize(Object obj) { + return gson.toJson(obj); + } + + /** + * Deserialize the given JSON string to Java object. + * + * @param Type + * @param body The JSON string + * @param returnType The type to deserialize into + * @return The deserialized Java object + */ + @SuppressWarnings("unchecked") + public T deserialize(String body, Type returnType) { + try { + if (isLenientOnJson) { + JsonReader jsonReader = new JsonReader(new StringReader(body)); + // see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean) + jsonReader.setLenient(true); + return gson.fromJson(jsonReader, returnType); + } else { + return gson.fromJson(body, returnType); + } + } catch (JsonParseException e) { + // Fallback processing when failed to parse JSON form response body: + // return the response body string directly for the String return type; + if (returnType.equals(String.class)) + return (T) body; + else throw (e); + } + } + + {{#joda}} + /** + * Gson TypeAdapter for Joda DateTime type + */ + public static class DateTimeTypeAdapter extends TypeAdapter { + + private DateTimeFormatter formatter; + + public DateTimeTypeAdapter() { + this(new DateTimeFormatterBuilder() + .append(ISODateTimeFormat.dateTime().getPrinter(), ISODateTimeFormat.dateOptionalTimeParser().getParser()) + .toFormatter()); + } + + public DateTimeTypeAdapter(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + public void setFormat(DateTimeFormatter dateFormat) { + this.formatter = dateFormat; + } + + @Override + public void write(JsonWriter out, DateTime date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(formatter.print(date)); + } + } + + @Override + public DateTime read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + return formatter.parseDateTime(date); + } + } + } + + /** + * Gson TypeAdapter for Joda LocalDate type + */ + public class LocalDateTypeAdapter extends TypeAdapter { + + private DateTimeFormatter formatter; + + public LocalDateTypeAdapter() { + this(ISODateTimeFormat.date()); + } + + public LocalDateTypeAdapter(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + public void setFormat(DateTimeFormatter dateFormat) { + this.formatter = dateFormat; + } + + @Override + public void write(JsonWriter out, LocalDate date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(formatter.print(date)); + } + } + + @Override + public LocalDate read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + return formatter.parseLocalDate(date); + } + } + } + + public JSON setDateTimeFormat(DateTimeFormatter dateFormat) { + dateTimeTypeAdapter.setFormat(dateFormat); + return this; + } + + public JSON setLocalDateFormat(DateTimeFormatter dateFormat) { + localDateTypeAdapter.setFormat(dateFormat); + return this; + } + + {{/joda}} + {{#jsr310}} + /** + * Gson TypeAdapter for JSR310 OffsetDateTime type + */ + public static class OffsetDateTimeTypeAdapter extends TypeAdapter { + + private DateTimeFormatter formatter; + + public OffsetDateTimeTypeAdapter() { + this(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } + + public OffsetDateTimeTypeAdapter(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + public void setFormat(DateTimeFormatter dateFormat) { + this.formatter = dateFormat; + } + + @Override + public void write(JsonWriter out, OffsetDateTime date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(formatter.format(date)); + } + } + + @Override + public OffsetDateTime read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + if (date.endsWith("+0000")) { + date = date.substring(0, date.length()-5) + "Z"; + } + return OffsetDateTime.parse(date, formatter); + } + } + } + + /** + * Gson TypeAdapter for JSR310 LocalDate type + */ + public class LocalDateTypeAdapter extends TypeAdapter { + + private DateTimeFormatter formatter; + + public LocalDateTypeAdapter() { + this(DateTimeFormatter.ISO_LOCAL_DATE); + } + + public LocalDateTypeAdapter(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + public void setFormat(DateTimeFormatter dateFormat) { + this.formatter = dateFormat; + } + + @Override + public void write(JsonWriter out, LocalDate date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(formatter.format(date)); + } + } + + @Override + public LocalDate read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + return LocalDate.parse(date, formatter); + } + } + } + + public JSON setOffsetDateTimeFormat(DateTimeFormatter dateFormat) { + offsetDateTimeTypeAdapter.setFormat(dateFormat); + return this; + } + + public JSON setLocalDateFormat(DateTimeFormatter dateFormat) { + localDateTypeAdapter.setFormat(dateFormat); + return this; + } + + {{/jsr310}} + /** + * Gson TypeAdapter for java.sql.Date type + * If the dateFormat is null, a simple "yyyy-MM-dd" format will be used + * (more efficient than SimpleDateFormat). + */ + public static class SqlDateTypeAdapter extends TypeAdapter { + + private DateFormat dateFormat; + + public SqlDateTypeAdapter() { + } + + public SqlDateTypeAdapter(DateFormat dateFormat) { + this.dateFormat = dateFormat; + } + + public void setFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + } + + @Override + public void write(JsonWriter out, java.sql.Date date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + String value; + if (dateFormat != null) { + value = dateFormat.format(date); + } else { + value = date.toString(); + } + out.value(value); + } + } + + @Override + public java.sql.Date read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + try { + if (dateFormat != null) { + return new java.sql.Date(dateFormat.parse(date).getTime()); + } + return new java.sql.Date(ISO8601Utils.parse(date, new ParsePosition(0)).getTime()); + } catch (ParseException e) { + throw new JsonParseException(e); + } + } + } + } + + /** + * Gson TypeAdapter for java.util.Date type + * If the dateFormat is null, ISO8601Utils will be used. + */ + public static class DateTypeAdapter extends TypeAdapter { + + private DateFormat dateFormat; + + public DateTypeAdapter() { + } + + public DateTypeAdapter(DateFormat dateFormat) { + this.dateFormat = dateFormat; + } + + public void setFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + } + + @Override + public void write(JsonWriter out, Date date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + String value; + if (dateFormat != null) { + value = dateFormat.format(date); + } else { + value = ISO8601Utils.format(date, true); + } + out.value(value); + } + } + + @Override + public Date read(JsonReader in) throws IOException { + try { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + try { + if (dateFormat != null) { + return dateFormat.parse(date); + } + return ISO8601Utils.parse(date, new ParsePosition(0)); + } catch (ParseException e) { + throw new JsonParseException(e); + } + } + } catch (IllegalArgumentException e) { + throw new JsonParseException(e); + } + } + } + + public JSON setDateFormat(DateFormat dateFormat) { + dateTypeAdapter.setFormat(dateFormat); + return this; + } + + public JSON setSqlDateFormat(DateFormat dateFormat) { + sqlDateTypeAdapter.setFormat(dateFormat); + return this; + } + +} diff --git a/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ProgressRequestBody.mustache b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ProgressRequestBody.mustache new file mode 100644 index 0000000000..d9ceeab12a --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ProgressRequestBody.mustache @@ -0,0 +1,66 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +import okhttp3.MediaType; +import okhttp3.RequestBody; + +import java.io.IOException; + +import okio.Buffer; +import okio.BufferedSink; +import okio.ForwardingSink; +import okio.Okio; +import okio.Sink; + +public class ProgressRequestBody extends RequestBody { + + public interface ProgressRequestListener { + void onRequestProgress(long bytesWritten, long contentLength, boolean done); + } + + private final RequestBody requestBody; + + private final ProgressRequestListener progressListener; + + public ProgressRequestBody(RequestBody requestBody, ProgressRequestListener progressListener) { + this.requestBody = requestBody; + this.progressListener = progressListener; + } + + @Override + public MediaType contentType() { + return requestBody.contentType(); + } + + @Override + public long contentLength() throws IOException { + return requestBody.contentLength(); + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + BufferedSink bufferedSink = Okio.buffer(sink(sink)); + requestBody.writeTo(bufferedSink); + bufferedSink.flush(); + } + + private Sink sink(Sink sink) { + return new ForwardingSink(sink) { + + long bytesWritten = 0L; + long contentLength = 0L; + + @Override + public void write(Buffer source, long byteCount) throws IOException { + super.write(source, byteCount); + if (contentLength == 0) { + contentLength = contentLength(); + } + + bytesWritten += byteCount; + progressListener.onRequestProgress(bytesWritten, contentLength, bytesWritten == contentLength); + } + }; + } +} diff --git a/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ProgressResponseBody.mustache b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ProgressResponseBody.mustache new file mode 100644 index 0000000000..34713eca11 --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/ProgressResponseBody.mustache @@ -0,0 +1,65 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +import okhttp3.MediaType; +import okhttp3.ResponseBody; + +import java.io.IOException; + +import okio.Buffer; +import okio.BufferedSource; +import okio.ForwardingSource; +import okio.Okio; +import okio.Source; + +public class ProgressResponseBody extends ResponseBody { + + public interface ProgressListener { + void update(long bytesRead, long contentLength, boolean done); + } + + private final ResponseBody responseBody; + private final ProgressListener progressListener; + private BufferedSource bufferedSource; + + public ProgressResponseBody(ResponseBody responseBody, ProgressListener progressListener) { + this.responseBody = responseBody; + this.progressListener = progressListener; + } + + @Override + public MediaType contentType() { + return responseBody.contentType(); + } + + @Override + public long contentLength() { + return responseBody.contentLength(); + } + + @Override + public BufferedSource source() { + if (bufferedSource == null) { + bufferedSource = Okio.buffer(source(responseBody.source())); + } + return bufferedSource; + } + + private Source source(Source source) { + return new ForwardingSource(source) { + long totalBytesRead = 0L; + + @Override + public long read(Buffer sink, long byteCount) throws IOException { + long bytesRead = super.read(sink, byteCount); + // read() returns the number of bytes read, or -1 if this source is exhausted. + totalBytesRead += bytesRead != -1 ? bytesRead : 0; + progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1); + return bytesRead; + } + }; + } +} + + diff --git a/src/main/resources/handlebars/Java/libraries/okhttp4-gson/api.mustache b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/api.mustache new file mode 100644 index 0000000000..4a13e61eea --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/api.mustache @@ -0,0 +1,250 @@ +{{>licenseInfo}} + +package {{package}}; + +import {{invokerPackage}}.ApiCallback; +import {{invokerPackage}}.ApiClient; +import {{invokerPackage}}.ApiException; +import {{invokerPackage}}.ApiResponse; +import {{invokerPackage}}.Configuration; +import {{invokerPackage}}.Pair; +import {{invokerPackage}}.ProgressRequestBody; +import {{invokerPackage}}.ProgressResponseBody; +{{#performBeanValidation}} +import {{invokerPackage}}.BeanValidationException; +{{/performBeanValidation}} + +import com.google.gson.reflect.TypeToken; + +import java.io.IOException; + +{{#useBeanValidation}} +import javax.validation.constraints.*; +{{/useBeanValidation}} +{{#performBeanValidation}} +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.ValidatorFactory; +import javax.validation.executable.ExecutableValidator; +import java.util.Set; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +{{/performBeanValidation}} + +{{#imports}}import {{import}}; +{{/imports}} + +import java.lang.reflect.Type; +{{^fullJavaUtil}} +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +{{/fullJavaUtil}} + +{{#operations}} +public class {{classname}} { + private ApiClient {{localVariablePrefix}}apiClient; + + public {{classname}}() { + this(Configuration.getDefaultApiClient()); + } + + public {{classname}}(ApiClient apiClient) { + this.{{localVariablePrefix}}apiClient = apiClient; + } + + public ApiClient getApiClient() { + return {{localVariablePrefix}}apiClient; + } + + public void setApiClient(ApiClient apiClient) { + this.{{localVariablePrefix}}apiClient = apiClient; + } + + {{#operation}} + {{#contents}} + /** + * Build call for {{operationId}}{{#parameters}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/parameters}} + * @param progressListener Progress listener + * @param progressRequestListener Progress request listener + * @return Call to execute + * @throws ApiException If fail to serialize the request body object + {{#externalDocs}} + * {{description}} + * @see {{summary}} Documentation + {{/externalDocs}} + */ + public okhttp3.Call {{operationId}}Call({{#parameters}}{{{dataType}}} {{paramName}}, {{/parameters}}final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException { + Object {{localVariablePrefix}}localVarPostBody = {{^isForm}}{{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}{{/isForm}}{{#isForm}}null{{/isForm}}; + + // create path and map variables + String {{localVariablePrefix}}localVarPath = "{{{path}}}"{{#pathParams}} + .replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}}; + + {{javaUtilPrefix}}List {{localVariablePrefix}}localVarQueryParams = new {{javaUtilPrefix}}ArrayList(); + {{javaUtilPrefix}}List {{localVariablePrefix}}localVarCollectionQueryParams = new {{javaUtilPrefix}}ArrayList();{{#queryParams}} + if ({{paramName}} != null) + {{localVariablePrefix}}{{#collectionFormat}}localVarCollectionQueryParams.addAll({{localVariablePrefix}}apiClient.parameterToPairs("{{{collectionFormat}}}", {{/collectionFormat}}{{^collectionFormat}}localVarQueryParams.addAll({{localVariablePrefix}}apiClient.parameterToPair({{/collectionFormat}}"{{baseName}}", {{paramName}}));{{/queryParams}} + + {{javaUtilPrefix}}Map {{localVariablePrefix}}localVarHeaderParams = new {{javaUtilPrefix}}HashMap();{{#headerParams}} + if ({{paramName}} != null) + {{localVariablePrefix}}localVarHeaderParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}));{{/headerParams}} + + {{javaUtilPrefix}}Map {{localVariablePrefix}}localVarFormParams = new {{javaUtilPrefix}}HashMap(); + {{#isForm}} + {{#formParams}} + if ({{paramName}} != null) + {{localVariablePrefix}}localVarFormParams.put("{{baseName}}", {{paramName}}); + {{/formParams}} + {{/isForm}} + + final String[] {{localVariablePrefix}}localVarAccepts = { + {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} + }; + final String {{localVariablePrefix}}localVarAccept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}localVarAccepts); + if ({{localVariablePrefix}}localVarAccept != null) {{localVariablePrefix}}localVarHeaderParams.put("Accept", {{localVariablePrefix}}localVarAccept); + + final String[] {{localVariablePrefix}}localVarContentTypes = { + {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} + }; + final String {{localVariablePrefix}}localVarContentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}localVarContentTypes); + {{localVariablePrefix}}localVarHeaderParams.put("Content-Type", {{localVariablePrefix}}localVarContentType); + + if(progressListener != null) { + {{localVariablePrefix}}apiClient.getHttpClient().networkInterceptors().add(new okhttp3.Interceptor() { + @Override + public okhttp3.Response intercept(okhttp3.Interceptor.Chain chain) throws IOException { + okhttp3.Response originalResponse = chain.proceed(chain.request()); + return originalResponse.newBuilder() + .body(new ProgressResponseBody(originalResponse.body(), progressListener)) + .build(); + } + }); + } + + String[] {{localVariablePrefix}}localVarAuthNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} }; + return {{localVariablePrefix}}apiClient.buildCall({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarCollectionQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAuthNames, progressRequestListener); + } + + {{#isDeprecated}} + @Deprecated + {{/isDeprecated}} + @SuppressWarnings("rawtypes") + private okhttp3.Call {{operationId}}ValidateBeforeCall({{#parameters}}{{{dataType}}} {{paramName}}, {{/parameters}}final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException { + {{^performBeanValidation}} + {{#parameters}}{{#required}} + // verify the required parameter '{{paramName}}' is set + if ({{paramName}} == null) { + throw new ApiException("Missing the required parameter '{{paramName}}' when calling {{operationId}}(Async)"); + } + {{/required}}{{/parameters}} + + okhttp3.Call {{localVariablePrefix}}call = {{operationId}}Call({{#parameters}}{{paramName}}, {{/parameters}}progressListener, progressRequestListener); + return {{localVariablePrefix}}call; + + {{/performBeanValidation}} + {{#performBeanValidation}} + try { + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + ExecutableValidator executableValidator = factory.getValidator().forExecutables(); + + Object[] parameterValues = { {{#parameters}}{{paramName}}{{#has this 'more'}}, {{/has}}{{/parameters}} }; + Method method = this.getClass().getMethod("{{operationId}}WithHttpInfo"{{#parameters}}, {{#is this 'list-container'}}java.util.List{{/is}}{{#is this 'map-container'}}java.util.Map{{/is}}{{#isNot this 'list-container'}}{{#isNot this 'map-container'}}{{{dataType}}}{{/isNot}}{{/isNot}}.class{{/parameters}}); + Set> violations = executableValidator.validateParameters(this, method, + parameterValues); + + if (violations.size() == 0) { + okhttp3.Call {{localVariablePrefix}}call = {{operationId}}Call({{#parameters}}{{paramName}}, {{/parameters}}progressListener, progressRequestListener); + return {{localVariablePrefix}}call; + + } else { + throw new BeanValidationException((Set) violations); + } + } catch (NoSuchMethodException e) { + e.printStackTrace(); + throw new ApiException(e.getMessage()); + } catch (SecurityException e) { + e.printStackTrace(); + throw new ApiException(e.getMessage()); + } + + {{/performBeanValidation}} + } + + /** + * {{summary}} + * {{notes}}{{#parameters}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/parameters}}{{#returnType}} + * @return {{returnType}}{{/returnType}} + * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body + {{#externalDocs}} + * {{description}} + * @see {{summary}} Documentation + {{/externalDocs}} + */ + public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#parameters}}{{{dataType}}} {{paramName}}{{#has this 'more'}}, {{/has}}{{/parameters}}) throws ApiException { + {{#returnType}}ApiResponse<{{{returnType}}}> {{localVariablePrefix}}resp = {{/returnType}}{{operationId}}WithHttpInfo({{#parameters}}{{paramName}}{{#has this 'more'}}, {{/has}}{{/parameters}});{{#returnType}} + return {{localVariablePrefix}}resp.getData();{{/returnType}} + } + + /** + * {{summary}} + * {{notes}}{{#parameters}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/parameters}} + * @return ApiResponse<{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Void{{/returnType}}> + * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body + {{#externalDocs}} + * {{description}} + * @see {{summary}} Documentation + {{/externalDocs}} + */ + public ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo({{#parameters}}{{#if useBeanValidation}}{{>beanValidationQueryParams}}{{/if}}{{{dataType}}} {{paramName}}{{#has this 'more'}}, {{/has}}{{/parameters}}) throws ApiException { + okhttp3.Call {{localVariablePrefix}}call = {{operationId}}ValidateBeforeCall({{#parameters}}{{paramName}}, {{/parameters}}null, null); + {{#returnType}}Type {{localVariablePrefix}}localVarReturnType = new TypeToken<{{{returnType}}}>(){}.getType(); + return {{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call, {{localVariablePrefix}}localVarReturnType);{{/returnType}}{{^returnType}}return {{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call);{{/returnType}} + } + + /** + * {{summary}} (asynchronously) + * {{notes}}{{#parameters}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/parameters}} + * @param callback The callback to be executed when the API call finishes + * @return The request call + * @throws ApiException If fail to process the API call, e.g. serializing the request body object + {{#externalDocs}} + * {{description}} + * @see {{summary}} Documentation + {{/externalDocs}} + */ + public okhttp3.Call {{operationId}}Async({{#parameters}}{{{dataType}}} {{paramName}}, {{/parameters}}final ApiCallback<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{localVariablePrefix}}callback) throws ApiException { + + ProgressResponseBody.ProgressListener progressListener = null; + ProgressRequestBody.ProgressRequestListener progressRequestListener = null; + + if (callback != null) { + progressListener = new ProgressResponseBody.ProgressListener() { + @Override + public void update(long bytesRead, long contentLength, boolean done) { + callback.onDownloadProgress(bytesRead, contentLength, done); + } + }; + + progressRequestListener = new ProgressRequestBody.ProgressRequestListener() { + @Override + public void onRequestProgress(long bytesWritten, long contentLength, boolean done) { + callback.onUploadProgress(bytesWritten, contentLength, done); + } + }; + } + + okhttp3.Call {{localVariablePrefix}}call = {{operationId}}ValidateBeforeCall({{#parameters}}{{paramName}}, {{/parameters}}progressListener, progressRequestListener); + {{#returnType}}Type {{localVariablePrefix}}localVarReturnType = new TypeToken<{{{returnType}}}>(){}.getType(); + {{localVariablePrefix}}apiClient.executeAsync({{localVariablePrefix}}call, {{localVariablePrefix}}localVarReturnType, {{localVariablePrefix}}callback);{{/returnType}}{{^returnType}}{{localVariablePrefix}}apiClient.executeAsync({{localVariablePrefix}}call, {{localVariablePrefix}}callback);{{/returnType}} + return {{localVariablePrefix}}call; + } + {{/contents}} + {{/operation}} +} +{{/operations}} diff --git a/src/main/resources/handlebars/Java/libraries/okhttp4-gson/auth/HttpBasicAuth.mustache b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/auth/HttpBasicAuth.mustache new file mode 100644 index 0000000000..6356e227a1 --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/auth/HttpBasicAuth.mustache @@ -0,0 +1,43 @@ +{{>licenseInfo}} + +package {{invokerPackage}}.auth; + +import {{invokerPackage}}.Pair; + +import okhttp3.Credentials; + +import java.util.Map; +import java.util.List; + +import java.io.UnsupportedEncodingException; + +public class HttpBasicAuth implements Authentication { + private String username; + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public void applyToParams(List queryParams, Map headerParams) { + if (username == null && password == null) { + return; + } + headerParams.put("Authorization", Credentials.basic( + username == null ? "" : username, + password == null ? "" : password)); + } +} diff --git a/src/main/resources/handlebars/Java/libraries/okhttp4-gson/build.gradle.java11.mustache b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/build.gradle.java11.mustache new file mode 100644 index 0000000000..80bd646b5c --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/build.gradle.java11.mustache @@ -0,0 +1,59 @@ +/* +* okhttp +*/ +plugins { + id 'java' + id 'maven-publish' +} + +repositories { + mavenLocal() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +dependencies { + compile 'io.swagger:swagger-annotations:1.6.9' + compile 'com.squareup.okhttp:okhttp:4.10.0' + compile 'com.squareup.okhttp:logging-interceptor:4.10.0' + compile 'com.google.code.gson:gson:2.10.1' + compile 'io.gsonfire:gson-fire:1.8.5' + {{#joda}} + compile 'joda-time:joda-time:2.12.1' + {{/joda}} + {{#threetenbp}} + compile 'org.threeten:threetenbp:1.6.5' + {{/threetenbp}} + testCompile 'junit:junit:4.13.2' +} + +group = '{{groupId}}' +version = '{{artifactVersion}}' +description = '{{artifactDescription}}' + +java.sourceCompatibility = 11 +java.targetCompatibility = 11 + +tasks.register('testsJar', Jar) { + archiveClassifier = 'tests' + from(sourceSets.test.output) +} + +java { + withSourcesJar() + withJavadocJar() +} + +publishing { + publications { + maven(MavenPublication) { + from(components.java) + artifact(testsJar) + } + } +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} diff --git a/src/main/resources/handlebars/Java/libraries/okhttp4-gson/build.gradle.mustache b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/build.gradle.mustache new file mode 100644 index 0000000000..8f445861a8 --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/build.gradle.mustache @@ -0,0 +1,118 @@ +apply plugin: 'idea' +apply plugin: 'eclipse' + +group = '{{groupId}}' +version = '{{artifactVersion}}' + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.3.+' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + } +} + +repositories { + jcenter() +} + + +if(hasProperty('target') && target == 'android') { + + apply plugin: 'com.android.library' + apply plugin: 'com.github.dcendents.android-maven' + + android { + compileSdkVersion 25 + buildToolsVersion '25.0.2' + defaultConfig { + minSdkVersion 14 + targetSdkVersion 25 + } + compileOptions { + {{#java8}} + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + {{/java8}} + {{^java8}} + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + {{/java8}} + } + + // Rename the aar correctly + libraryVariants.all { variant -> + variant.outputs.each { output -> + def outputFile = output.outputFile + if (outputFile != null && outputFile.name.endsWith('.aar')) { + def fileName = "${project.name}-${variant.baseName}-${version}.aar" + output.outputFile = new File(outputFile.parent, fileName) + } + } + } + + dependencies { + provided 'javax.annotation:jsr250-api:1.0' + } + } + + afterEvaluate { + android.libraryVariants.all { variant -> + def task = project.tasks.create "jar${variant.name.capitalize()}", Jar + task.description = "Create jar artifact for ${variant.name}" + task.dependsOn variant.javaCompile + task.from variant.javaCompile.destinationDir + task.destinationDir = project.file("${project.buildDir}/outputs/jar") + task.archiveName = "${project.name}-${variant.baseName}-${version}.jar" + artifacts.add('archives', task); + } + } + + task sourcesJar(type: Jar) { + from android.sourceSets.main.java.srcDirs + classifier = 'sources' + } + + artifacts { + archives sourcesJar + } + +} else { + + apply plugin: 'java' + apply plugin: 'maven-publish' + + sourceCompatibility = JavaVersion.VERSION_{{^java8}}1_7{{/java8}}{{#java8}}1_8{{/java8}} + targetCompatibility = JavaVersion.VERSION_{{^java8}}1_7{{/java8}}{{#java8}}1_8{{/java8}} + + publishing { + publications { + maven(MavenPublication) { + artifactId = '{{artifactId}}' + from components.java + } + } + } + + task execute(type:JavaExec) { + main = System.getProperty('mainClass') + classpath = sourceSets.main.runtimeClasspath + } +} + +dependencies { + implementation 'io.swagger:swagger-annotations:1.6.9' + implementation 'com.squareup.okhttp:okhttp:4.10.0' + implementation 'com.squareup.okhttp:logging-interceptor:4.10.0' + implementation 'com.google.code.gson:gson:2.10.1' + implementation 'io.gsonfire:gson-fire:1.8.5' + {{#joda}} + implementation 'joda-time:joda-time:2.12.1' + {{/joda}} + {{#threetenbp}} + implementation 'org.threeten:threetenbp:1.6.5' + {{/threetenbp}} + testImplementation 'junit:junit:4.13.2' +} diff --git a/src/main/resources/handlebars/Java/libraries/okhttp4-gson/build.sbt.mustache b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/build.sbt.mustache new file mode 100644 index 0000000000..9a7e22cb0f --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/build.sbt.mustache @@ -0,0 +1,26 @@ +lazy val root = (project in file(".")). + settings( + organization := "{{groupId}}", + name := "{{artifactId}}", + version := "{{artifactVersion}}", + scalaVersion := "2.11.4", + scalacOptions ++= Seq("-feature"), + javacOptions in compile ++= Seq("-Xlint:deprecation"), + publishArtifact in (Compile, packageDoc) := false, + resolvers += Resolver.mavenLocal, + libraryDependencies ++= Seq( + "io.swagger" % "swagger-annotations" % "1.6.9", + "com.squareup.okhttp" % "okhttp" % "4.10.0", + "com.squareup.okhttp" % "logging-interceptor" % "4.10.0", + "com.google.code.gson" % "gson" % "2.10.1", + {{#joda}} + "joda-time" % "joda-time" % "2.12.1" % "compile", + {{/joda}} + {{#threetenbp}} + "org.threeten" % "threetenbp" % "1.6.5" % "compile", + {{/threetenbp}} + "io.gsonfire" % "gson-fire" % "1.8.5" % "compile", + "junit" % "junit" % "4.13.2" % "test", + "com.novocode" % "junit-interface" % "0.10" % "test" + ) + ) diff --git a/src/main/resources/handlebars/Java/libraries/okhttp4-gson/pom.mustache b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/pom.mustache new file mode 100644 index 0000000000..bb69b9c41f --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/okhttp4-gson/pom.mustache @@ -0,0 +1,341 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{artifactVersion}} + {{artifactUrl}} + {{artifactDescription}} + + {{scmConnection}} + {{scmDeveloperConnection}} + {{scmUrl}} + + + + + {{licenseName}} + {{licenseUrl}} + repo + + + + + + {{developerName}} + {{developerEmail}} + {{developerOrganization}} + {{developerOrganizationUrl}} + + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M1 + + + enforce-maven + + enforce + + + + + 2.2.0 + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + 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.2.0 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + + + + + sign-artifacts + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + {{#java11}} + + jdk11 + + [11,) + + + + com.sun.xml.ws + jaxws-rt + 2.3.3 + pom + + + + {{/java11}} + + + + {{#useOas2}} + + io.swagger + swagger-annotations + ${swagger-core-version} + + {{/useOas2}} + {{^useOas2}} + + io.swagger.core.v3 + swagger-annotations + ${swagger-core-version} + + {{/useOas2}} + + com.squareup.okhttp3 + okhttp + ${okhttp-version} + + + com.squareup.okhttp3 + logging-interceptor + ${okhttp-version} + + + com.google.code.gson + gson + ${gson-version} + + + io.gsonfire + gson-fire + ${gson-fire-version} + + {{#joda}} + + joda-time + joda-time + ${jodatime-version} + + {{/joda}} + {{#threetenbp}} + + org.threeten + threetenbp + ${threetenbp-version} + + {{/threetenbp}} + {{#useBeanValidation}} + + + javax.validation + validation-api + 2.0.1.Final + provided + + {{/useBeanValidation}} + {{#notNullJacksonAnnotation}} + + com.fasterxml.jackson.core + jackson-annotations + 2.14.1 + + {{/notNullJacksonAnnotation}} + {{^notNullJacksonAnnotation}} + {{#ignoreUnknownJacksonAnnotation}} + + com.fasterxml.jackson.core + jackson-annotations + 2.14.1 + + {{/ignoreUnknownJacksonAnnotation}} + {{/notNullJacksonAnnotation}} + {{#performBeanValidation}} + + + org.hibernate + hibernate-validator + 8.0.0.Final + + + javax.el + el-api + 2.2 + + {{/performBeanValidation}} + {{#parcelableModel}} + + + com.google.android + android + 4.1.1.4 + provided + + {{/parcelableModel}} + + + junit + junit + ${junit-version} + test + + {{#wiremock}} + + com.github.tomakehurst + wiremock + 2.27.2 + test + + {{/wiremock}} + + + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} + ${java.version} + ${java.version} + 1.8.5 + {{#useOas2}} + 1.5.15 + {{/useOas2}} + {{^useOas2}} + 2.0.0 + {{/useOas2}} + 4.10.0 + 2.10.1 + {{#joda}} + 2.12.1 + {{/joda}} + {{#threetenbp}} + 1.6.5 + {{/threetenbp}} + 1.0.0 + 4.13.2 + UTF-8 + + diff --git a/src/main/resources/handlebars/Java/libraries/resteasy/ApiClient.mustache b/src/main/resources/handlebars/Java/libraries/resteasy/ApiClient.mustache index cc8ad4af25..110f07e3a8 100644 --- a/src/main/resources/handlebars/Java/libraries/resteasy/ApiClient.mustache +++ b/src/main/resources/handlebars/Java/libraries/resteasy/ApiClient.mustache @@ -23,6 +23,19 @@ import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; +{{#jakarta}} +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.Form; +import jakarta.ws.rs.core.GenericType; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; @@ -33,6 +46,7 @@ import javax.ws.rs.core.GenericType; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +{{/jakarta}} import org.jboss.logging.Logger; import org.jboss.resteasy.client.jaxrs.internal.ClientConfiguration; diff --git a/src/main/resources/handlebars/Java/libraries/resteasy/JSON.mustache b/src/main/resources/handlebars/Java/libraries/resteasy/JSON.mustache index 27d2aa65d2..ae8f9dd597 100644 --- a/src/main/resources/handlebars/Java/libraries/resteasy/JSON.mustache +++ b/src/main/resources/handlebars/Java/libraries/resteasy/JSON.mustache @@ -11,7 +11,12 @@ import com.fasterxml.jackson.datatype.joda.*; import java.text.DateFormat; +{{#jakarta}} +import jakarta.ws.rs.ext.ContextResolver; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.ext.ContextResolver; +{{/jakarta}} {{>generatedAnnotation}} public class JSON implements ContextResolver { diff --git a/src/main/resources/handlebars/Java/libraries/resteasy/api.mustache b/src/main/resources/handlebars/Java/libraries/resteasy/api.mustache index 9aaa14a33e..dc82c09647 100644 --- a/src/main/resources/handlebars/Java/libraries/resteasy/api.mustache +++ b/src/main/resources/handlebars/Java/libraries/resteasy/api.mustache @@ -5,7 +5,12 @@ import {{invokerPackage}}.ApiClient; import {{invokerPackage}}.Configuration; import {{invokerPackage}}.Pair; +{{#jakarta}} +import jakarta.ws.rs.core.GenericType; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.GenericType; +{{/jakarta}} {{#imports}}import {{import}}; {{/imports}} diff --git a/src/main/resources/handlebars/Java/libraries/resteasy/build.gradle.mustache b/src/main/resources/handlebars/Java/libraries/resteasy/build.gradle.mustache index cb4a9f8e61..e09a15af50 100644 --- a/src/main/resources/handlebars/Java/libraries/resteasy/build.gradle.mustache +++ b/src/main/resources/handlebars/Java/libraries/resteasy/build.gradle.mustache @@ -6,7 +6,7 @@ version = '{{artifactVersion}}' buildscript { repositories { - jcenter() + mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:1.5.+' @@ -15,7 +15,7 @@ buildscript { } repositories { - jcenter() + mavenCentral() } @@ -54,7 +54,7 @@ if(hasProperty('target') && target == 'android') { } dependencies { - provided 'javax.annotation:jsr250-api:1.0' + provided 'jakarta.annotation:jakarta.annotation-api:{{#jakarta}}2.1.1{{/jakarta}}{{^jakarta}}1.3.5{{/jakarta}}' } } @@ -82,7 +82,7 @@ if(hasProperty('target') && target == 'android') { } else { apply plugin: 'java' - apply plugin: 'maven' + apply plugin: 'maven-publish' {{#java8}} sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 @@ -92,9 +92,12 @@ if(hasProperty('target') && target == 'android') { targetCompatibility = JavaVersion.VERSION_1_7 {{/java8}} - install { - repositories.mavenInstaller { - pom.artifactId = '{{artifactId}}' + publishing { + publications { + maven(MavenPublication) { + artifactId = '{{artifactId}}' + from components.java + } } } @@ -111,8 +114,8 @@ ext { {{^useOas2}} swagger_annotations_version = "2.0.0" {{/useOas2}} - jackson_version = "2.7.5" - jersey_version = "2.22.2" + jackson_version = "2.10.1" + jersey_version = "{{#jakarta}}3.1.0{{/jakarta}}{{^jakarta}}2.22.2{{/jakarta}}" {{^java8}} jodatime_version = "2.9.4" {{/java8}} @@ -125,28 +128,28 @@ ext { dependencies { {{#useOas2}} - compile "io.swagger:swagger-annotations:$swagger_annotations_version" + implementation "io.swagger:swagger-annotations:$swagger_annotations_version" {{/useOas2}} {{^useOas2}} - compile "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" + implementation "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" {{/useOas2}} - compile "org.glassfish.jersey.core:jersey-client:$jersey_version" - compile "org.glassfish.jersey.media:jersey-media-multipart:$jersey_version" - compile "org.glassfish.jersey.media:jersey-media-json-jackson:$jersey_version" - compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" - compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" - compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + implementation "org.glassfish.jersey.core:jersey-client:$jersey_version" + implementation "org.glassfish.jersey.media:jersey-media-multipart:$jersey_version" + implementation "org.glassfish.jersey.media:jersey-media-json-jackson:$jersey_version" + implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version" {{#java8}} - compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" {{/java8}} {{^java8}} - compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" - compile "joda-time:joda-time:$jodatime_version" - compile "com.brsanthu:migbase64:2.2" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" + implementation "joda-time:joda-time:$jodatime_version" + implementation "com.brsanthu:migbase64:2.2" {{/java8}} {{#supportJava6}} - compile "commons-io:commons-io:$commons_io_version" - compile "org.apache.commons:commons-lang3:$commons_lang3_version" + implementation "commons-io:commons-io:$commons_io_version" + implementation "org.apache.commons:commons-lang3:$commons_lang3_version" {{/supportJava6}} - testCompile "junit:junit:$junit_version" + testImplementation "junit:junit:$junit_version" } diff --git a/src/main/resources/handlebars/Java/libraries/resteasy/pom.mustache b/src/main/resources/handlebars/Java/libraries/resteasy/pom.mustache index f8dcf77470..802a60823a 100644 --- a/src/main/resources/handlebars/Java/libraries/resteasy/pom.mustache +++ b/src/main/resources/handlebars/Java/libraries/resteasy/pom.mustache @@ -113,7 +113,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.4 + 3.2.0 @@ -211,7 +211,7 @@ {{/supportJava6}} org.jboss.resteasy - resteasy-jackson-provider + resteasy-jackson2-provider 3.1.3.Final @@ -231,6 +231,14 @@ ${junit-version} test + {{#wiremock}} + + com.github.tomakehurst + wiremock + 2.27.2 + test + + {{/wiremock}} {{#useOas2}} @@ -240,7 +248,7 @@ 2.0.0 {{/useOas2}} 3.1.3.Final - 2.6.4 + 2.15.2 {{^java8}} 2.9.9 {{/java8}} diff --git a/src/main/resources/handlebars/Java/libraries/resttemplate/ApiClient.mustache b/src/main/resources/handlebars/Java/libraries/resttemplate/ApiClient.mustache index 7b4cf2abad..c74ff62c8f 100644 --- a/src/main/resources/handlebars/Java/libraries/resttemplate/ApiClient.mustache +++ b/src/main/resources/handlebars/Java/libraries/resttemplate/ApiClient.mustache @@ -91,9 +91,6 @@ public class ApiClient { private RestTemplate restTemplate; private Map authentications; - - private HttpStatus statusCode; - private MultiValueMap responseHeaders; private DateFormat dateFormat; @@ -147,22 +144,6 @@ public class ApiClient { return this; } - /** - * Gets the status code of the previous request - * @return HttpStatus the status code - */ - public HttpStatus getStatusCode() { - return statusCode; - } - - /** - * Gets the response headers of the previous request - * @return MultiValueMap a map of response headers - */ - public MultiValueMap getResponseHeaders() { - return responseHeaders; - } - /** * Get authentications (key: authentication name, value: authentication). * @return Map the currently configured authentication types @@ -518,9 +499,9 @@ public class ApiClient { * @param contentType The request's Content-Type header * @param authNames The authentications to apply * @param returnType The return type into which to deserialize the response - * @return The response body in chosen type + * @return ResponseEntity<T> The response of the chosen type */ - public T invokeAPI(String path, HttpMethod method, MultiValueMap queryParams, Object body, HttpHeaders headerParams, MultiValueMap formParams, List accept, MediaType contentType, String[] authNames, ParameterizedTypeReference returnType) throws RestClientException { + public ResponseEntity invokeAPI(String path, HttpMethod method, MultiValueMap queryParams, Object body, HttpHeaders headerParams, MultiValueMap formParams, List accept, MediaType contentType, String[] authNames, ParameterizedTypeReference returnType) throws RestClientException { updateParamsForAuth(authNames, queryParams, headerParams); final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(basePath).path(path); @@ -542,20 +523,12 @@ public class ApiClient { RequestEntity requestEntity = requestBuilder.body(selectBody(body, formParams, contentType)); ResponseEntity responseEntity = restTemplate.exchange(requestEntity, returnType); - - statusCode = responseEntity.getStatusCode(); - responseHeaders = responseEntity.getHeaders(); - if (responseEntity.getStatusCode() == HttpStatus.NO_CONTENT) { - return null; - } else if (responseEntity.getStatusCode().is2xxSuccessful()) { - if (returnType == null) { - return null; - } - return responseEntity.getBody(); + if (responseEntity.getStatusCode().is2xxSuccessful()) { + return responseEntity; } else { // The error handler built into the RestTemplate should handle 400 and 500 series errors. - throw new RestClientException("API returned " + statusCode + " and it wasn't handled by the RestTemplate error handler"); + throw new RestClientException("API returned " + responseEntity.getStatusCode() + " and it wasn't handled by the RestTemplate error handler"); } } diff --git a/src/main/resources/handlebars/Java/libraries/resttemplate/api.mustache b/src/main/resources/handlebars/Java/libraries/resttemplate/api.mustache index 8350062ef1..c4b64f5b75 100644 --- a/src/main/resources/handlebars/Java/libraries/resttemplate/api.mustache +++ b/src/main/resources/handlebars/Java/libraries/resttemplate/api.mustache @@ -23,6 +23,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; {{>generatedAnnotation}} @Component("{{package}}.{{classname}}") @@ -56,7 +57,7 @@ public class {{classname}} { *

{{code}}{{#message}} - {{message}}{{/message}} {{/responses}} {{#parameters}} - * @param {{paramName}} {{description}}{{^description}}The {{paramName}} parameter{{/description}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} {{/parameters}} {{#returnType}} * @return {{returnType}} @@ -67,7 +68,38 @@ public class {{classname}} { * @see {{summary}} Documentation {{/externalDocs}} */ + {{#isDeprecated}} + @Deprecated + {{/isDeprecated}} public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#parameters}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/parameters}}) throws RestClientException { + {{#returnType}} + return {{operationId}}WithHttpInfo({{#parameters}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/parameters}}).getBody(); + {{/returnType}} + {{^returnType}} + {{operationId}}WithHttpInfo({{#parameters}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/parameters}}); + {{/returnType}} + } + + /** + * {{summary}} + * {{notes}} + {{#responses}} + *

{{code}}{{#message}} - {{message}}{{/message}} + {{/responses}} + {{#parameters}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} + {{/parameters}} + * @return ResponseEntity<{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Void{{/returnType}}> + * @throws RestClientException if an error occurs while attempting to invoke the API + {{#externalDocs}} + * {{description}} + * @see {{summary}} Documentation + {{/externalDocs}} + */ + {{#isDeprecated}} + @Deprecated + {{/isDeprecated}} + public ResponseEntity<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo({{#parameters}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/parameters}}) throws RestClientException { Object {{localVariablePrefix}}postBody = {{^isForm}}{{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}{{/isForm}}{{#isForm}}null{{/isForm}}; {{#parameters}} {{#required}} @@ -121,7 +153,7 @@ public class {{classname}} { String[] {{localVariablePrefix}}authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} }; {{#returnType}}ParameterizedTypeReference<{{{returnType}}}> {{localVariablePrefix}}returnType = new ParameterizedTypeReference<{{{returnType}}}>() {};{{/returnType}}{{^returnType}}ParameterizedTypeReference {{localVariablePrefix}}returnType = new ParameterizedTypeReference() {};{{/returnType}} - {{#returnType}}return {{/returnType}}{{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, HttpMethod.{{httpMethod}}, {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, {{localVariablePrefix}}returnType); + return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, HttpMethod.{{httpMethod}}, {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, {{localVariablePrefix}}returnType); } {{/contents}} {{/operation}} diff --git a/src/main/resources/handlebars/Java/libraries/resttemplate/build.gradle.java11.mustache b/src/main/resources/handlebars/Java/libraries/resttemplate/build.gradle.java11.mustache new file mode 100644 index 0000000000..7f04f3cbdf --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/resttemplate/build.gradle.java11.mustache @@ -0,0 +1,81 @@ +plugins { + id 'java' + id 'maven-publish' +} + +repositories { + mavenLocal() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +ext { + swagger_annotations_version = "{{#useOas2}}1.5.24{{/useOas2}}{{^useOas2}}2.0.0{{/useOas2}}" + jackson_version = "2.11.4" + spring_web_version = "4.3.9.RELEASE" + jodatime_version = "2.10.5" + junit_version = "4.12" + {{#threetenbp}} + jackson_threeten_version = "2.6.4" + {{/threetenbp}} +} + +dependencies { + {{#useOas2}} + implementation "io.swagger:swagger-annotations:$swagger_annotations_version" + {{/useOas2}} + {{^useOas2}} + implementation "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" + {{/useOas2}} + implementation "org.springframework:spring-web:$spring_web_version" + implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version" + {{#joda}} + implementation "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" + implementation "joda-time:joda-time:$jodatime_version" + {{/joda}} + {{#threetenbp}} + implementation "com.github.joschi.jackson:jackson-datatype-threetenbp:$jackson_threeten_version" + {{/threetenbp}} + {{#withXml}} + implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:$jackson_version" + {{/withXml}} + implementation "com.sun.xml.ws:jaxws-rt:{{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}2.3.3{{/jakarta}}" + testImplementation "junit:junit:$junit_version" + {{#wiremock}} + testImplementation "com.github.tomakehurst:wiremock:2.27.2" + {{/wiremock}} +} + +group = '{{groupId}}' +version = '{{artifactVersion}}' +description = '{{artifactDescription}}' + +java.sourceCompatibility = 11 +java.targetCompatibility = 11 + +tasks.register('testsJar', Jar) { + archiveClassifier = 'tests' + from(sourceSets.test.output) +} + +java { + withSourcesJar() + withJavadocJar() +} + +publishing { + publications { + maven(MavenPublication) { + from(components.java) + artifact(testsJar) + } + } +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} diff --git a/src/main/resources/handlebars/Java/libraries/resttemplate/build.gradle.mustache b/src/main/resources/handlebars/Java/libraries/resttemplate/build.gradle.mustache index 3ccd732914..d553776f27 100644 --- a/src/main/resources/handlebars/Java/libraries/resttemplate/build.gradle.mustache +++ b/src/main/resources/handlebars/Java/libraries/resttemplate/build.gradle.mustache @@ -6,7 +6,7 @@ version = '{{artifactVersion}}' buildscript { repositories { - jcenter() + mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:1.5.+' @@ -15,7 +15,7 @@ buildscript { } repositories { - jcenter() + mavenCentral() } @@ -54,7 +54,12 @@ if(hasProperty('target') && target == 'android') { } dependencies { + {{#jakarta}} + provided 'jakarta.annotation:jakarta.annotation-api:2.1.1' + {{/jakarta}} + {{^jakarta}} provided 'javax.annotation:jsr250-api:1.0' + {{/jakarta}} } } @@ -82,7 +87,7 @@ if(hasProperty('target') && target == 'android') { } else { apply plugin: 'java' - apply plugin: 'maven' + apply plugin: 'maven-publish' {{#java8}} sourceCompatibility = JavaVersion.VERSION_1_8 @@ -93,9 +98,12 @@ if(hasProperty('target') && target == 'android') { targetCompatibility = JavaVersion.VERSION_1_7 {{/java8}} - install { - repositories.mavenInstaller { - pom.artifactId = '{{artifactId}}' + publishing { + publications { + maven(MavenPublication) { + artifactId = '{{artifactId}}' + from components.java + } } } @@ -112,7 +120,7 @@ ext { {{^useOas2}} swagger_annotations_version = "2.0.0" {{/useOas2}} - jackson_version = "2.8.9" + jackson_version = "2.10.1" spring_web_version = "4.3.9.RELEASE" jodatime_version = "2.9.9" junit_version = "4.12" @@ -123,28 +131,28 @@ ext { dependencies { {{#useOas2}} - compile "io.swagger:swagger-annotations:$swagger_annotations_version" + implementation "io.swagger:swagger-annotations:$swagger_annotations_version" {{/useOas2}} {{^useOas2}} - compile "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" + implementation "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" {{/useOas2}} - compile "org.springframework:spring-web:$spring_web_version" - compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" - compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" - compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" - compile "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version" + implementation "org.springframework:spring-web:$spring_web_version" + implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version" {{#java8}} - compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" {{/java8}} {{#joda}} - compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" - compile "joda-time:joda-time:$jodatime_version" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" + implementation "joda-time:joda-time:$jodatime_version" {{/joda}} {{#threetenbp}} - compile "com.github.joschi.jackson:jackson-datatype-threetenbp:$jackson_threeten_version" + implementation "com.github.joschi.jackson:jackson-datatype-threetenbp:$jackson_threeten_version" {{/threetenbp}} {{#withXml}} - compile "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:$jackson_version" + implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:$jackson_version" {{/withXml}} - testCompile "junit:junit:$junit_version" + testImplementation "junit:junit:$junit_version" } diff --git a/src/main/resources/handlebars/Java/libraries/resttemplate/pom.mustache b/src/main/resources/handlebars/Java/libraries/resttemplate/pom.mustache index e032df8d00..992eb298b7 100644 --- a/src/main/resources/handlebars/Java/libraries/resttemplate/pom.mustache +++ b/src/main/resources/handlebars/Java/libraries/resttemplate/pom.mustache @@ -133,7 +133,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.4 + 3.2.0 attach-javadocs @@ -181,6 +181,22 @@ + {{#java11}} + + jdk11 + + [11,) + + + + com.sun.xml.ws + jaxws-rt + {{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}2.3.3{{/jakarta}} + pom + + + + {{/java11}} @@ -271,6 +287,14 @@ ${junit-version} test + {{#wiremock}} + + com.github.tomakehurst + wiremock + 2.27.2 + test + + {{/wiremock}} UTF-8 @@ -286,7 +310,7 @@ 2.9.9 {{/joda}} {{#threetenbp}} - 2.6.4 + 2.15.2 {{/threetenbp}} 1.0.0 4.13.1 diff --git a/src/main/resources/handlebars/Java/libraries/retrofit/ApiClient.mustache b/src/main/resources/handlebars/Java/libraries/retrofit/ApiClient.mustache index 12c2f0efc5..487cc233d7 100644 --- a/src/main/resources/handlebars/Java/libraries/retrofit/ApiClient.mustache +++ b/src/main/resources/handlebars/Java/libraries/retrofit/ApiClient.mustache @@ -54,7 +54,7 @@ public class ApiClient { this(); for(String authName : authNames) { {{#hasAuthMethods}} - Interceptor auth; + Interceptor auth = null; {{#authMethods}}if ("{{name}}".equals(authName)) { {{#is this 'basic'}} auth = new HttpBasicAuth(); diff --git a/src/main/resources/handlebars/Java/libraries/retrofit/api_test.mustache b/src/main/resources/handlebars/Java/libraries/retrofit/api_test.mustache index ac191b73e4..34e47634d4 100644 --- a/src/main/resources/handlebars/Java/libraries/retrofit/api_test.mustache +++ b/src/main/resources/handlebars/Java/libraries/retrofit/api_test.mustache @@ -6,6 +6,13 @@ import {{invokerPackage}}.ApiClient; import org.junit.Before; import org.junit.Test; +{{#wiremock}} +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import java.net.HttpURLConnection; +import org.junit.AfterClass; +{{/wiremock}} + {{^fullJavaUtil}} import java.util.ArrayList; import java.util.HashMap; @@ -13,6 +20,10 @@ import java.util.List; import java.util.Map; {{/fullJavaUtil}} +{{#wiremock}} +import static com.github.tomakehurst.wiremock.client.WireMock.*; +{{/wiremock}} + /** * API tests for {{classname}} */ @@ -20,10 +31,36 @@ public class {{classname}}Test { private {{classname}} api; + {{#wiremock}} + private static WireMockServer wireMockServer; + + @Before + public void setup() { + wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().dynamicPort()); + wireMockServer.start(); + configureFor(wireMockServer.port()); + ApiClient apiClient = new ApiClient(); + apiClient.getAdapterBuilder().setEndpoint("http://localhost:" + wireMockServer.port()); + api = apiClient.createService({{classname}}.class); + + {{#operations}}{{#operation}} + stubFor({{toLowerCase httpMethod}}(urlPathMatching("{{{path}}}")) + .willReturn(aResponse() + .withStatus(HttpURLConnection.HTTP_OK))); + {{/operation}}{{/operations}} + } + + @AfterClass + public static void tearDown() { + wireMockServer.stop(); + } + {{/wiremock}} + {{^wiremock}} @Before public void setup() { api = new ApiClient().createService({{classname}}.class); } + {{/wiremock}} {{#operations}}{{#operation}}{{#contents}}{{#@first}} /** diff --git a/src/main/resources/handlebars/Java/libraries/retrofit/auth/OAuth.mustache b/src/main/resources/handlebars/Java/libraries/retrofit/auth/OAuth.mustache index a88378f3e2..4c39f4e629 100644 --- a/src/main/resources/handlebars/Java/libraries/retrofit/auth/OAuth.mustache +++ b/src/main/resources/handlebars/Java/libraries/retrofit/auth/OAuth.mustache @@ -113,8 +113,14 @@ public class OAuth implements Interceptor { // 401/403 most likely indicates that access token has expired. Unless it happens two times in a row. if ( response != null && (response.code() == HTTP_UNAUTHORIZED || response.code() == HTTP_FORBIDDEN) && updateTokenAndRetryOnAuthorizationFailure ) { - if (updateAccessToken(requestAccessToken)) { - return retryingIntercept( chain, false ); + try { + if (updateAccessToken(requestAccessToken)) { + response.body().close(); + return retryingIntercept( chain, false ); + } + } catch (Exception e) { + response.body().close(); + throw e; } } return response; diff --git a/src/main/resources/handlebars/Java/libraries/retrofit/build.gradle.java11.mustache b/src/main/resources/handlebars/Java/libraries/retrofit/build.gradle.java11.mustache new file mode 100644 index 0000000000..69654df15c --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/retrofit/build.gradle.java11.mustache @@ -0,0 +1,71 @@ +plugins { + id 'java' + id 'maven-publish' +} + +repositories { + mavenLocal() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +ext { + okhttp_version = "2.7.5" + oltu_version = "1.0.2" + retrofit_version = "1.9.0" + swagger_annotations_version = "{{#useOas2}}1.5.24{{/useOas2}}{{^useOas2}}2.0.0{{/useOas2}}" + junit_version = "4.13.1" + jodatime_version = "2.10.5" +} + +dependencies { + implementation "com.squareup.okhttp:okhttp:$okhttp_version" + implementation "com.squareup.retrofit:retrofit:$retrofit_version" + {{#useOas2}} + implementation "io.swagger:swagger-annotations:$swagger_annotations_version" + {{/useOas2}} + {{^useOas2}} + implementation "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" + {{/useOas2}} + implementation("org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version") { + exclude group: 'org.json', module: 'json' + } + implementation "org.json:json:20180130" + implementation "joda-time:joda-time:$jodatime_version" + implementation "com.sun.xml.ws:jaxws-rt:{{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}2.3.3{{/jakarta}}" + testImplementation "junit:junit:$junit_version" + {{#wiremock}} + testImplementation "com.github.tomakehurst:wiremock:2.27.2" + {{/wiremock}} +} + +group = '{{groupId}}' +version = '{{artifactVersion}}' +description = '{{artifactDescription}}' + +java.sourceCompatibility = 11 +java.targetCompatibility = 11 + +tasks.register('testsJar', Jar) { + archiveClassifier = 'tests' + from(sourceSets.test.output) +} + +java { + withSourcesJar() + withJavadocJar() +} + +publishing { + publications { + maven(MavenPublication) { + from(components.java) + artifact(testsJar) + } + } +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} diff --git a/src/main/resources/handlebars/Java/libraries/retrofit/build.gradle.mustache b/src/main/resources/handlebars/Java/libraries/retrofit/build.gradle.mustache index 0473350b52..3b13e4066f 100644 --- a/src/main/resources/handlebars/Java/libraries/retrofit/build.gradle.mustache +++ b/src/main/resources/handlebars/Java/libraries/retrofit/build.gradle.mustache @@ -6,7 +6,7 @@ version = '{{artifactVersion}}' buildscript { repositories { - jcenter() + mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:2.3.+' @@ -15,7 +15,7 @@ buildscript { } repositories { - jcenter() + mavenCentral() } @@ -54,7 +54,12 @@ if(hasProperty('target') && target == 'android') { } dependencies { + {{#jakarta}} + provided 'jakarta.annotation:jakarta.annotation-api:2.1.1' + {{/jakarta}} + {{^jakarta}} provided 'javax.annotation:jsr250-api:1.0' + {{/jakarta}} } } @@ -82,14 +87,17 @@ if(hasProperty('target') && target == 'android') { } else { apply plugin: 'java' - apply plugin: 'maven' + apply plugin: 'maven-publish' sourceCompatibility = JavaVersion.VERSION_1_7 targetCompatibility = JavaVersion.VERSION_1_7 - install { - repositories.mavenInstaller { - pom.artifactId = '{{artifactId}}' + publishing { + publications { + maven(MavenPublication) { + artifactId = '{{artifactId}}' + from components.java + } } } @@ -114,15 +122,18 @@ ext { } dependencies { - compile "com.squareup.okhttp:okhttp:$okhttp_version" - compile "com.squareup.retrofit:retrofit:$retrofit_version" + implementation "com.squareup.okhttp:okhttp:$okhttp_version" + implementation "com.squareup.retrofit:retrofit:$retrofit_version" {{#useOas2}} - compile "io.swagger:swagger-annotations:$swagger_annotations_version" + implementation "io.swagger:swagger-annotations:$swagger_annotations_version" {{/useOas2}} {{^useOas2}} - compile "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" + implementation "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" {{/useOas2}} - compile "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version" - compile "joda-time:joda-time:$jodatime_version" - testCompile "junit:junit:$junit_version" + implementation ("org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version") { + exclude group: "org.json", module: "json" + } + implementation "org.json:json:20180130" + implementation "joda-time:joda-time:$jodatime_version" + testImplementation "junit:junit:$junit_version" } diff --git a/src/main/resources/handlebars/Java/libraries/retrofit/pom.mustache b/src/main/resources/handlebars/Java/libraries/retrofit/pom.mustache index cbeada35bd..c099b11501 100644 --- a/src/main/resources/handlebars/Java/libraries/retrofit/pom.mustache +++ b/src/main/resources/handlebars/Java/libraries/retrofit/pom.mustache @@ -126,7 +126,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.4 + 3.2.0 attach-javadocs @@ -174,6 +174,22 @@ + {{#java11}} + + jdk11 + + [11,) + + + + com.sun.xml.ws + jaxws-rt + {{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}2.3.3{{/jakarta}} + pom + + + + {{/java11}} @@ -229,6 +245,14 @@ ${junit-version} test + {{#wiremock}} + + com.github.tomakehurst + wiremock + 2.27.2 + test + + {{/wiremock}} {{#useOas2}} diff --git a/src/main/resources/handlebars/Java/libraries/retrofit2/ApiClient.mustache b/src/main/resources/handlebars/Java/libraries/retrofit2/ApiClient.mustache index f3b9efc618..64b2648585 100644 --- a/src/main/resources/handlebars/Java/libraries/retrofit2/ApiClient.mustache +++ b/src/main/resources/handlebars/Java/libraries/retrofit2/ApiClient.mustache @@ -61,7 +61,7 @@ public class ApiClient { this(); for(String authName : authNames) { {{#hasAuthMethods}} - Interceptor auth; + Interceptor auth = null; {{#authMethods}}if ("{{name}}".equals(authName)) { {{#is this 'basic'}} auth = new HttpBasicAuth(); diff --git a/src/main/resources/handlebars/Java/libraries/retrofit2/api_test.mustache b/src/main/resources/handlebars/Java/libraries/retrofit2/api_test.mustache index 7c4e8e21ce..ed169f5614 100644 --- a/src/main/resources/handlebars/Java/libraries/retrofit2/api_test.mustache +++ b/src/main/resources/handlebars/Java/libraries/retrofit2/api_test.mustache @@ -6,6 +6,13 @@ import {{invokerPackage}}.ApiClient; import org.junit.Before; import org.junit.Test; +{{#wiremock}} +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import java.net.HttpURLConnection; +import org.junit.AfterClass; +{{/wiremock}} + {{^fullJavaUtil}} import java.util.ArrayList; import java.util.HashMap; @@ -13,6 +20,10 @@ import java.util.List; import java.util.Map; {{/fullJavaUtil}} +{{#wiremock}} +import static com.github.tomakehurst.wiremock.client.WireMock.*; +{{/wiremock}} + /** * API tests for {{classname}} */ @@ -20,10 +31,36 @@ public class {{classname}}Test { private {{classname}} api; + {{#wiremock}} + private static WireMockServer wireMockServer; + + @Before + public void setup() { + wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().dynamicPort()); + wireMockServer.start(); + configureFor(wireMockServer.port()); + ApiClient apiClient = new ApiClient(); + apiClient.getAdapterBuilder().setEndpoint("http://localhost:" + wireMockServer.port()); + api = apiClient.createService({{classname}}.class); + + {{#operations}}{{#operation}} + stubFor({{toLowerCase httpMethod}}(urlPathMatching("{{{path}}}")) + .willReturn(aResponse() + .withStatus(HttpURLConnection.HTTP_OK))); + {{/operation}}{{/operations}} + } + + @AfterClass + public static void tearDown() { + wireMockServer.stop(); + } + {{/wiremock}} + {{^wiremock}} @Before public void setup() { api = new ApiClient().createService({{classname}}.class); } + {{/wiremock}} {{#operations}} {{#operation}} diff --git a/src/main/resources/handlebars/Java/libraries/retrofit2/auth/OAuth.mustache b/src/main/resources/handlebars/Java/libraries/retrofit2/auth/OAuth.mustache index e3b3727cd8..59c0984ae2 100644 --- a/src/main/resources/handlebars/Java/libraries/retrofit2/auth/OAuth.mustache +++ b/src/main/resources/handlebars/Java/libraries/retrofit2/auth/OAuth.mustache @@ -113,8 +113,15 @@ public class OAuth implements Interceptor { // 401/403 most likely indicates that access token has expired. Unless it happens two times in a row. if ( response != null && (response.code() == HTTP_UNAUTHORIZED || response.code() == HTTP_FORBIDDEN) && updateTokenAndRetryOnAuthorizationFailure ) { - if (updateAccessToken(requestAccessToken)) { - return retryingIntercept( chain, false ); + if ( response != null && (response.code() == HTTP_UNAUTHORIZED || response.code() == HTTP_FORBIDDEN) && updateTokenAndRetryOnAuthorizationFailure ) { + try { + if (updateAccessToken(requestAccessToken)) { + response.body().close(); + return retryingIntercept( chain, false ); + } + } catch (Exception e) { + response.body().close(); + throw e; } } return response; diff --git a/src/main/resources/handlebars/Java/libraries/retrofit2/build.gradle.java11.mustache b/src/main/resources/handlebars/Java/libraries/retrofit2/build.gradle.java11.mustache new file mode 100644 index 0000000000..cc2368e844 --- /dev/null +++ b/src/main/resources/handlebars/Java/libraries/retrofit2/build.gradle.java11.mustache @@ -0,0 +1,116 @@ +plugins { + id 'java' + id 'maven-publish' +} + +repositories { + mavenLocal() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +ext { + oltu_version = "1.0.2" + retrofit_version = "2.7.1" + {{#usePlayWS}} + {{#play24}} + jackson_version = "2.11.4" + play_version = "2.4.11" + {{/play24}} + {{#play25}} + jackson_version = "2.11.4" + play_version = "2.5.14" + {{/play25}} + {{/usePlayWS}} + swagger_annotations_version = "{{#useOas2}}1.5.24{{/useOas2}}{{^useOas2}}2.0.0{{/useOas2}}" + junit_version = "4.12" + {{#useRxJava}} + rx_java_version = "1.3.0" + {{/useRxJava}} + {{#useRxJava2}} + rx_java_version = "2.1.1" + {{/useRxJava2}} + {{#joda}} + jodatime_version = "2.10.5" + {{/joda}} + {{#threetenbp}} + threetenbp_version = "1.4.1" + {{/threetenbp}} + json_fire_version = "1.8.3" +} + +dependencies { + implementation "com.squareup.retrofit2:retrofit:$retrofit_version" + implementation "com.squareup.retrofit2:converter-scalars:$retrofit_version" + implementation "com.squareup.retrofit2:converter-gson:$retrofit_version" + {{#useRxJava}} + implementation "com.squareup.retrofit2:adapter-rxjava:$retrofit_version" + implementation "io.reactivex:rxjava:$rx_java_version" + {{/useRxJava}} + {{#useRxJava2}} + implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' + implementation "io.reactivex.rxjava2:rxjava:$rx_java_version" + {{/useRxJava2}} + {{#useOas2}} + implementation "io.swagger:swagger-annotations:$swagger_annotations_version" + {{/useOas2}} + {{^useOas2}} + implementation "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" + {{/useOas2}} + implementation ("org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version"){ + exclude group:'org.apache.oltu.oauth2' , module: 'org.apache.oltu.oauth2.common' + exclude group: 'org.json', module: 'json' + } + implementation "org.json:json:20180130" + implementation "io.gsonfire:gson-fire:$json_fire_version" + {{#joda}} + implementation "joda-time:joda-time:$jodatime_version" + {{/joda}} + {{#threetenbp}} + implementation "org.threeten:threetenbp:$threetenbp_version" + {{/threetenbp}} + {{#usePlayWS}} + implementation "com.typesafe.play:play-java-ws_2.11:$play_version" + implementation "com.squareup.retrofit2:converter-jackson:$retrofit_version" + implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" + {{/usePlayWS}} + implementation "com.sun.xml.ws:jaxws-rt:{{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}2.3.3{{/jakarta}}" + {{#wiremock}} + testImplementation "com.github.tomakehurst:wiremock:2.27.2" + {{/wiremock}} + + testImplementation "junit:junit:$junit_version" +} + +group = '{{groupId}}' +version = '{{artifactVersion}}' +description = '{{artifactDescription}}' + +java.sourceCompatibility = 11 +java.targetCompatibility = 11 + +tasks.register('testsJar', Jar) { + archiveClassifier = 'tests' + from(sourceSets.test.output) +} + +java { + withSourcesJar() + withJavadocJar() +} + +publishing { + publications { + maven(MavenPublication) { + from(components.java) + artifact(testsJar) + } + } +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} diff --git a/src/main/resources/handlebars/Java/libraries/retrofit2/build.gradle.mustache b/src/main/resources/handlebars/Java/libraries/retrofit2/build.gradle.mustache index 523bf65124..ca19ded1ef 100644 --- a/src/main/resources/handlebars/Java/libraries/retrofit2/build.gradle.mustache +++ b/src/main/resources/handlebars/Java/libraries/retrofit2/build.gradle.mustache @@ -6,7 +6,7 @@ version = '{{artifactVersion}}' buildscript { repositories { - jcenter() + mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:2.3.+' @@ -15,7 +15,7 @@ buildscript { } repositories { - jcenter() + mavenCentral() } @@ -54,7 +54,12 @@ if(hasProperty('target') && target == 'android') { } dependencies { + {{#jakarta}} + provided 'jakarta.annotation:jakarta.annotation-api:2.1.1' + {{/jakarta}} + {{^jakarta}} provided 'javax.annotation:jsr250-api:1.0' + {{/jakarta}} } } @@ -82,7 +87,7 @@ if(hasProperty('target') && target == 'android') { } else { apply plugin: 'java' - apply plugin: 'maven' + apply plugin: 'maven-publish' sourceCompatibility = JavaVersion.VERSION_{{^java8}}1_7{{/java8}}{{#java8}}1_8{{/java8}} targetCompatibility = JavaVersion.VERSION_{{^java8}}1_7{{/java8}}{{#java8}}1_8{{/java8}} @@ -104,13 +109,12 @@ ext { retrofit_version = "2.3.0" {{#usePlayWS}} {{#play24}} - jackson_version = "2.6.6" play_version = "2.4.11" {{/play24}} {{#play25}} - jackson_version = "2.7.8" play_version = "2.5.14" {{/play25}} + jackson_version = "2.10.1" {{/usePlayWS}} {{#useOas2}} swagger_annotations_version = "1.5.15" @@ -135,38 +139,41 @@ ext { } dependencies { - compile "com.squareup.retrofit2:retrofit:$retrofit_version" - compile "com.squareup.retrofit2:converter-scalars:$retrofit_version" - compile "com.squareup.retrofit2:converter-gson:$retrofit_version" + implementation "com.squareup.retrofit2:retrofit:$retrofit_version" + implementation "com.squareup.retrofit2:converter-scalars:$retrofit_version" + implementation "com.squareup.retrofit2:converter-gson:$retrofit_version" {{#useRxJava}} - compile "com.squareup.retrofit2:adapter-rxjava:$retrofit_version" - compile "io.reactivex:rxjava:$rx_java_version" + implementation "com.squareup.retrofit2:adapter-rxjava:$retrofit_version" + implementation "io.reactivex:rxjava:$rx_java_version" {{/useRxJava}} {{#useRxJava2}} compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' - compile "io.reactivex.rxjava2:rxjava:$rx_java_version" + implementation "io.reactivex.rxjava2:rxjava:$rx_java_version" {{/useRxJava2}} {{#useOas2}} - compile "io.swagger:swagger-annotations:$swagger_annotations_version" + implementation "io.swagger:swagger-annotations:$swagger_annotations_version" {{/useOas2}} {{^useOas2}} - compile "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" + implementation "io.swagger.core.v3:swagger-annotations:$swagger_annotations_version" {{/useOas2}} - compile "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version" - compile "io.gsonfire:gson-fire:$json_fire_version" + implementation ("org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version") { + exclude group: "org.json", module: "json" + } + implementation "org.json:json:20180130" + implementation "io.gsonfire:gson-fire:$json_fire_version" {{#joda}} - compile "joda-time:joda-time:$jodatime_version" + implementation "joda-time:joda-time:$jodatime_version" {{/joda}} {{#threetenbp}} - compile "org.threeten:threetenbp:$threetenbp_version" + implementation "org.threeten:threetenbp:$threetenbp_version" {{/threetenbp}} {{#usePlayWS}} - compile "com.typesafe.play:play-java-ws_2.11:$play_version" - compile "com.squareup.retrofit2:converter-jackson:$retrofit_version" - compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" - compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" - compile "com.fasterxml.jackson.datatype:jackson-datatype-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}}:$jackson_version" + implementation "com.typesafe.play:play-java-ws_2.11:$play_version" + implementation "com.squareup.retrofit2:converter-jackson:$retrofit_version" + implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}}:$jackson_version" {{/usePlayWS}} - testCompile "junit:junit:$junit_version" + testImplementation "junit:junit:$junit_version" } diff --git a/src/main/resources/handlebars/Java/libraries/retrofit2/pom.mustache b/src/main/resources/handlebars/Java/libraries/retrofit2/pom.mustache index a9da7810fe..3404e55b5b 100644 --- a/src/main/resources/handlebars/Java/libraries/retrofit2/pom.mustache +++ b/src/main/resources/handlebars/Java/libraries/retrofit2/pom.mustache @@ -118,7 +118,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.4 + 3.2.0 attach-javadocs @@ -166,6 +166,22 @@ + {{#java11}} + + jdk11 + + [11,) + + + + com.sun.xml.ws + jaxws-rt + {{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}2.3.3{{/jakarta}} + pom + + + + {{/java11}} @@ -320,10 +336,18 @@ ${junit-version} test + {{#wiremock}} + + com.github.tomakehurst + wiremock + 2.27.2 + test + + {{/wiremock}} UTF-8 - {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} ${java.version} ${java.version} 1.8.0 diff --git a/src/main/resources/handlebars/Java/model.mustache b/src/main/resources/handlebars/Java/model.mustache index 6c006f921b..adc112c5d2 100644 --- a/src/main/resources/handlebars/Java/model.mustache +++ b/src/main/resources/handlebars/Java/model.mustache @@ -29,8 +29,14 @@ import android.os.Parcelable; import android.os.Parcel; {{/parcelableModel}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +import jakarta.validation.Valid; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; import javax.validation.Valid; +{{/jakarta}} {{/useBeanValidation}} {{/x-is-composed-model}} {{#models}} diff --git a/src/main/resources/handlebars/Java/modelEnum.mustache b/src/main/resources/handlebars/Java/modelEnum.mustache index 785ffb5ba9..dd9906dc75 100644 --- a/src/main/resources/handlebars/Java/modelEnum.mustache +++ b/src/main/resources/handlebars/Java/modelEnum.mustache @@ -19,6 +19,11 @@ import com.google.gson.stream.JsonWriter; public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} { {{#allowableValues}} {{#enumVars}} + {{#gson}} + {{#value}} + @SerializedName({{{toQuotedWord value}}}) + {{/value}} + {{/gson}} {{{name}}}({{#value}}{{{value}}}{{/value}}{{^value}}null{{/value}}){{^@last}},{{/@last}}{{#@last}};{{/@last}} {{/enumVars}} {{/allowableValues}} @@ -44,27 +49,27 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum {{#jackson}} @JsonCreator {{/jackson}} - public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue(String text) { + public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue({{{dataType}}} input) { for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) { - if (String.valueOf(b.value).equals(text)) { + if (b.value.equals(input)) { return b; } } {{^errorOnUnknownEnum}}return null;{{/errorOnUnknownEnum}}{{#errorOnUnknownEnum}}throw new IllegalArgumentException("Unexpected value '" + text + "' for '{{{classname}}}' enum.");{{/errorOnUnknownEnum}} } -{{#if gson}} +{{#gson}} public static class Adapter extends TypeAdapter<{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}> { @Override public void write(final JsonWriter jsonWriter, final {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} enumeration) throws IOException { - jsonWriter.value(enumeration.getValue()); + jsonWriter.value(String.valueOf(enumeration.getValue())); } @Override public {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} read(final JsonReader jsonReader) throws IOException { Object value = {{#isNumber}}new BigDecimal(jsonReader.nextDouble()){{/isNumber}}{{^isNumber}}jsonReader.{{#isInteger}}nextInt(){{/isInteger}}{{^isInteger}}nextString(){{/isInteger}}{{/isNumber}}; - return {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.fromValue(String.valueOf(value)); + return {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.fromValue(({{{dataType}}})(value)); } } -{{/if}} +{{/gson}} } diff --git a/src/main/resources/handlebars/Java/modelInnerEnum.mustache b/src/main/resources/handlebars/Java/modelInnerEnum.mustache index 544c92887e..7144835581 100644 --- a/src/main/resources/handlebars/Java/modelInnerEnum.mustache +++ b/src/main/resources/handlebars/Java/modelInnerEnum.mustache @@ -5,6 +5,11 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}} {{#enumVars}} + {{#gson}} + {{#value}} + @SerializedName({{{toQuotedWord value}}}) + {{/value}} + {{/gson}} {{{name}}}({{#value}}{{{value}}}{{/value}}{{^value}}null{{/value}}){{^@last}},{{/@last}}{{#@last}};{{/@last}} {{/enumVars}} {{/allowableValues}} @@ -28,9 +33,9 @@ {{#jackson}} @JsonCreator {{/jackson}} - public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue(String text) { + public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue({{{datatype}}} input) { for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) { - if (String.valueOf(b.value).equals(text)) { + if (b.value.equals(input)) { return b; } } @@ -40,13 +45,13 @@ public static class Adapter extends TypeAdapter<{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}> { @Override public void write(final JsonWriter jsonWriter, final {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} enumeration) throws IOException { - jsonWriter.value(enumeration.getValue()); + jsonWriter.value(String.valueOf(enumeration.getValue())); } @Override public {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} read(final JsonReader jsonReader) throws IOException { Object value = {{#isNumber}}new BigDecimal(jsonReader.nextDouble()){{/isNumber}}{{^isNumber}}jsonReader.{{#isInteger}}nextInt(){{/isInteger}}{{^isInteger}}nextString(){{/isInteger}}{{/isNumber}}; - return {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}.fromValue(String.valueOf(value)); + return {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}.fromValue(({{{datatype}}})(value)); } }{{/gson}} } \ No newline at end of file diff --git a/src/main/resources/handlebars/Java/pojo.mustache b/src/main/resources/handlebars/Java/pojo.mustache index df003ca848..135b6e6b8f 100644 --- a/src/main/resources/handlebars/Java/pojo.mustache +++ b/src/main/resources/handlebars/Java/pojo.mustache @@ -7,7 +7,7 @@ @JsonInclude(JsonInclude.Include.NON_NULL) {{/notNullJacksonAnnotation}} -public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcelableModel}}implements Parcelable {{#serializableModel}}, Serializable {{/serializableModel}}{{#interfaceModels}}{{#@first}}, {{/@first}}{{classname}}{{^@last}}, {{/@last}}{{#@last}} {{/@last}}{{/interfaceModels}}{{/parcelableModel}}{{^parcelableModel}}{{#serializableModel}}implements Serializable{{#interfaceModels}}, {{classname}}{{^@last}}, {{/@last}}{{#@last}} {{/@last}}{{/interfaceModels}}{{/serializableModel}}{{^serializableModel}}{{#interfaceModels}}{{#@first}}implements {{/@first}}{{classname}}{{^@last}}, {{/@last}}{{#@last}} {{/@last}}{{/interfaceModels}}{{/serializableModel}}{{/parcelableModel}}{ +public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcelableModel}}implements Parcelable {{#serializableModel}}, Serializable {{/serializableModel}}{{#interfaceModels}}{{#@first}}, {{/@first}}{{classname}}{{^@last}}, {{/@last}}{{#@last}} {{/@last}}{{/interfaceModels}}{{/parcelableModel}}{{^parcelableModel}}{{#serializableModel}}implements Serializable{{#interfaceModels}}{{#@first}}, {{/@first}}{{classname}}{{^@last}}, {{/@last}}{{#@last}} {{/@last}}{{/interfaceModels}}{{/serializableModel}}{{^serializableModel}}{{#interfaceModels}}{{#@first}}implements {{/@first}}{{classname}}{{^@last}}, {{/@last}}{{#@last}} {{/@last}}{{/interfaceModels}}{{/serializableModel}}{{/parcelableModel}}{ {{#serializableModel}} private static final long serialVersionUID = 1L; {{/serializableModel}} diff --git a/src/main/resources/handlebars/Java/pom.mustache b/src/main/resources/handlebars/Java/pom.mustache index 805fe40a9e..465657a9ad 100644 --- a/src/main/resources/handlebars/Java/pom.mustache +++ b/src/main/resources/handlebars/Java/pom.mustache @@ -133,7 +133,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.4 + 3.2.0 attach-javadocs @@ -181,6 +181,22 @@ + {{#java11}} + + jdk11 + + [11,) + + + + com.sun.xml.ws + jaxws-rt + {{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}2.3.3{{/jakarta}} + pom + + + + {{/java11}} @@ -285,12 +301,22 @@ {{/supportJava6}} {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + {{/jakarta}} + {{^jakarta}} javax.validation validation-api 1.1.0.Final provided + {{/jakarta}} {{/useBeanValidation}} {{#parcelableModel}} @@ -308,6 +334,14 @@ ${junit-version} test + {{#wiremock}} + + com.github.tomakehurst + wiremock + 2.27.2 + test + + {{/wiremock}} UTF-8 @@ -322,7 +356,7 @@ 2.5 3.6 {{/supportJava6}} - {{^threetenbp}}2.10.1{{/threetenbp}}{{#threetenbp}}2.6.4{{/threetenbp}} + {{^threetenbp}}2.15.2{{/threetenbp}}{{#threetenbp}}2.6.4{{/threetenbp}} 1.0.0 4.13.1 diff --git a/src/main/resources/handlebars/Java/typeInfoAnnotation.mustache b/src/main/resources/handlebars/Java/typeInfoAnnotation.mustache index f2a2e1c88f..eeda9eb1cf 100644 --- a/src/main/resources/handlebars/Java/typeInfoAnnotation.mustache +++ b/src/main/resources/handlebars/Java/typeInfoAnnotation.mustache @@ -1,7 +1,14 @@ {{#jackson}} @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator.propertyName}}", visible = true ) @JsonSubTypes({ - {{#children}} - @JsonSubTypes.Type(value = {{classname}}.class, name = "{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}"), - {{/children}} -}){{/jackson}} +{{#if discriminator.mapping}} +{{#each discriminator.mapping}} + @JsonSubTypes.Type(value = {{this}}.class, name = "{{@key}}"), +{{/each}} +{{else}} +{{#children}} + @JsonSubTypes.Type(value = {{classname}}.class, name = "{{name}}"), +{{/children}} +{{/if}} +}) +{{/jackson}} diff --git a/src/main/resources/handlebars/JavaInflector/api.mustache b/src/main/resources/handlebars/JavaInflector/api.mustache index 055ef574eb..48101979ba 100644 --- a/src/main/resources/handlebars/JavaInflector/api.mustache +++ b/src/main/resources/handlebars/JavaInflector/api.mustache @@ -2,7 +2,12 @@ package {{invokerPackage}}; import io.swagger.oas.inflector.models.RequestContext; import io.swagger.oas.inflector.models.ResponseContext; +{{#jakarta}} +import jakarta.ws.rs.core.Response.Status; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.Response.Status; +{{/jakarta}} import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import java.io.File; diff --git a/src/main/resources/handlebars/JavaInflector/generatedAnnotation.mustache b/src/main/resources/handlebars/JavaInflector/generatedAnnotation.mustache index a47b6faa85..c6c0883bcb 100644 --- a/src/main/resources/handlebars/JavaInflector/generatedAnnotation.mustache +++ b/src/main/resources/handlebars/JavaInflector/generatedAnnotation.mustache @@ -1 +1 @@ -{{^hideGenerationTimestamp}}@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} \ No newline at end of file +{{^hideGenerationTimestamp}}@{{#jakarta}}jakarta{{/jakarta}}{{^jakarta}}javax{{/jakarta}}.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} diff --git a/src/main/resources/handlebars/JavaInflector/interface.mustache b/src/main/resources/handlebars/JavaInflector/interface.mustache index becc0c5549..abec32f768 100644 --- a/src/main/resources/handlebars/JavaInflector/interface.mustache +++ b/src/main/resources/handlebars/JavaInflector/interface.mustache @@ -3,4 +3,9 @@ */ public interface {{{classname}}} { +{{#vendorExtensions}} +{{#x-discriminator-type-getter}} + {{x-discriminator-type}} {{x-discriminator-type-getter}}(); +{{/x-discriminator-type-getter}} +{{/vendorExtensions}} } diff --git a/src/main/resources/handlebars/JavaInflector/pom.mustache b/src/main/resources/handlebars/JavaInflector/pom.mustache index a79dd4344c..b01b8b4495 100644 --- a/src/main/resources/handlebars/JavaInflector/pom.mustache +++ b/src/main/resources/handlebars/JavaInflector/pom.mustache @@ -117,10 +117,14 @@ + {{#java11}} + 11 + 11 + {{/java11}} UTF-8 1.0.0 9.4.9.v20180320 - 1.0.1 + 1.2.9 4.13.1 1.6.3 2.0.0 diff --git a/src/main/resources/handlebars/JavaInflector/typeInfoAnnotation.mustache b/src/main/resources/handlebars/JavaInflector/typeInfoAnnotation.mustache index f2a2e1c88f..52695c64fe 100644 --- a/src/main/resources/handlebars/JavaInflector/typeInfoAnnotation.mustache +++ b/src/main/resources/handlebars/JavaInflector/typeInfoAnnotation.mustache @@ -1,7 +1,14 @@ {{#jackson}} -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator.propertyName}}", visible = true ) -@JsonSubTypes({ - {{#children}} - @JsonSubTypes.Type(value = {{classname}}.class, name = "{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}"), - {{/children}} -}){{/jackson}} + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator.propertyName}}", visible = true ) + @JsonSubTypes({ + {{#if discriminator.mapping}} + {{#each discriminator.mapping}} + @JsonSubTypes.Type(value = {{this}}.class, name = "{{@key}}"), + {{/each}} + {{else}} + {{#children}} + @JsonSubTypes.Type(value = {{classname}}.class, name = "{{name}}"), + {{/children}} + {{/if}} + }) +{{/jackson}} diff --git a/src/main/resources/handlebars/JavaInflector/web.mustache b/src/main/resources/handlebars/JavaInflector/web.mustache index 16a254d111..5ff9821692 100644 --- a/src/main/resources/handlebars/JavaInflector/web.mustache +++ b/src/main/resources/handlebars/JavaInflector/web.mustache @@ -4,7 +4,7 @@ swagger-inflector org.glassfish.jersey.servlet.ServletContainer - javax.ws.rs.Application + {{#jakarta}}jakarta{{/jakarta}}{{^jakarta}}javax{{/jakarta}}.ws.rs.Application io.swagger.oas.inflector.OpenAPIInflector 1 @@ -21,4 +21,4 @@ CORSFilter /* - \ No newline at end of file + diff --git a/src/main/resources/handlebars/JavaJaxRS/ApiOriginFilter.mustache b/src/main/resources/handlebars/JavaJaxRS/ApiOriginFilter.mustache index b8af270a05..f9ef60c3ee 100644 --- a/src/main/resources/handlebars/JavaJaxRS/ApiOriginFilter.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/ApiOriginFilter.mustache @@ -2,11 +2,17 @@ package {{apiPackage}}; import java.io.IOException; +{{#jakarta}} +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletResponse; +{{/jakarta}} +{{^jakarta}} import javax.servlet.*; import javax.servlet.http.HttpServletResponse; +{{/jakarta}} {{>generatedAnnotation}} -public class ApiOriginFilter implements javax.servlet.Filter { +public class ApiOriginFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse res = (HttpServletResponse) response; @@ -19,4 +25,4 @@ public class ApiOriginFilter implements javax.servlet.Filter { public void destroy() {} public void init(FilterConfig filterConfig) throws ServletException {} -} \ No newline at end of file +} diff --git a/src/main/resources/handlebars/JavaJaxRS/ApiResponseMessage.mustache b/src/main/resources/handlebars/JavaJaxRS/ApiResponseMessage.mustache index c883e16b5e..50f428a3aa 100644 --- a/src/main/resources/handlebars/JavaJaxRS/ApiResponseMessage.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/ApiResponseMessage.mustache @@ -1,8 +1,15 @@ package {{apiPackage}}; +{{#jakarta}} +import jakarta.xml.bind.annotation.XmlTransient; + +@jakarta.xml.bind.annotation.XmlRootElement +{{/jakarta}} +{{^jakarta}} import javax.xml.bind.annotation.XmlTransient; @javax.xml.bind.annotation.XmlRootElement +{{/jakarta}} {{>generatedAnnotation}} public class ApiResponseMessage { public static final int ERROR = 1; diff --git a/src/main/resources/handlebars/JavaJaxRS/JodaDateTimeProvider.mustache b/src/main/resources/handlebars/JavaJaxRS/JodaDateTimeProvider.mustache index f942179098..2e81525879 100644 --- a/src/main/resources/handlebars/JavaJaxRS/JodaDateTimeProvider.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/JodaDateTimeProvider.mustache @@ -4,6 +4,16 @@ import com.sun.jersey.core.spi.component.ComponentContext; import com.sun.jersey.spi.inject.Injectable; import com.sun.jersey.spi.inject.PerRequestTypeInjectableProvider; +{{#jakarta}} +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; +import jakarta.ws.rs.core.UriInfo; +import jakarta.ws.rs.ext.Provider; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; @@ -11,6 +21,7 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; import javax.ws.rs.ext.Provider; +{{/jakarta}} import org.joda.time.DateTime; import java.util.List; @@ -41,4 +52,4 @@ public class JodaDateTimeProvider extends PerRequestTypeInjectableProviderqueryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{>cookieParams}},{{/parameters}}@Context SecurityContext securityContext) throws NotFoundException { - return delegate.{{nickname}}({{#parameters}}{{paramName}},{{/parameters}}securityContext); + return delegate.{{nickname}}({{#parameters}}{{#isBinary}}{{#isBodyParam}}{{paramName}}{{/isBodyParam}}{{^isBodyParam}}{{paramName}}InputStream, {{paramName}}Detail{{/isBodyParam}}{{/isBinary}}{{^isBinary}}{{paramName}}{{/isBinary}},{{/parameters}}securityContext); } {{/@first}} {{/contents}} diff --git a/src/main/resources/handlebars/JavaJaxRS/apiService.mustache b/src/main/resources/handlebars/JavaJaxRS/apiService.mustache index 5bdc33e068..570856c13e 100644 --- a/src/main/resources/handlebars/JavaJaxRS/apiService.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/apiService.mustache @@ -14,10 +14,21 @@ import {{package}}.NotFoundException; import java.io.InputStream; +{{#jakarta}} +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; +{{/jakarta}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{>generatedAnnotation}} {{#operations}} diff --git a/src/main/resources/handlebars/JavaJaxRS/apiServiceImpl.mustache b/src/main/resources/handlebars/JavaJaxRS/apiServiceImpl.mustache index 7c9bc7c412..87e10cc7e0 100644 --- a/src/main/resources/handlebars/JavaJaxRS/apiServiceImpl.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/apiServiceImpl.mustache @@ -14,10 +14,21 @@ import java.io.InputStream; import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +{{#jakarta}} +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; +{{/jakarta}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{>generatedAnnotation}} {{#operations}} diff --git a/src/main/resources/handlebars/JavaJaxRS/bootstrap.mustache b/src/main/resources/handlebars/JavaJaxRS/bootstrap.mustache index 433c0389c3..72f020fcc6 100644 --- a/src/main/resources/handlebars/JavaJaxRS/bootstrap.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/bootstrap.mustache @@ -1,9 +1,17 @@ package {{apiPackage}}; +{{#jakarta}} +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletException; +{{/jakarta}} +{{^jakarta}} import javax.servlet.http.HttpServlet; import javax.servlet.ServletContext; import javax.servlet.ServletConfig; import javax.servlet.ServletException; +{{/jakarta}} {{#useOas2}} import io.swagger.jaxrs.config.SwaggerContextService; @@ -52,4 +60,4 @@ import io.swagger.v3.oas.annotations.info.License; ) public class Bootstrap { } -{{/useOas2}} \ No newline at end of file +{{/useOas2}} diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/RestApplication.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/RestApplication.mustache index d3d8b238d7..722cb94e47 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/RestApplication.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/RestApplication.mustache @@ -1,9 +1,15 @@ package {{invokerPackage}}; +{{#jakarta}} +import jakarta.ws.rs.ApplicationPath; +import jakarta.ws.rs.core.Application; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; +{{/jakarta}} @ApplicationPath("/") public class RestApplication extends Application { // Add implementation-specific details here -} \ No newline at end of file +} diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/api.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/api.mustache index 0cb1b1445f..41780bfce4 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/api.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/api.mustache @@ -4,12 +4,22 @@ package {{package}}; {{/imports}} import {{package}}.{{classname}}Service; +{{#jakarta}} +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.*; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; +{{/jakarta}} {{#useOas2}} import io.swagger.annotations.*; @@ -32,7 +42,12 @@ import org.apache.cxf.jaxrs.ext.multipart.Multipart; import java.util.Map; import java.util.List; {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} @Path("/{{{baseName}}}") @RequestScoped diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/apiService.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/apiService.mustache index d75faaca09..7055bc34d6 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/apiService.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/apiService.mustache @@ -13,8 +13,14 @@ import java.util.List; import java.io.InputStream; +{{#jakarta}} +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; +{{/jakarta}} {{>generatedAnnotation}} {{#operations}} diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/apiServiceImpl.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/apiServiceImpl.mustache index b0af063d33..812338de91 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/apiServiceImpl.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/apiServiceImpl.mustache @@ -12,9 +12,16 @@ import java.util.List; import java.io.InputStream; +{{#jakarta}} +import jakarta.enterprise.context.RequestScoped; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +{{/jakarta}} +{{^jakarta}} import javax.enterprise.context.RequestScoped; import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; +{{/jakarta}} @RequestScoped {{>generatedAnnotation}} diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/generatedAnnotation.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/generatedAnnotation.mustache index a47b6faa85..c6c0883bcb 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/generatedAnnotation.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/generatedAnnotation.mustache @@ -1 +1 @@ -{{^hideGenerationTimestamp}}@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} \ No newline at end of file +{{^hideGenerationTimestamp}}@{{#jakarta}}jakarta{{/jakarta}}{{^jakarta}}javax{{/jakarta}}.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/interface.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/interface.mustache index becc0c5549..abec32f768 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/interface.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/interface.mustache @@ -3,4 +3,9 @@ */ public interface {{{classname}}} { +{{#vendorExtensions}} +{{#x-discriminator-type-getter}} + {{x-discriminator-type}} {{x-discriminator-type-getter}}(); +{{/x-discriminator-type-getter}} +{{/vendorExtensions}} } diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/model.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/model.mustache index abbe476515..5edf75f7d8 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/model.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/model.mustache @@ -4,7 +4,12 @@ package {{package}}; {{#imports}}import {{import}}; {{/imports}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{/x-is-composed-model}} {{#models}} diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/pojo.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/pojo.mustache index 78b3ec8ca0..d8cc0f03f1 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/pojo.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/pojo.mustache @@ -6,7 +6,12 @@ import io.swagger.v3.oas.annotations.media.Schema; {{/useOas2}} import java.util.Objects; +{{#jakarta}} +import jakarta.xml.bind.annotation.*; +{{/jakarta}} +{{^jakarta}} import javax.xml.bind.annotation.*; +{{/jakarta}} {{#description}}{{#useOas2}}@ApiModel{{/useOas2}}{{^useOas2}}@Schema{{/useOas2}}(description = "{{{description}}}"){{/description}} diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/pom.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/pom.mustache index 070c9f7c2b..fe70e414b4 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/pom.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf-cdi/pom.mustache @@ -46,12 +46,22 @@ + {{#jakarta}} + + jakarta.platform + jakarta.jakartaee-api + 10.0.0 + provided + + {{/jakarta}} + {{^jakarta}} javax javaee-api 7.0 provided + {{/jakarta}} @@ -59,7 +69,7 @@ cxf-rt-frontend-jaxrs - 3.0.2 + {{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}3.5.5{{/jakarta}} provided @@ -88,14 +98,31 @@ {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + {{/jakarta}} + {{^jakarta}} javax.validation validation-api 1.1.0.Final provided + {{/jakarta}} {{/useBeanValidation}} + {{#java11}} + + 11 + 11 + + {{/java11}} + diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/CXF2InterfaceComparator.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/CXF2InterfaceComparator.mustache index d1fd0bf82c..8e4f060577 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf/CXF2InterfaceComparator.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/CXF2InterfaceComparator.mustache @@ -5,8 +5,26 @@ import java.lang.reflect.Method; import java.util.regex.Matcher; import java.util.regex.Pattern; +{{#jakarta}} +import jakarta.ws.rs.DELETE; +import jakarta.ws.rs.HEAD; +import jakarta.ws.rs.HttpMethod; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.OPTIONS; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.PUT; +{{/jakarta}} +{{^jakarta}} +import javax.ws.rs.DELETE; +import javax.ws.rs.HEAD; import javax.ws.rs.HttpMethod; +import javax.ws.rs.GET; +import javax.ws.rs.OPTIONS; import javax.ws.rs.Path; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +{{/jakarta}} import org.apache.cxf.jaxrs.ext.ResourceComparator; import org.apache.cxf.jaxrs.model.ClassResourceInfo; @@ -60,7 +78,7 @@ public class CXFInterfaceComparator implements ResourceComparator { Method[] methods = cri.getServiceClass().getInterfaces()[0].getMethods(); // Java reflexion. Check all the methods of an interface. for (Method method : methods) { - Path pathAnnotation = method.getAnnotation(javax.ws.rs.Path.class); + Path pathAnnotation = method.getAnnotation(Path.class); if (pathAnnotation != null && pathAnnotation.value() != null) { String pathValue = pathAnnotation.value(); String methodHttpVerb = getMethodHttpVerb(method); @@ -79,17 +97,17 @@ public class CXFInterfaceComparator implements ResourceComparator { } private static String getMethodHttpVerb(Method method) { - if (method.getAnnotation(javax.ws.rs.POST.class) != null) { + if (method.getAnnotation(POST.class) != null) { return HttpMethod.POST; - } else if (method.getAnnotation(javax.ws.rs.GET.class) != null) { + } else if (method.getAnnotation(GET.class) != null) { return HttpMethod.GET; - } else if (method.getAnnotation(javax.ws.rs.PUT.class) != null) { + } else if (method.getAnnotation(PUT.class) != null) { return HttpMethod.PUT; - } else if (method.getAnnotation(javax.ws.rs.OPTIONS.class) != null) { + } else if (method.getAnnotation(OPTIONS.class) != null) { return HttpMethod.OPTIONS; - } else if (method.getAnnotation(javax.ws.rs.DELETE.class) != null) { + } else if (method.getAnnotation(DELETE.class) != null) { return HttpMethod.DELETE; - } else if (method.getAnnotation(javax.ws.rs.HEAD.class) != null) { + } else if (method.getAnnotation(HEAD.class) != null) { return HttpMethod.HEAD; } assert false; @@ -117,4 +135,4 @@ public class CXFInterfaceComparator implements ResourceComparator { public int compare(OperationResourceInfo ori1, OperationResourceInfo ori2, Message message) { return 0; // Leave CXF decision } -} \ No newline at end of file +} diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/api.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/api.mustache index e9cf1dc7e4..c2d3005aa9 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf/api.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/api.mustache @@ -7,9 +7,16 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.List; import java.util.Map; +{{#jakarta}} +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.MediaType; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.*; import javax.ws.rs.core.Response; import javax.ws.rs.core.MediaType; +{{/jakarta}} import org.apache.cxf.jaxrs.ext.multipart.*; {{#useOas2}} @@ -28,8 +35,14 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; {{/useOas2}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +import jakarta.validation.Valid; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; import javax.validation.Valid; +{{/jakarta}} {{/useBeanValidation}} {{#appName}} @@ -83,7 +96,7 @@ public interface {{classname}} { @ApiResponses(value = { {{#responses}} @ApiResponse(responseCode = "{{{code}}}", description = "{{{message}}}"{{^vendorExtensions.x-java-is-response-void}}, content = @Content({{#schema.extensions.x-content-type}}mediaType = "{{schema.extensions.x-content-type}}", {{/schema.extensions.x-content-type}}{{^containerType}}schema = @Schema(implementation = {{{baseType}}}.class)){{/containerType}}{{#containerType}}array = @ArraySchema(schema = @Schema(implementation = {{{baseType}}}.class))){{/containerType}}{{/vendorExtensions.x-java-is-response-void}}){{#hasMore}},{{/hasMore}}{{/responses}} }) {{/useOas2}} - public {{>returnTypes}} {{nickname}}({{#parameters}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}}, {{/hasMore}}{{/parameters}}); + public {{>returnTypes}} {{nickname}}({{#parameters}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>cookieParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}}, {{/hasMore}}{{/parameters}}); {{/contents}} {{/operation}} } diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/apiServiceImpl.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/apiServiceImpl.mustache index 82ebd6da18..7e54832af9 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf/apiServiceImpl.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/apiServiceImpl.mustache @@ -8,8 +8,14 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.List; import java.util.Map; +{{#jakarta}} +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.Response; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.*; import javax.ws.rs.core.Response; +{{/jakarta}} import org.apache.cxf.jaxrs.model.wadl.Description; import org.apache.cxf.jaxrs.model.wadl.DocTarget; @@ -48,7 +54,7 @@ public class {{classname}}ServiceImpl implements {{classname}} { {{/notes}} */ {{/summary}} - public {{>returnTypes}} {{nickname}}({{#parameters}}{{>queryParamsImpl}}{{>pathParamsImpl}}{{>headerParamsImpl}}{{>bodyParamsImpl}}{{>formParamsImpl}}{{#hasMore}}, {{/hasMore}}{{/parameters}}) { + public {{>returnTypes}} {{nickname}}({{#parameters}}{{>queryParamsImpl}}{{>pathParamsImpl}}{{>headerParamsImpl}}{{>cookieParamsImpl}}{{>bodyParamsImpl}}{{>formParamsImpl}}{{#hasMore}}, {{/hasMore}}{{/parameters}}) { // TODO: Implement... {{#useGenericResponse}}return Response.ok().entity("magic!").build();{{/useGenericResponse}}{{^useGenericResponse}}{{^vendorExtensions.x-java-is-response-void}}return null;{{/vendorExtensions.x-java-is-response-void}}{{/useGenericResponse}} diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/api_test.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/api_test.mustache index e265b96996..b1b6bbacac 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf/api_test.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/api_test.mustache @@ -8,7 +8,12 @@ import org.junit.Test; import org.junit.Before; import static org.junit.Assert.*; +{{#jakarta}} +import jakarta.ws.rs.core.Response; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.Response; +{{/jakarta}} import org.apache.cxf.jaxrs.client.JAXRSClientFactory; import org.apache.cxf.jaxrs.client.ClientConfiguration; import org.apache.cxf.jaxrs.client.WebClient; diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/cookieParams.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/cookieParams.mustache new file mode 100644 index 0000000000..4af2e57d24 --- /dev/null +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/cookieParams.mustache @@ -0,0 +1 @@ +{{#isCookieParam}}@CookieParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/isCookieParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/cookieParamsImpl.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/cookieParamsImpl.mustache new file mode 100644 index 0000000000..70871f0f8c --- /dev/null +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/cookieParamsImpl.mustache @@ -0,0 +1 @@ +{{#isCookieParam}}{{{dataType}}} {{paramName}}{{/isCookieParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/enumOuterClass.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/enumOuterClass.mustache index 491a199e09..5973e0434e 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf/enumOuterClass.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/enumOuterClass.mustache @@ -3,9 +3,16 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; {{/jackson}} {{#withXml}} +{{#jakarta}} +import jakarta.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.XmlEnum; +import jakarta.xml.bind.annotation.XmlEnumValue; +{{/jakarta}} +{{^jakarta}} import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlEnum; import javax.xml.bind.annotation.XmlEnumValue; +{{/jakarta}} {{/withXml}} /** diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/generatedAnnotation.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/generatedAnnotation.mustache index 49110fc1ad..c6c0883bcb 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf/generatedAnnotation.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/generatedAnnotation.mustache @@ -1 +1 @@ -@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}") \ No newline at end of file +{{^hideGenerationTimestamp}}@{{#jakarta}}jakarta{{/jakarta}}{{^jakarta}}javax{{/jakarta}}.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/interface.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/interface.mustache index becc0c5549..abec32f768 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf/interface.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/interface.mustache @@ -3,4 +3,9 @@ */ public interface {{{classname}}} { +{{#vendorExtensions}} +{{#x-discriminator-type-getter}} + {{x-discriminator-type}} {{x-discriminator-type-getter}}(); +{{/x-discriminator-type-getter}} +{{/vendorExtensions}} } diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/model.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/model.mustache index fe9f571dd2..8642b990ba 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf/model.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/model.mustache @@ -4,7 +4,12 @@ package {{package}}; {{#imports}}import {{import}}; {{/imports}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{/isComposedModel}} diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/modelInnerEnum.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/modelInnerEnum.mustache index bd397a1208..384db158f5 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf/modelInnerEnum.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/modelInnerEnum.mustache @@ -1,6 +1,13 @@ + {{#withXml}} + @XmlType(name="{{datatypeWithEnum}}") + @XmlEnum({{datatypeWithEnum}}.class) + {{/withXml}} public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}} {{#enumVars}} + {{#withXml}} + @XmlEnumValue({{#value}}{{{value}}}{{/value}}{{^value}}""{{/value}}) + {{/withXml}} {{{name}}}({{#value}}{{{value}}}{{/value}}{{^value}}null{{/value}}){{^@last}},{{/@last}}{{#@last}};{{/@last}} {{/enumVars}} {{/allowableValues}} diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/pojo.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/pojo.mustache index 6c8429248f..656f475a03 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf/pojo.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/pojo.mustache @@ -4,6 +4,16 @@ import io.swagger.annotations.ApiModelProperty; {{^useOas2}} import io.swagger.v3.oas.annotations.media.Schema; {{/useOas2}} +{{#jakarta}} +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.XmlEnum; +import jakarta.xml.bind.annotation.XmlEnumValue; +{{/jakarta}} +{{^jakarta}} import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlAccessType; @@ -11,6 +21,7 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlEnum; import javax.xml.bind.annotation.XmlEnumValue; +{{/jakarta}} import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/pom.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/pom.mustache index 0a91a003b2..d4cf5679d9 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf/pom.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/pom.mustache @@ -41,11 +41,22 @@ {{#useBeanValidation}} + {{#jakarta}} - javax.validation - validation-api - ${beanvalidation-version} + jakarta.validation + jakarta.validation-api + ${beanvalidation-version} + provided + {{/jakarta}} + {{^jakarta}} + + javax.validation + validation-api + ${beanvalidation-version} + provided + + {{/jakarta}} {{/useBeanValidation}} @@ -127,12 +138,22 @@ {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + ${beanvalidation-version} + provided + + {{/jakarta}} + {{^jakarta}} javax.validation validation-api ${beanvalidation-version} provided + {{/jakarta}} {{/useBeanValidation}} @@ -141,7 +162,7 @@ ${cxf-version} test - + org.apache.cxf @@ -187,13 +208,31 @@ ${jackson-jaxrs-version} {{/java8}} -{{#useBeanValidationFeature}} +{{#useBeanValidationFeature}} org.hibernate hibernate-validator - 5.2.2.Final + {{#jakarta}}8.0.0.Final{{/jakarta}}{{^jakarta}}5.2.2.Final{{/jakarta}} {{/useBeanValidationFeature}} + {{#jakarta}} + + jakarta.xml.bind + jakarta.xml.bind-api + 4.0.0 + + + com.sun.xml.bind + jaxb-impl + 4.0.1 + + + jakarta.activation + jakarta.activation-api + 2.1.0 + + {{/jakarta}} + {{^jakarta}} javax.xml.bind jaxb-api @@ -204,6 +243,7 @@ activation 1.1.1 + {{/jakarta}} @@ -215,7 +255,7 @@ - {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} ${java.version} ${java.version} {{#useOas2}} @@ -226,12 +266,12 @@ {{/useOas2}} 9.2.9.v20150224 4.13.1 - 1.1.7 + 1.4.14 2.5 {{#useBeanValidation}} - 1.1.0.Final + {{#jakarta}}3.0.2{{/jakarta}}{{^jakarta}}1.1.0.Final{{/jakarta}} {{/useBeanValidation}} - 3.2.4 + {{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}3.2.4{{/jakarta}} 2.9.1 UTF-8 diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/server/ApplicationContext.xml.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/server/ApplicationContext.xml.mustache index fd1b6d6f8f..1fa7aea495 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf/server/ApplicationContext.xml.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/server/ApplicationContext.xml.mustache @@ -84,7 +84,7 @@ {{/useGzipFeature}} - + diff --git a/src/main/resources/handlebars/JavaJaxRS/cxf/server/pom.mustache b/src/main/resources/handlebars/JavaJaxRS/cxf/server/pom.mustache index 467e58218d..e020f78165 100644 --- a/src/main/resources/handlebars/JavaJaxRS/cxf/server/pom.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/cxf/server/pom.mustache @@ -41,11 +41,20 @@ {{#useBeanValidation}} + {{#jakarta}} - javax.validation - validation-api - ${beanvalidation-version} + jakarta.validation + jakarta.validation-api + ${beanvalidation-version} + {{/jakarta}} + {{^jakarta}} + + javax.validation + validation-api + ${beanvalidation-version} + + {{/jakarta}} {{/useBeanValidation}} @@ -88,7 +97,7 @@ - + maven-war-plugin @@ -136,12 +145,22 @@ {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + ${beanvalidation-version} + provided + + {{/jakarta}} + {{^jakarta}} javax.validation validation-api ${beanvalidation-version} provided + {{/jakarta}} {{/useBeanValidation}} @@ -150,7 +169,7 @@ ${cxf-version} test - + org.apache.cxf @@ -212,7 +231,7 @@ ${jackson-jaxrs-version} {{/java8}} -{{#generateSpringApplication}} +{{#generateSpringApplication}} org.springframework @@ -223,7 +242,7 @@ org.springframework spring-web ${spring-version} - + {{/generateSpringApplication}} {{#generateSpringBootApplication}} @@ -240,7 +259,7 @@ ${spring.boot-version} test - + org.apache.cxf cxf-spring-boot-starter-jaxrs @@ -255,16 +274,35 @@ 3.6.1 {{/useSwaggerUI}} + {{#jakarta}} + + jakarta.xml.bind + jakarta.xml.bind-api + 4.0.0 + - javax.xml.bind - jaxb-api - 2.2.6 + com.sun.xml.bind + jaxb-impl + 4.0.1 - javax.activation - activation - 1.1.1 + jakarta.activation + jakarta.activation-api + 2.1.0 + {{/jakarta}} + {{^jakarta}} + + javax.xml.bind + jaxb-api + 2.2.6 + + + javax.activation + activation + 1.1.1 + + {{/jakarta}} @@ -276,7 +314,7 @@ - {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} ${java.version} ${java.version} {{#useOas2}} @@ -287,18 +325,18 @@ {{/useOas2}} 9.2.9.v20150224 4.13.1 - 1.1.7 + 1.4.14 2.5 {{#useBeanValidation}} - 1.1.0.Final + {{#jakarta}}3.0.2{{/jakarta}}{{^jakarta}}1.1.0.Final{{/jakarta}} {{/useBeanValidation}} -{{#generateSpringApplication}} +{{#generateSpringApplication}} 4.3.13.RELEASE -{{/generateSpringApplication}} +{{/generateSpringApplication}} {{#generateSpringBootApplication}} 1.5.9.RELEASE -{{/generateSpringBootApplication}} - 3.2.4 +{{/generateSpringBootApplication}} + {{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}3.2.4{{/jakarta}} 2.9.1 UTF-8 diff --git a/src/main/resources/handlebars/JavaJaxRS/di/api.mustache b/src/main/resources/handlebars/JavaJaxRS/di/api.mustache index fae82cbd69..6c79865b54 100644 --- a/src/main/resources/handlebars/JavaJaxRS/di/api.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/di/api.mustache @@ -29,12 +29,25 @@ import java.io.InputStream; import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataParam; +{{#jakarta}} +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +import jakarta.ws.rs.*; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; import javax.ws.rs.*; +{{/jakarta}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} @Path("/{{{baseName}}}") @@ -52,7 +65,7 @@ public class {{classname}} { protected {{classname}}() { } - @javax.inject.Inject + @{{#jakarta}}jakarta{{/jakarta}}{{^jakarta}}javax{{/jakarta}}.inject.Inject public {{classname}}({{classname}}Service delegate) { this.delegate = delegate; } diff --git a/src/main/resources/handlebars/JavaJaxRS/di/apiService.mustache b/src/main/resources/handlebars/JavaJaxRS/di/apiService.mustache index 56092f5e7c..414550b752 100644 --- a/src/main/resources/handlebars/JavaJaxRS/di/apiService.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/di/apiService.mustache @@ -13,10 +13,21 @@ import java.util.List; import java.io.InputStream; +{{#jakarta}} +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; +{{/jakarta}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{>generatedAnnotation}} {{#operations}} diff --git a/src/main/resources/handlebars/JavaJaxRS/formParams.mustache b/src/main/resources/handlebars/JavaJaxRS/formParams.mustache index 96e8a148e0..5bd5a1cf3f 100644 --- a/src/main/resources/handlebars/JavaJaxRS/formParams.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/formParams.mustache @@ -1,2 +1 @@ -{{#is this 'form-param'}}{{#isNot this 'binary'}}{{#useOas2}}@ApiParam(value = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}){{#vendorExtensions.x-multipart}}@FormDataParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/vendorExtensions.x-multipart}}{{^vendorExtensions.x-multipart}} {{#defaultValue}} @DefaultValue("{{{defaultValue}}}"){{/defaultValue}} @FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/vendorExtensions.x-multipart}}{{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}){{#vendorExtensions.x-multipart}}@FormDataParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/vendorExtensions.x-multipart}}{{^vendorExtensions.x-multipart}} {{#defaultValue}} @DefaultValue("{{{defaultValue}}}"){{/defaultValue}} @FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/vendorExtensions.x-multipart}}{{/useOas2}}{{/isNot}}{{#is this 'binary'}}@FormDataParam("{{baseName}}") InputStream {{paramName}}InputStream, - @FormDataParam("{{baseName}}") FormDataContentDisposition {{paramName}}Detail{{/is}}{{/is}} +{{#isFormParam}}{{^isBinary}}{{#useOas2}}@ApiParam(value = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}){{#vendorExtensions.x-multipart}}@FormDataParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/vendorExtensions.x-multipart}}{{^vendorExtensions.x-multipart}} {{#defaultValue}} @DefaultValue("{{{defaultValue}}}"){{/defaultValue}} @FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/vendorExtensions.x-multipart}}{{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}){{#vendorExtensions.x-multipart}}@FormDataParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/vendorExtensions.x-multipart}}{{^vendorExtensions.x-multipart}} {{#defaultValue}} @DefaultValue("{{{defaultValue}}}"){{/defaultValue}} @FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/vendorExtensions.x-multipart}}{{/useOas2}}{{/isBinary}}{{#isBinary}}@FormDataParam("{{baseName}}") InputStream {{paramName}}InputStream, @FormDataParam("{{baseName}}") FormDataContentDisposition {{paramName}}Detail{{/isBinary}}{{/isFormParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/generatedAnnotation.mustache b/src/main/resources/handlebars/JavaJaxRS/generatedAnnotation.mustache index a47b6faa85..c6c0883bcb 100644 --- a/src/main/resources/handlebars/JavaJaxRS/generatedAnnotation.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/generatedAnnotation.mustache @@ -1 +1 @@ -{{^hideGenerationTimestamp}}@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} \ No newline at end of file +{{^hideGenerationTimestamp}}@{{#jakarta}}jakarta{{/jakarta}}{{^jakarta}}javax{{/jakarta}}.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} diff --git a/src/main/resources/handlebars/JavaJaxRS/interface.mustache b/src/main/resources/handlebars/JavaJaxRS/interface.mustache index becc0c5549..abec32f768 100644 --- a/src/main/resources/handlebars/JavaJaxRS/interface.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/interface.mustache @@ -3,4 +3,9 @@ */ public interface {{{classname}}} { +{{#vendorExtensions}} +{{#x-discriminator-type-getter}} + {{x-discriminator-type}} {{x-discriminator-type-getter}}(); +{{/x-discriminator-type-getter}} +{{/vendorExtensions}} } diff --git a/src/main/resources/handlebars/JavaJaxRS/jacksonJsonProvider.mustache b/src/main/resources/handlebars/JavaJaxRS/jacksonJsonProvider.mustache index 5fa284e809..132341ff36 100644 --- a/src/main/resources/handlebars/JavaJaxRS/jacksonJsonProvider.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/jacksonJsonProvider.mustache @@ -13,9 +13,16 @@ import com.fasterxml.jackson.datatype.joda.*; import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; +{{#jakarta}} +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.ext.Provider; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.ext.Provider; +{{/jakarta}} @Provider @Produces({MediaType.APPLICATION_JSON}) @@ -36,4 +43,4 @@ public class JacksonJsonProvider extends JacksonJaxbJsonProvider { setMapper(objectMapper); } -} \ No newline at end of file +} diff --git a/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/LocalDateProvider.mustache b/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/LocalDateProvider.mustache index 8c4cd4cbd1..a264da486f 100644 --- a/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/LocalDateProvider.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/LocalDateProvider.mustache @@ -4,6 +4,16 @@ import com.sun.jersey.core.spi.component.ComponentContext; import com.sun.jersey.spi.inject.Injectable; import com.sun.jersey.spi.inject.PerRequestTypeInjectableProvider; +{{#jakarta}} +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; +import jakarta.ws.rs.core.UriInfo; +import jakarta.ws.rs.ext.Provider; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; @@ -11,6 +21,7 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; import javax.ws.rs.ext.Provider; +{{/jakarta}} import java.time.LocalDate; import java.util.List; @@ -41,4 +52,4 @@ public class LocalDateProvider extends PerRequestTypeInjectableProviderqueryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}, + {{#parameters}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{>serviceCookieParams}}, {{/parameters}}@Context SecurityContext securityContext) throws NotFoundException { - return delegate.{{nickname}}({{#parameters}}{{#isBinary}} {{paramName}}InputStream, {{paramName}}Detail{{/isBinary}}{{^isBinary}}{{paramName}}{{/isBinary}},{{/parameters}}securityContext); + return delegate.{{nickname}}({{#parameters}}{{#isBinary}}{{#isBodyParam}}{{paramName}}{{/isBodyParam}}{{^isBodyParam}}{{paramName}}InputStream, {{paramName}}Detail{{/isBodyParam}}{{/isBinary}}{{^isBinary}}{{paramName}}{{/isBinary}},{{/parameters}}securityContext); } {{/contents}} {{/operation}} diff --git a/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/apiService.mustache b/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/apiService.mustache index 06d2d6a051..6b18780d60 100644 --- a/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/apiService.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/apiService.mustache @@ -17,17 +17,28 @@ import java.io.InputStream; import com.sun.jersey.core.header.FormDataContentDisposition; import com.sun.jersey.multipart.FormDataParam; +{{#jakarta}} +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; +{{/jakarta}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{>generatedAnnotation}} {{#operations}} public abstract class {{classname}}Service { {{#operation}} {{#contents}} - public abstract Response {{nickname}}({{#parameters}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{>serviceFormParams}},{{/parameters}}SecurityContext securityContext) + public abstract Response {{nickname}}({{#parameters}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{>serviceFormParams}}{{>serviceCookieParams}},{{/parameters}}SecurityContext securityContext) throws NotFoundException; {{/contents}} {{/operation}} diff --git a/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/apiServiceImpl.mustache b/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/apiServiceImpl.mustache index d22f98fb8c..ee19b24d80 100644 --- a/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/apiServiceImpl.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/apiServiceImpl.mustache @@ -17,10 +17,21 @@ import java.io.InputStream; import com.sun.jersey.core.header.FormDataContentDisposition; import com.sun.jersey.multipart.FormDataParam; +{{#jakarta}} +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; +{{/jakarta}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{>generatedAnnotation}} {{#operations}} @@ -28,7 +39,7 @@ public class {{classname}}ServiceImpl extends {{classname}}Service { {{#operation}} {{#contents}} @Override - public Response {{nickname}}({{#parameters}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{>serviceFormParams}}, {{/parameters}}SecurityContext securityContext) + public Response {{nickname}}({{#parameters}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{>serviceFormParams}}{{>serviceCookieParams}}, {{/parameters}}SecurityContext securityContext) throws NotFoundException { // do some magic! return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build(); diff --git a/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/formParams.mustache b/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/formParams.mustache index d9b7151f76..5bd5a1cf3f 100644 --- a/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/formParams.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/formParams.mustache @@ -1,2 +1 @@ -{{#is this 'form-param'}}{{#isNot this 'binary'}}{{#isNot this 'multipart'}}@ApiParam(value = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}){{/isNot}}{{#is this 'multipart'}}@FormDataParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/is}}{{#isNot this 'multipart'}} {{#defaultValue}} @DefaultValue("{{{defaultValue}}}"){{/defaultValue}} @FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/isNot}}{{/isNot}}{{#is this 'binary'}}@FormDataParam("{{baseName}}") InputStream inputStream, - @FormDataParam("{{baseName}}") FormDataContentDisposition fileDetail{{/is}}{{/is}} \ No newline at end of file +{{#isFormParam}}{{^isBinary}}{{#useOas2}}@ApiParam(value = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}){{#vendorExtensions.x-multipart}}@FormDataParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/vendorExtensions.x-multipart}}{{^vendorExtensions.x-multipart}} {{#defaultValue}} @DefaultValue("{{{defaultValue}}}"){{/defaultValue}} @FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/vendorExtensions.x-multipart}}{{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}){{#vendorExtensions.x-multipart}}@FormDataParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/vendorExtensions.x-multipart}}{{^vendorExtensions.x-multipart}} {{#defaultValue}} @DefaultValue("{{{defaultValue}}}"){{/defaultValue}} @FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/vendorExtensions.x-multipart}}{{/useOas2}}{{/isBinary}}{{#isBinary}}@FormDataParam("{{baseName}}") InputStream {{paramName}}InputStream, @FormDataParam("{{baseName}}") FormDataContentDisposition {{paramName}}Detail{{/isBinary}}{{/isFormParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/pom.mustache b/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/pom.mustache index 6936dc4a31..0ab2bef863 100644 --- a/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/pom.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/libraries/jersey1/pom.mustache @@ -44,11 +44,20 @@ {{#useBeanValidation}} + {{#jakarta}} - javax.validation - validation-api - ${beanvalidation-version} + jakarta.validation + jakarta.validation-api + ${beanvalidation-version} + {{/jakarta}} + {{^jakarta}} + + javax.validation + validation-api + ${beanvalidation-version} + + {{/jakarta}} {{/useBeanValidation}} @@ -129,11 +138,27 @@ jersey-server ${jersey-version} + {{#jakarta}} + + jakarta.servlet + jakarta.servlet-api + ${servlet-api-version} + + + + jakarta.platform + jakarta.jakartaee-api + 10.0.0 + provided + + {{/jakarta}} + {{^jakarta}} javax.servlet servlet-api ${servlet-api-version} + {{/jakarta}} junit @@ -179,13 +204,37 @@ {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + ${beanvalidation-version} + provided + + {{/jakarta}} + {{^jakarta}} javax.validation validation-api ${beanvalidation-version} provided -{{/useBeanValidation}} + {{/jakarta}} +{{/useBeanValidation}} + {{#java8}} + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson-version} + + {{/java8}} + {{^java8}} + + com.fasterxml.jackson.datatype + jackson-datatype-joda + ${jackson-version} + + {{/java8}} @@ -197,18 +246,18 @@ - {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} ${java.version} ${java.version} 1.5.18 9.2.9.v20150224 1.19.1 - 2.8.9 + 2.9.5 1.7.21 4.13.1 - 2.5 + {{#jakarta}}6.0.0{{/jakarta}}{{^jakarta}}2.5{{/jakarta}} {{#useBeanValidation}} - 1.1.0.Final + {{#jakarta}}3.0.2{{/jakarta}}{{^jakarta}}1.1.0.Final{{/jakarta}} {{/useBeanValidation}} UTF-8 diff --git a/src/main/resources/handlebars/JavaJaxRS/libraries/jersey2/LocalDateProvider.mustache b/src/main/resources/handlebars/JavaJaxRS/libraries/jersey2/LocalDateProvider.mustache index 90a5fb6208..45a30ffee6 100644 --- a/src/main/resources/handlebars/JavaJaxRS/libraries/jersey2/LocalDateProvider.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/libraries/jersey2/LocalDateProvider.mustache @@ -1,8 +1,15 @@ package {{apiPackage}}; +{{#jakarta}} +import jakarta.ws.rs.ext.ParamConverter; +import jakarta.ws.rs.ext.ParamConverterProvider; +import jakarta.ws.rs.ext.Provider; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.ext.ParamConverter; import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.Provider; +{{/jakarta}} import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.time.LocalDate; @@ -25,4 +32,4 @@ public class LocalDateProvider implements ParamConverterProvider { } return null; } -} \ No newline at end of file +} diff --git a/src/main/resources/handlebars/JavaJaxRS/libraries/jersey2/OffsetDateTimeProvider.mustache b/src/main/resources/handlebars/JavaJaxRS/libraries/jersey2/OffsetDateTimeProvider.mustache index fccb0deb16..6ab5876892 100644 --- a/src/main/resources/handlebars/JavaJaxRS/libraries/jersey2/OffsetDateTimeProvider.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/libraries/jersey2/OffsetDateTimeProvider.mustache @@ -1,8 +1,15 @@ package {{apiPackage}}; +{{#jakarta}} +import jakarta.ws.rs.ext.ParamConverter; +import jakarta.ws.rs.ext.ParamConverterProvider; +import jakarta.ws.rs.ext.Provider; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.ext.ParamConverter; import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.Provider; +{{/jakarta}} import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.time.OffsetDateTime; @@ -25,4 +32,4 @@ public class OffsetDateTimeProvider implements ParamConverterProvider { } return null; } -} \ No newline at end of file +} diff --git a/src/main/resources/handlebars/JavaJaxRS/model.mustache b/src/main/resources/handlebars/JavaJaxRS/model.mustache index 833c4a9c04..36b27798e7 100644 --- a/src/main/resources/handlebars/JavaJaxRS/model.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/model.mustache @@ -15,8 +15,14 @@ import org.apache.commons.lang3.ObjectUtils; import java.io.Serializable; {{/serializableModel}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +import jakarta.validation.Valid; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; import javax.validation.Valid; +{{/jakarta}} {{/useBeanValidation}} {{/x-is-composed-model}} diff --git a/src/main/resources/handlebars/JavaJaxRS/pojo.mustache b/src/main/resources/handlebars/JavaJaxRS/pojo.mustache index 72fa1edc33..68ebb507d0 100644 --- a/src/main/resources/handlebars/JavaJaxRS/pojo.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/pojo.mustache @@ -3,7 +3,7 @@ */{{#description}} {{#useOas2}}@ApiModel{{/useOas2}}{{^useOas2}}@Schema{{/useOas2}}(description = "{{{description}}}"){{/description}} {{>generatedAnnotation}} -public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#serializableModel}}implements Serializable {{#interfaceModels}}, {{classname}}{{^@last}}, {{/@last}}{{#@last}} {{/@last}}{{/interfaceModels}}{{/serializableModel}}{{^serializableModel}}{{#interfaceModels}}{{#@first}}implements {{/@first}}{{classname}}{{^@last}}, {{/@last}}{{#@last}} {{/@last}}{{/interfaceModels}}{{/serializableModel}} { +public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#serializableModel}}implements Serializable {{#interfaceModels}}{{#@first}},{{/@first}} {{classname}}{{^@last}}, {{/@last}}{{#@last}} {{/@last}}{{/interfaceModels}}{{/serializableModel}}{{^serializableModel}}{{#interfaceModels}}{{#@first}}implements {{/@first}}{{classname}}{{^@last}}, {{/@last}}{{#@last}} {{/@last}}{{/interfaceModels}}{{/serializableModel}} { {{#vars}} {{#baseItems this}} {{#is this 'enum'}} diff --git a/src/main/resources/handlebars/JavaJaxRS/pom.mustache b/src/main/resources/handlebars/JavaJaxRS/pom.mustache index a20ab5d228..90a69c9d61 100644 --- a/src/main/resources/handlebars/JavaJaxRS/pom.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/pom.mustache @@ -13,7 +13,7 @@ repo - + src/main/java @@ -53,11 +53,20 @@ {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + ${beanvalidation-version} + + {{/jakarta}} + {{^jakarta}} - javax.validation - validation-api - ${beanvalidation-version} + javax.validation + validation-api + ${beanvalidation-version} + {{/jakarta}} {{/useBeanValidation}} @@ -137,11 +146,27 @@ ${junit-version} test + {{#jakarta}} - javax.servlet - servlet-api - ${servlet-api-version} + jakarta.servlet + jakarta.servlet-api + ${servlet-api-version} + + + jakarta.platform + jakarta.jakartaee-api + 10.0.0 + provided + + {{/jakarta}} + {{^jakarta}} + + javax.servlet + servlet-api + ${servlet-api-version} + + {{/jakarta}} org.glassfish.jersey.containers jersey-container-servlet-core @@ -201,15 +226,30 @@ ${commons_io_version} {{/supportJava6}} - + {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + ${beanvalidation-version} + + + + jakarta.annotation + jakarta.annotation-api + 2.1.1 + + {{/jakarta}} + {{^jakarta}} javax.validation validation-api ${beanvalidation-version} - provided + {{/jakarta}} + {{/useBeanValidation}} @@ -223,7 +263,7 @@ - {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} ${java.version} ${java.version} {{#useOas2}} @@ -240,10 +280,10 @@ 3.5 {{/supportJava6}} 4.13.1 - 1.1.7 - 2.5 + 1.4.14 + {{#jakarta}}6.0.0{{/jakarta}}{{^jakarta}}2.5{{/jakarta}} {{#useBeanValidation}} - 1.1.0.Final + {{#jakarta}}3.0.2{{/jakarta}}{{^jakarta}}1.1.0.Final{{/jakarta}} {{/useBeanValidation}} UTF-8 diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/ApiOriginFilter.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/ApiOriginFilter.mustache index 090fd8cb55..f9ef60c3ee 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/ApiOriginFilter.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/ApiOriginFilter.mustache @@ -2,11 +2,17 @@ package {{apiPackage}}; import java.io.IOException; +{{#jakarta}} +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletResponse; +{{/jakarta}} +{{^jakarta}} import javax.servlet.*; import javax.servlet.http.HttpServletResponse; +{{/jakarta}} {{>generatedAnnotation}} -public class ApiOriginFilter implements javax.servlet.Filter { +public class ApiOriginFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse res = (HttpServletResponse) response; diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/ApiResponseMessage.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/ApiResponseMessage.mustache index f47a535094..5851bdd03f 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/ApiResponseMessage.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/ApiResponseMessage.mustache @@ -1,8 +1,15 @@ package {{apiPackage}}; +{{#jakarta}} +import jakarta.xml.bind.annotation.XmlTransient; + +@jakarta.xml.bind.annotation.XmlRootElement +{{/jakarta}} +{{^jakarta}} import javax.xml.bind.annotation.XmlTransient; @javax.xml.bind.annotation.XmlRootElement +{{/jakarta}} {{>generatedAnnotation}} public class ApiResponseMessage { public static final int ERROR = 1; diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/JacksonConfig.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/JacksonConfig.mustache index 1be7abd835..abcbaac4e3 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/JacksonConfig.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/JacksonConfig.mustache @@ -15,8 +15,14 @@ import org.joda.time.LocalDate; import org.joda.time.format.ISODateTimeFormat; {{/joda}} +{{#jakarta}} +import jakarta.ws.rs.ext.ContextResolver; +import jakarta.ws.rs.ext.Provider; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; +{{/jakarta}} import java.io.IOException; @Provider diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/JodaDateTimeProvider.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/JodaDateTimeProvider.mustache index 74c24c8777..b0a115a41f 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/JodaDateTimeProvider.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/JodaDateTimeProvider.mustache @@ -1,13 +1,22 @@ package {{apiPackage}}; import org.joda.time.DateTime; +{{#jakarta}} +import jakarta.ws.rs.ext.ParamConverter; +import jakarta.ws.rs.ext.ParamConverterProvider; +import jakarta.ws.rs.ext.Provider; +import jakarta.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.ext.ParamConverter; import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.Provider; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; +{{/jakarta}} +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; @Provider @@ -36,4 +45,4 @@ public class JodaDateTimeProvider implements ParamConverterProvider { } return null; } -} \ No newline at end of file +} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/JodaLocalDateProvider.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/JodaLocalDateProvider.mustache index 0b28c915dd..6d51e070a6 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/JodaLocalDateProvider.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/JodaLocalDateProvider.mustache @@ -1,13 +1,22 @@ package {{apiPackage}}; import org.joda.time.LocalDate; +{{#jakarta}} +import jakarta.ws.rs.ext.ParamConverter; +import jakarta.ws.rs.ext.ParamConverterProvider; +import jakarta.ws.rs.ext.Provider; +import jakarta.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.ext.ParamConverter; import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.Provider; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; +{{/jakarta}} +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; @Provider @@ -36,4 +45,4 @@ public class JodaLocalDateProvider implements ParamConverterProvider { } return null; } -} \ No newline at end of file +} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/LocalDateProvider.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/LocalDateProvider.mustache index a57e3e7475..86350d230e 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/LocalDateProvider.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/LocalDateProvider.mustache @@ -1,9 +1,16 @@ package {{apiPackage}}; import java.time.LocalDate; +{{#jakarta}} +import jakarta.ws.rs.ext.ParamConverter; +import jakarta.ws.rs.ext.ParamConverterProvider; +import jakarta.ws.rs.ext.Provider; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.ext.ParamConverter; import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.Provider; +{{/jakarta}} import java.lang.annotation.Annotation; import java.lang.reflect.Type; @@ -28,4 +35,4 @@ public class LocalDateProvider implements ParamConverterProvider { } return null; } -} \ No newline at end of file +} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/OffsetDateTimeProvider.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/OffsetDateTimeProvider.mustache index a3974c3c53..d3093bae45 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/OffsetDateTimeProvider.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/OffsetDateTimeProvider.mustache @@ -1,9 +1,16 @@ package {{apiPackage}}; import java.time.OffsetDateTime; +{{#jakarta}} +import jakarta.ws.rs.ext.ParamConverter; +import jakarta.ws.rs.ext.ParamConverterProvider; +import jakarta.ws.rs.ext.Provider; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.ext.ParamConverter; import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.Provider; +{{/jakarta}} import java.lang.annotation.Annotation; import java.lang.reflect.Type; @@ -28,4 +35,4 @@ public class OffsetDateTimeProvider implements ParamConverterProvider { } return null; } -} \ No newline at end of file +} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/RestApplication.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/RestApplication.mustache index df9a31434b..74127894d7 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/RestApplication.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/RestApplication.mustache @@ -1,9 +1,15 @@ package {{invokerPackage}}; +{{#jakarta}} +import jakarta.ws.rs.ApplicationPath; +import jakarta.ws.rs.core.Application; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; +{{/jakarta}} @ApplicationPath("/") public class RestApplication extends Application { -} \ No newline at end of file +} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/api.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/api.mustache index 57ebfa65d6..63df307143 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/api.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/api.mustache @@ -27,14 +27,28 @@ import {{package}}.NotFoundException; import java.io.InputStream; +{{#jakarta}} +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +import jakarta.ws.rs.*; +import jakarta.inject.Inject; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; import javax.ws.rs.*; import javax.inject.Inject; +{{/jakarta}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{#operations}} {{#operation}} @@ -86,9 +100,9 @@ public class {{classname}} { @ApiResponse(responseCode = "{{{code}}}", description = "{{{message}}}"{{^vendorExtensions.x-java-is-response-void}}, content = @Content({{#schema.extensions.x-content-type}}mediaType = "{{schema.extensions.x-content-type}}", {{/schema.extensions.x-content-type}}{{^containerType}}schema = @Schema(implementation = {{{baseType}}}.class)){{/containerType}}{{#containerType}}array = @ArraySchema(schema = @Schema(implementation = {{{baseType}}}.class))){{/containerType}}{{/vendorExtensions.x-java-is-response-void}}){{#hasMore}}, {{/hasMore}}{{/responses}} }) {{/useOas2}} - public Response {{nickname}}({{#isMultipart}}MultipartFormDataInput input,{{/isMultipart}}{{#parameters}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{^isMultipart}}{{>formParams}},{{/isMultipart}}{{#isMultipart}}{{^isFormParam}},{{/isFormParam}}{{/isMultipart}}{{/parameters}}@Context SecurityContext securityContext) + public Response {{nickname}}({{#isMultipart}}MultipartFormDataInput input,{{/isMultipart}}{{#parameters}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{>cookieParams}}{{>comma}}{{/parameters}}@Context SecurityContext securityContext) throws NotFoundException { - return service.{{nickname}}({{#isMultipart}}input,{{/isMultipart}}{{#parameters}}{{^isMultipart}}{{paramName}},{{/isMultipart}}{{#isMultipart}}{{^isFormParam}}{{paramName}},{{/isFormParam}}{{/isMultipart}}{{/parameters}}securityContext); + return service.{{nickname}}({{#isMultipart}}input,{{/isMultipart}}{{#parameters}}{{^isFormParam}}{{paramName}}{{/isFormParam}}{{#isFormParam}}{{^isBinary}}{{paramName}}{{/isBinary}}{{/isFormParam}}{{>comma}}{{/parameters}}securityContext); } {{/contents}} {{/operation}} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/apiService.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/apiService.mustache index 83741b6ec0..1fe2bf110c 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/apiService.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/apiService.mustache @@ -9,20 +9,26 @@ import {{package}}.*; {{/imports}} import java.util.List; +import java.util.Map; import {{package}}.NotFoundException; import java.io.InputStream; +{{#jakarta}} +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; +{{/jakarta}} {{>generatedAnnotation}} {{#operations}} public interface {{classname}}Service { {{#operation}} {{#contents}} - Response {{nickname}}({{#isMultipart}}MultipartFormDataInput input,{{/isMultipart}}{{#parameters}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{^isMultipart}}{{>serviceFormParams}},{{/isMultipart}}{{#isMultipart}}{{^isFormParam}},{{/isFormParam}}{{/isMultipart}}{{/parameters}}SecurityContext securityContext) - throws NotFoundException; + Response {{nickname}}({{#isMultipart}}MultipartFormDataInput input,{{/isMultipart}}{{#parameters}}{{>serviceQueryParams}}{{>serviceCookieParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{>serviceFormParams}}{{>comma}}{{/parameters}}SecurityContext securityContext) throws NotFoundException; {{/contents}} {{/operation}} } diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/apiServiceImpl.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/apiServiceImpl.mustache index aa22aae714..379ff2bf0e 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/apiServiceImpl.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/apiServiceImpl.mustache @@ -9,13 +9,21 @@ import {{package}}.*; {{/imports}} import java.util.List; +import java.util.Map; import {{package}}.NotFoundException; import java.io.InputStream; +{{#jakarta}} +import jakarta.enterprise.context.RequestScoped; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +{{/jakarta}} +{{^jakarta}} import javax.enterprise.context.RequestScoped; import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; +{{/jakarta}} @RequestScoped {{>generatedAnnotation}} @@ -23,7 +31,7 @@ import javax.ws.rs.core.SecurityContext; public class {{classname}}ServiceImpl implements {{classname}}Service { {{#operation}} {{#contents}} - public Response {{nickname}}({{#isMultipart}}MultipartFormDataInput input,{{/isMultipart}}{{#parameters}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{^isMultipart}}{{>serviceFormParams}},{{/isMultipart}}{{#isMultipart}}{{^isFormParam}},{{/isFormParam}}{{/isMultipart}}{{/parameters}}SecurityContext securityContext) + public Response {{nickname}}({{#isMultipart}}MultipartFormDataInput input,{{/isMultipart}}{{#parameters}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{>serviceFormParams}}{{>serviceCookieParams}}{{>comma}}{{/parameters}}SecurityContext securityContext) throws NotFoundException { // do some magic! return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build(); diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/bodyParams.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/bodyParams.mustache index 3d22f0b06b..9ad8f3307e 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/bodyParams.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/bodyParams.mustache @@ -1 +1,4 @@ -{{#is this 'body-param'}}{{#useOas2}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{{dataType}}} {{paramName}}{{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{{dataType}}} {{paramName}}{{/useOas2}}{{/is}} \ No newline at end of file +{{#is this 'body-param'}} +{{#useOas2}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{{dataType}}} {{paramName}}{{/useOas2}} +{{^useOas2}}@Parameter(description = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}) {{{dataType}}} {{paramName}}{{/useOas2}} +{{/is}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/comma.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/comma.mustache new file mode 100644 index 0000000000..5d8c1f9602 --- /dev/null +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/comma.mustache @@ -0,0 +1 @@ +{{^isFormParam}},{{/isFormParam}}{{#isFormParam}}{{^isBinary}},{{/isBinary}}{{/isFormParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/cookieParams.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/cookieParams.mustache new file mode 100644 index 0000000000..c8dae79c63 --- /dev/null +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/cookieParams.mustache @@ -0,0 +1,4 @@ +{{#isCookieParam}} +{{#useOas2}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{{dataType}}} {{paramName}}{{/useOas2}} +{{^useOas2}}@Parameter(description = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}) {{{dataType}}} {{paramName}}{{/useOas2}} +{{/isCookieParam}} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/JacksonConfig.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/JacksonConfig.mustache index 923d26477d..e2eda9dc19 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/JacksonConfig.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/JacksonConfig.mustache @@ -1,9 +1,17 @@ package {{invokerPackage}}; +{{#jakarta}} +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.ext.ContextResolver; +import jakarta.ws.rs.ext.Provider; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; +{{/jakarta}} import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,4 +49,4 @@ public class JacksonConfig implements ContextResolver { public ObjectMapper getContext(Class objectType) { return objectMapper; } -} \ No newline at end of file +} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/RestApplication.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/RestApplication.mustache index f208b4e4da..1ddfaf8946 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/RestApplication.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/RestApplication.mustache @@ -1,7 +1,17 @@ package {{invokerPackage}}; +{{#jakarta}} +import jakarta.ws.rs.ApplicationPath; +import jakarta.ws.rs.core.Application; +import jakarta.servlet.ServletConfig; +import jakarta.ws.rs.core.Context; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; +import javax.servlet.ServletConfig; +import javax.ws.rs.core.Context; +{{/jakarta}} import java.util.Set; import java.util.HashSet; @@ -10,7 +20,6 @@ import java.util.HashSet; import io.swagger.jaxrs.config.BeanConfig; {{/useOas2}} {{^useOas2}} -import javax.servlet.ServletConfig; import io.swagger.v3.jaxrs2.integration.JaxrsOpenApiContextBuilder; import io.swagger.v3.oas.integration.OpenApiConfigurationException; import io.swagger.v3.oas.integration.SwaggerConfiguration; @@ -18,7 +27,6 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; -import javax.ws.rs.core.Context; import java.util.stream.Collectors; import java.util.stream.Stream; {{/useOas2}} @@ -98,4 +106,4 @@ public class RestApplication extends Application { -} \ No newline at end of file +} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/api.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/api.mustache index 6785626684..a0a6c30bad 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/api.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/api.mustache @@ -25,12 +25,25 @@ import java.util.Map; import java.io.InputStream; +{{#jakarta}} +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +import jakarta.ws.rs.*; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; import javax.ws.rs.*; +{{/jakarta}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{#operations}} {{#operation}} @@ -80,7 +93,7 @@ public interface {{classname}} { @ApiResponse(responseCode = "{{{code}}}", description = "{{{message}}}"{{^vendorExtensions.x-java-is-response-void}}, content = @Content({{#schema.extensions.x-content-type}}mediaType = "{{schema.extensions.x-content-type}}", {{/schema.extensions.x-content-type}}{{^containerType}}schema = @Schema(implementation = {{{baseType}}}.class)){{/containerType}}{{#containerType}}array = @ArraySchema(schema = @Schema(implementation = {{{baseType}}}.class))){{/containerType}}{{/vendorExtensions.x-java-is-response-void}}){{#hasMore}},{{/hasMore}} {{/responses}} }) {{/useOas2}} - Response {{nickname}}({{#isMultipart}}MultipartFormDataInput input,{{/isMultipart}}{{#parameters}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{^isMultipart}}{{>formParams}},{{/isMultipart}}{{#isMultipart}}{{^isFormParam}},{{/isFormParam}}{{/isMultipart}}{{/parameters}}@Context SecurityContext securityContext); + Response {{nickname}}({{#isMultipart}}MultipartFormDataInput input,{{/isMultipart}}{{#parameters}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{>cookieParams}}{{>comma}}{{/parameters}}@Context SecurityContext securityContext); {{/contents}} {{/operation}} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/apiServiceImpl.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/apiServiceImpl.mustache index b37b1cf289..eeae9022e1 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/apiServiceImpl.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/apiServiceImpl.mustache @@ -9,18 +9,25 @@ import {{package}}.*; {{/imports}} import java.util.List; +import java.util.Map; import java.io.InputStream; +{{#jakarta}} +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; +{{/jakarta}} {{>generatedAnnotation}} {{#operations}} public class {{classname}}ServiceImpl implements {{classname}} { {{#operation}} {{#contents}} - public Response {{nickname}}({{#isMultipart}}MultipartFormDataInput input,{{/isMultipart}}{{#parameters}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{^isMultipart}}{{>serviceFormParams}},{{/isMultipart}}{{#isMultipart}}{{^isFormParam}},{{/isFormParam}}{{/isMultipart}}{{/parameters}}SecurityContext securityContext) { + public Response {{nickname}}({{#isMultipart}}MultipartFormDataInput input,{{/isMultipart}}{{#parameters}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{>serviceFormParams}}{{>serviceCookieParams}}{{>comma}}{{/parameters}}SecurityContext securityContext) { // do some magic! return Response.ok().build(); } diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/bodyParams.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/bodyParams.mustache index 3d22f0b06b..d9250c7e56 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/bodyParams.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/bodyParams.mustache @@ -1 +1 @@ -{{#is this 'body-param'}}{{#useOas2}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{{dataType}}} {{paramName}}{{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{{dataType}}} {{paramName}}{{/useOas2}}{{/is}} \ No newline at end of file +{{#is this 'body-param'}}{{#useOas2}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{{dataType}}} {{paramName}}{{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}) {{{dataType}}} {{paramName}}{{/useOas2}}{{/is}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/comma.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/comma.mustache new file mode 100644 index 0000000000..5d8c1f9602 --- /dev/null +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/comma.mustache @@ -0,0 +1 @@ +{{^isFormParam}},{{/isFormParam}}{{#isFormParam}}{{^isBinary}},{{/isBinary}}{{/isFormParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/cookieParams.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/cookieParams.mustache new file mode 100644 index 0000000000..c8dae79c63 --- /dev/null +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/cookieParams.mustache @@ -0,0 +1,4 @@ +{{#isCookieParam}} +{{#useOas2}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{{dataType}}} {{paramName}}{{/useOas2}} +{{^useOas2}}@Parameter(description = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}) {{{dataType}}} {{paramName}}{{/useOas2}} +{{/isCookieParam}} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/formParams.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/formParams.mustache index bca3affc3d..52ddceda5d 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/formParams.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/formParams.mustache @@ -1 +1 @@ -{{#is this 'form-param'}}{{#isNot this 'binary'}}{{#useOas2}}@ApiParam(value = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}})@FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}})@FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{/isNot}}{{/is}} \ No newline at end of file +{{#is this 'form-param'}}{{#isNot this 'binary'}}{{#useOas2}}@ApiParam(value = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}})@FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}})@FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{/isNot}}{{/is}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/generatedAnnotation.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/generatedAnnotation.mustache index a47b6faa85..c6c0883bcb 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/generatedAnnotation.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/generatedAnnotation.mustache @@ -1 +1 @@ -{{^hideGenerationTimestamp}}@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} \ No newline at end of file +{{^hideGenerationTimestamp}}@{{#jakarta}}jakarta{{/jakarta}}{{^jakarta}}javax{{/jakarta}}.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/gradle.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/gradle.mustache index 069226075d..672e74726f 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/gradle.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/gradle.mustache @@ -8,15 +8,15 @@ repositories { } dependencies { - providedCompile 'org.jboss.resteasy:resteasy-jaxrs:3.0.11.Final' - providedCompile 'org.jboss.resteasy:jaxrs-api:3.0.11.Final' - providedCompile 'org.jboss.resteasy:resteasy-validator-provider-11:3.0.11.Final' - providedCompile 'org.jboss.resteasy:resteasy-multipart-provider:3.0.11.Final' - providedCompile 'javax.annotation:javax.annotation-api:1.2' + providedCompile 'org.jboss.resteasy:resteasy-jaxrs:3.15.6.Final' + providedCompile 'org.jboss.resteasy:jaxrs-api:3.0.12.Final' + providedCompile 'org.jboss.resteasy:resteasy-validator-provider-11:3.6.3.Final' + providedCompile 'org.jboss.resteasy:resteasy-multipart-provider:3.15.6.Final' + providedCompile 'jakarta.annotation:jakarta.annotation-api:{{#jakarta}}2.1.1{{/jakarta}}{{^jakarta}}1.3.5{{/jakarta}}' providedCompile 'org.jboss.spec.javax.servlet:jboss-servlet-api_3.0_spec:1.0.0.Final' - compile 'org.jboss.resteasy:resteasy-jackson2-provider:3.0.11.Final' + compile 'org.jboss.resteasy:resteasy-jackson2-provider:3.15.6.Final' {{#useBeanValidation}} - providedCompile 'javax.validation:validation-api:1.1.0.Final' + providedCompile 'jakarta.validation:jakarta.validation-api:{{#jakarta}}3.0.2{{/jakarta}}{{^jakarta}}2.0.2{{/jakarta}}' {{/useBeanValidation}} {{^java8}} compile 'com.fasterxml.jackson.datatype:jackson-datatype-joda:2.10.1' @@ -25,6 +25,7 @@ dependencies { {{#java8}} compile 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.1' {{/java8}} + compile 'com.fasterxml.jackson.core:jackson-databind:2.10.1' testCompile 'junit:junit:4.12', 'org.hamcrest:hamcrest-core:1.3' } diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/headerParams.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/headerParams.mustache index 7b9d478841..2df32600fa 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/headerParams.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/headerParams.mustache @@ -1 +1 @@ -{{#is this 'header-param'}}{{#useOas2}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}})@HeaderParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}})@HeaderParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{/is}} \ No newline at end of file +{{#is this 'header-param'}}{{#useOas2}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}})@HeaderParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}})@HeaderParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{/is}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/interface.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/interface.mustache index becc0c5549..abec32f768 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/interface.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/interface.mustache @@ -3,4 +3,9 @@ */ public interface {{{classname}}} { +{{#vendorExtensions}} +{{#x-discriminator-type-getter}} + {{x-discriminator-type}} {{x-discriminator-type-getter}}(); +{{/x-discriminator-type-getter}} +{{/vendorExtensions}} } diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/model.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/model.mustache index 41abb664d0..8c70a27988 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/model.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/model.mustache @@ -3,13 +3,19 @@ package {{package}}; {{^x-is-composed-model}} import java.util.Objects; import java.util.ArrayList; +import java.util.HashMap; {{#imports}}import {{import}}; {{/imports}} {{#serializableModel}} import java.io.Serializable; {{/serializableModel}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{/x-is-composed-model}} {{#models}} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/pom.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/pom.mustache index 3d7a8bff75..0c755fa3e5 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/pom.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/pom.mustache @@ -14,8 +14,8 @@ maven-compiler-plugin 3.6.1 - {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} - {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} @@ -97,11 +97,20 @@ slf4j-log4j12 ${slf4j-version} + {{#jakarta}} + jakarta.servlet + jakarta.servlet-api + ${servlet-api-version} + + {{/jakarta}} + {{^jakarta}} + javax.servlet servlet-api ${servlet-api-version} + {{/jakarta}} org.jboss.resteasy @@ -111,17 +120,17 @@ org.jboss.resteasy resteasy-servlet-initializer - ${resteasy-version} + 6.2.3.Final org.jboss.resteasy jaxrs-api - ${resteasy-version} + 3.0.12.Final org.jboss.resteasy resteasy-validator-provider-11 - ${resteasy-version} + 3.6.3.Final org.jboss.resteasy @@ -133,11 +142,20 @@ resteasy-jackson2-provider ${resteasy-version} + {{#jakarta}} + + jakarta.annotation + jakarta.annotation-api + 2.1.1 + + {{/jakarta}} + {{^jakarta}} javax.annotation javax.annotation-api 1.2 + {{/jakarta}} {{#useOas2}} io.swagger @@ -180,11 +198,20 @@ {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + 3.0.2 + + {{/jakarta}} + {{^jakarta}} javax.validation validation-api 1.1.0.Final + {{/jakarta}} {{/useBeanValidation}} {{^java8}} @@ -245,9 +272,9 @@ 2.0.0 {{/useOas2}} 9.3.27.v20190418 - 3.0.11.Final + 3.15.6.Final 1.6.3 4.13.1 - 2.5 + {{#jakarta}}6.0.0{{/jakarta}}{{^jakarta}}2.5{{/jakarta}} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/serviceCookieParams.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/serviceCookieParams.mustache new file mode 100644 index 0000000000..70871f0f8c --- /dev/null +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/serviceCookieParams.mustache @@ -0,0 +1 @@ +{{#isCookieParam}}{{{dataType}}} {{paramName}}{{/isCookieParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/serviceFormParams.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/serviceFormParams.mustache index 72fe3e7ebe..610b6059ac 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/serviceFormParams.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/eap/serviceFormParams.mustache @@ -1 +1 @@ -{{#is this 'form-param'}}{{#isNot this 'binary'}}{{{dataType}}} {{paramName}}{{/isNot}}{{#is this 'binary'}}FormDataContentDisposition fileDetail{{/is}}{{/is}} \ No newline at end of file +{{#isFormParam}}{{^isBinary}}{{{dataType}}} {{paramName}}{{/isBinary}}{{/isFormParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/enumOuterClass.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/enumOuterClass.mustache index fd5a5a3f5f..8b6b0b1127 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/enumOuterClass.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/enumOuterClass.mustache @@ -1,3 +1,23 @@ -public enum {{classname}} { - {{#allowableValues}}{{.}}{{^@last}}, {{/@last}}{{/allowableValues}} +/** o.O +* {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}} +*/ +public enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { + {{#allowableValues}} + {{#enumVars}} + {{{name}}}({{#value}}{{{value}}}{{/value}}{{^value}}null{{/value}}){{^@last}}, +{{/@last}}{{#@last}}; + {{/@last}} + {{/enumVars}} + {{/allowableValues}} + private {{dataType}} value; + + {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}({{dataType}} value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } } \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/formParams.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/formParams.mustache index bca3affc3d..52ddceda5d 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/formParams.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/formParams.mustache @@ -1 +1 @@ -{{#is this 'form-param'}}{{#isNot this 'binary'}}{{#useOas2}}@ApiParam(value = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}})@FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}})@FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{/isNot}}{{/is}} \ No newline at end of file +{{#is this 'form-param'}}{{#isNot this 'binary'}}{{#useOas2}}@ApiParam(value = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}})@FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}})@FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{/isNot}}{{/is}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/generatedAnnotation.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/generatedAnnotation.mustache index a47b6faa85..c6c0883bcb 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/generatedAnnotation.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/generatedAnnotation.mustache @@ -1 +1 @@ -{{^hideGenerationTimestamp}}@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} \ No newline at end of file +{{^hideGenerationTimestamp}}@{{#jakarta}}jakarta{{/jakarta}}{{^jakarta}}javax{{/jakarta}}.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/gradle.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/gradle.mustache index 9e66a801d0..8a02257f2b 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/gradle.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/gradle.mustache @@ -8,11 +8,11 @@ repositories { } dependencies { - providedCompile 'org.jboss.resteasy:resteasy-jaxrs:3.0.11.Final' - providedCompile 'org.jboss.resteasy:jaxrs-api:3.0.11.Final' + providedCompile 'org.jboss.resteasy:resteasy-jaxrs:3.15.6.Final' + providedCompile 'org.jboss.resteasy:jaxrs-api:3.0.12.Final' providedCompile 'org.jboss.resteasy:resteasy-validator-provider-11:3.0.11.Final' - providedCompile 'org.jboss.resteasy:resteasy-multipart-provider:3.0.11.Final' - providedCompile 'javax.annotation:javax.annotation-api:1.2' + providedCompile 'org.jboss.resteasy:resteasy-multipart-provider:3.15.6.Final' + providedCompile 'jakarta.annotation:jakarta.annotation-api:{{#jakarta}}2.1.1{{/jakarta}}{{^jakarta}}1.3.5{{/jakarta}}' providedCompile 'javax:javaee-api:7.0' providedCompile 'org.jboss.spec.javax.servlet:jboss-servlet-api_3.0_spec:1.0.0.Final' {{#useOas2}} @@ -21,10 +21,10 @@ dependencies { {{^useOas2}} compile 'io.swagger.core.v3:swagger-annotations:2.0.0' {{/useOas2}} - compile 'org.jboss.resteasy:resteasy-jackson2-provider:3.0.11.Final' + compile 'org.jboss.resteasy:resteasy-jackson2-provider:3.15.6.Final' compile 'org.apache.httpcomponents:httpclient:4.5.10' {{#useBeanValidation}} - providedCompile 'javax.validation:validation-api:1.1.0.Final' + providedCompile 'jakarta.validation:jakarta.validation-api:{{#jakarta}}3.0.2{{/jakarta}}{{^jakarta}}2.0.2{{/jakarta}}' {{/useBeanValidation}} {{^java8}} compile 'com.fasterxml.jackson.datatype:jackson-datatype-joda:2.10.1' @@ -33,6 +33,7 @@ dependencies { {{#java8}} compile 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.1' {{/java8}} + compile 'com.fasterxml.jackson.core:jackson-databind:2.10.1' //TODO: swaggerFeature {{#useOas2}} compile 'io.swagger:swagger-jaxrs:1.5.12' diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/headerParams.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/headerParams.mustache index 7b9d478841..2df32600fa 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/headerParams.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/headerParams.mustache @@ -1 +1 @@ -{{#is this 'header-param'}}{{#useOas2}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}})@HeaderParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}})@HeaderParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{/is}} \ No newline at end of file +{{#is this 'header-param'}}{{#useOas2}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}})@HeaderParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}})@HeaderParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/useOas2}}{{/is}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/interface.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/interface.mustache index becc0c5549..2ee7870910 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/interface.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/interface.mustache @@ -1,6 +1,22 @@ +{{#jackson}} +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; // +{{/jackson}} /** * {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} */ +{{#jackson}} +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{#discriminator}}{{#propertyName}}{{propertyName}}{{/propertyName}}{{^propertyName}}type{{/propertyName}}{{/discriminator}}{{^discriminator}}type{{/discriminator}}") + @JsonSubTypes({ + {{#subTypes}} + @JsonSubTypes.Type(value = {{classname}}.class, name = "{{classname}}"){{^@last}},{{/@last}} + {{/subTypes}} +}) +{{/jackson}} public interface {{{classname}}} { - +{{#vendorExtensions}} +{{#x-discriminator-type-getter}} + {{x-discriminator-type}} {{x-discriminator-type-getter}}(); +{{/x-discriminator-type-getter}} +{{/vendorExtensions}} } diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/model.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/model.mustache index 41abb664d0..8c70a27988 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/model.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/model.mustache @@ -3,13 +3,19 @@ package {{package}}; {{^x-is-composed-model}} import java.util.Objects; import java.util.ArrayList; +import java.util.HashMap; {{#imports}}import {{import}}; {{/imports}} {{#serializableModel}} import java.io.Serializable; {{/serializableModel}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{/x-is-composed-model}} {{#models}} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/pom.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/pom.mustache index 46373c555c..8d52ff3998 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/pom.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/pom.mustache @@ -14,8 +14,8 @@ maven-compiler-plugin 3.6.1 - {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} - {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} @@ -59,12 +59,22 @@ + {{#jakarta}} + + jakarta.platform + jakarta.jakartaee-api + 10.0.0 + provided + + {{/jakarta}} + {{^jakarta}} javax javaee-api 7.0 provided + {{/jakarta}} {{#useOas2}} io.swagger @@ -84,12 +94,22 @@ slf4j-log4j12 ${slf4j-version} + {{#jakarta}} + + jakarta.servlet + jakarta.servlet-api + ${servlet-api-version} + provided + + {{/jakarta}} + {{^jakarta}} javax.servlet servlet-api ${servlet-api-version} provided + {{/jakarta}} org.jboss.resteasy @@ -100,12 +120,12 @@ org.jboss.resteasy jaxrs-api - ${resteasy-version} + 3.0.12.Final org.jboss.resteasy resteasy-validator-provider-11 - ${resteasy-version} + 3.6.3.Final provided @@ -120,12 +140,22 @@ ${resteasy-version} provided + {{#jakarta}} + + jakarta.annotation + jakarta.annotation-api + 2.1.1 + provided + + {{/jakarta}} + {{^jakarta}} javax.annotation javax.annotation-api 1.2 provided + {{/jakarta}} {{#java8}} com.fasterxml.jackson.datatype @@ -193,12 +223,22 @@ {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + {{/jakarta}} + {{^jakarta}} javax.validation validation-api 1.1.0.Final provided + {{/jakarta}} {{/useBeanValidation}} @@ -219,10 +259,10 @@ 2.0.9 {{/useOas2}} 9.3.27.v20190418 - 3.0.11.Final + 3.15.6.Final 1.6.3 4.13.1 - 2.5 + {{#jakarta}}6.0.0{{/jakarta}}{{^jakarta}}2.5{{/jakarta}} {{#java8}}2.10.1{{/java8}} diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/serviceCookieParams.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/serviceCookieParams.mustache new file mode 100644 index 0000000000..70871f0f8c --- /dev/null +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/serviceCookieParams.mustache @@ -0,0 +1 @@ +{{#isCookieParam}}{{{dataType}}} {{paramName}}{{/isCookieParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/resteasy/serviceFormParams.mustache b/src/main/resources/handlebars/JavaJaxRS/resteasy/serviceFormParams.mustache index 72fe3e7ebe..610b6059ac 100644 --- a/src/main/resources/handlebars/JavaJaxRS/resteasy/serviceFormParams.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/resteasy/serviceFormParams.mustache @@ -1 +1 @@ -{{#is this 'form-param'}}{{#isNot this 'binary'}}{{{dataType}}} {{paramName}}{{/isNot}}{{#is this 'binary'}}FormDataContentDisposition fileDetail{{/is}}{{/is}} \ No newline at end of file +{{#isFormParam}}{{^isBinary}}{{{dataType}}} {{paramName}}{{/isBinary}}{{/isFormParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/serviceFormParams.mustache b/src/main/resources/handlebars/JavaJaxRS/serviceFormParams.mustache index 06e6c0d0fd..56d43d61c5 100644 --- a/src/main/resources/handlebars/JavaJaxRS/serviceFormParams.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/serviceFormParams.mustache @@ -1 +1 @@ -{{#is this 'form-param'}}{{#isNot this 'binary'}}{{{dataType}}} {{paramName}}{{/isNot}}{{#is this 'binary'}}InputStream {{paramName}}InputStream, FormDataContentDisposition {{paramName}}Detail{{/is}}{{/is}} \ No newline at end of file +{{#isFormParam}}{{^isBinary}}{{{dataType}}} {{paramName}}{{/isBinary}}{{#isBinary}}java.io.InputStream {{paramName}}InputStream, FormDataContentDisposition {{paramName}}Detail{{/isBinary}}{{/isFormParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaJaxRS/spec/RestApplication.mustache b/src/main/resources/handlebars/JavaJaxRS/spec/RestApplication.mustache index 82b8d9533e..74127894d7 100644 --- a/src/main/resources/handlebars/JavaJaxRS/spec/RestApplication.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/spec/RestApplication.mustache @@ -1,7 +1,13 @@ package {{invokerPackage}}; +{{#jakarta}} +import jakarta.ws.rs.ApplicationPath; +import jakarta.ws.rs.core.Application; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; +{{/jakarta}} @ApplicationPath("/") public class RestApplication extends Application { diff --git a/src/main/resources/handlebars/JavaJaxRS/spec/api.mustache b/src/main/resources/handlebars/JavaJaxRS/spec/api.mustache index 305d2ac928..e942aa61e7 100644 --- a/src/main/resources/handlebars/JavaJaxRS/spec/api.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/spec/api.mustache @@ -3,8 +3,14 @@ package {{package}}; {{#imports}}import {{import}}; {{/imports}} +{{#jakarta}} +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.Response; +{{/jakarta}} +{{^jakarta}} import javax.ws.rs.*; import javax.ws.rs.core.Response; +{{/jakarta}} {{#useOas2}} import io.swagger.annotations.*; @@ -22,8 +28,16 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement; import java.util.Map; import java.util.List; -{{#useBeanValidation}}import javax.validation.constraints.*; -import javax.validation.Valid;{{/useBeanValidation}} +{{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +import jakarta.validation.Valid; +{{/jakarta}} +{{^jakarta}} +import javax.validation.constraints.*; +import javax.validation.Valid; +{{/jakarta}} +{{/useBeanValidation}} @Path("/{{{baseName}}}") {{#useOas2}} @@ -40,4 +54,4 @@ import javax.validation.Valid;{{/useBeanValidation}} {{/contents}} {{/operation}} } -{{/operations}} \ No newline at end of file +{{/operations}} diff --git a/src/main/resources/handlebars/JavaJaxRS/spec/generatedAnnotation.mustache b/src/main/resources/handlebars/JavaJaxRS/spec/generatedAnnotation.mustache index ad17a426e9..c6c0883bcb 100644 --- a/src/main/resources/handlebars/JavaJaxRS/spec/generatedAnnotation.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/spec/generatedAnnotation.mustache @@ -1,3 +1 @@ -{{^hideGenerationTimestamp}} -@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}") -{{/hideGenerationTimestamp}} \ No newline at end of file +{{^hideGenerationTimestamp}}@{{#jakarta}}jakarta{{/jakarta}}{{^jakarta}}javax{{/jakarta}}.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} diff --git a/src/main/resources/handlebars/JavaJaxRS/spec/interface.mustache b/src/main/resources/handlebars/JavaJaxRS/spec/interface.mustache index becc0c5549..abec32f768 100644 --- a/src/main/resources/handlebars/JavaJaxRS/spec/interface.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/spec/interface.mustache @@ -3,4 +3,9 @@ */ public interface {{{classname}}} { +{{#vendorExtensions}} +{{#x-discriminator-type-getter}} + {{x-discriminator-type}} {{x-discriminator-type-getter}}(); +{{/x-discriminator-type-getter}} +{{/vendorExtensions}} } diff --git a/src/main/resources/handlebars/JavaJaxRS/spec/model.mustache b/src/main/resources/handlebars/JavaJaxRS/spec/model.mustache index 12a22e18ee..67a3c2dd73 100644 --- a/src/main/resources/handlebars/JavaJaxRS/spec/model.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/spec/model.mustache @@ -7,8 +7,14 @@ package {{package}}; import java.io.Serializable; {{/serializableModel}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +import jakarta.validation.Valid; +{{/jakarta}} +{{^jakarta}} import javax.validation.constraints.*; import javax.validation.Valid; +{{/jakarta}} {{/useBeanValidation}} {{/x-is-composed-model}} diff --git a/src/main/resources/handlebars/JavaJaxRS/spec/pom.mustache b/src/main/resources/handlebars/JavaJaxRS/spec/pom.mustache index 049ba9dc6e..189ac51a9e 100644 --- a/src/main/resources/handlebars/JavaJaxRS/spec/pom.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/spec/pom.mustache @@ -35,13 +35,41 @@ {{/interfaceOnly}} + {{#java11}} + + + jdk11 + + [11,) + + + + com.sun.xml.ws + jaxws-rt + {{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}2.3.3{{/jakarta}} + pom + + + + + {{/java11}} + {{#jakarta}} + + jakarta.ws.rs + jakarta.ws.rs-api + 3.1.0 + provided + + {{/jakarta}} + {{^jakarta}} javax.ws.rs javax.ws.rs-api 2.0 provided + {{/jakarta}} {{#useOas2}} io.swagger @@ -86,15 +114,29 @@ {{/interfaceOnly}} {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + {{/jakarta}} + {{^jakarta}} javax.validation validation-api 1.1.0.Final provided + {{/jakarta}} {{/useBeanValidation}} + {{#java11}} + 11 + 11 + {{/java11}} 4.13.1 diff --git a/src/main/resources/handlebars/JavaJaxRS/typeInfoAnnotation.mustache b/src/main/resources/handlebars/JavaJaxRS/typeInfoAnnotation.mustache index f2a2e1c88f..52695c64fe 100644 --- a/src/main/resources/handlebars/JavaJaxRS/typeInfoAnnotation.mustache +++ b/src/main/resources/handlebars/JavaJaxRS/typeInfoAnnotation.mustache @@ -1,7 +1,14 @@ {{#jackson}} -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator.propertyName}}", visible = true ) -@JsonSubTypes({ - {{#children}} - @JsonSubTypes.Type(value = {{classname}}.class, name = "{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}"), - {{/children}} -}){{/jackson}} + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator.propertyName}}", visible = true ) + @JsonSubTypes({ + {{#if discriminator.mapping}} + {{#each discriminator.mapping}} + @JsonSubTypes.Type(value = {{this}}.class, name = "{{@key}}"), + {{/each}} + {{else}} + {{#children}} + @JsonSubTypes.Type(value = {{classname}}.class, name = "{{name}}"), + {{/children}} + {{/if}} + }) +{{/jackson}} diff --git a/src/main/resources/handlebars/JavaMicronaut/api.mustache b/src/main/resources/handlebars/JavaMicronaut/api.mustache index f10469f744..2bc0e282ba 100644 --- a/src/main/resources/handlebars/JavaMicronaut/api.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/api.mustache @@ -10,25 +10,42 @@ package {{package}}; import com.fasterxml.jackson.databind.ObjectMapper; import io.micronaut.http.*; import io.micronaut.http.annotation.*; +{{#useRxJava3}} +import io.reactivex.rxjava3.core.Single; +{{/useRxJava3}} +{{^useRxJava3}} +{{#useRxJava2}} import io.reactivex.Single; +{{/useRxJava2}} +{{/useRxJava3}} import io.swagger.v3.oas.annotations.*; import io.swagger.v3.oas.annotations.responses.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +{{#useReactor}} +import org.reactivestreams.Publisher; +import reactor.core.publisher.Mono; +{{/useReactor}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.annotation.Nullable; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.annotation.Nullable; import javax.validation.Valid; import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} import java.io.IOException; import java.util.List; import java.util.Map; +{{#useOptional}} import java.util.Optional; +{{/useOptional}} {{>generatedAnnotation}} {{#operations}} -@Controller public interface {{classname}} { {{#operation}} @@ -46,8 +63,8 @@ public interface {{classname}} { }) {{/implicitHeaders}} @{{#lambda.capitalise}}{{httpMethod}}{{/lambda.capitalise}}(value = "{{{path}}}"{{#hasProduces}}, produces = { {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }{{/hasProduces}}{{#hasConsumes}}, consumes = {{braces "left"}}{{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}{{braces "right"}}{{/hasConsumes}}) - default SinglereturnTypes}}>> {{operationId}}({{#parameters}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/parameters}}) { - return Single.fromCallable(() -> { + default SinglereturnTypes}}>> {{operationId}}({{#parameters}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>cookieParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/parameters}}) { + return {{^useReactor}}Single{{/useReactor}}{{#useReactor}}Mono{{/useReactor}}.fromCallable(() -> { throw new UnsupportedOperationException(); }); } diff --git a/src/main/resources/handlebars/JavaMicronaut/apiController.mustache b/src/main/resources/handlebars/JavaMicronaut/apiController.mustache new file mode 100644 index 0000000000..4cdc59424e --- /dev/null +++ b/src/main/resources/handlebars/JavaMicronaut/apiController.mustache @@ -0,0 +1,55 @@ +package {{package}}; + +{{#imports}} +import {{import}}; + +{{/imports}} +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.HttpResponse; +{{#useRxJava3}} +import io.reactivex.rxjava3.core.Single; +{{/useRxJava3}} +{{^useRxJava3}} +{{#useRxJava2}} +import io.reactivex.Single; +{{/useRxJava2}} +{{/useRxJava3}} +{{#useReactor}} +import org.reactivestreams.Publisher; +import reactor.core.publisher.Mono; +{{/useReactor}} + +{{#useBeanValidation}} +import javax.annotation.Nullable; +import javax.validation.Valid; +import javax.validation.constraints.*; +{{/useBeanValidation}} +import java.util.List; +import java.util.Map; +{{#useOptional}} +import java.util.Optional; +{{/useOptional}} + +{{#operations}} +@Controller +public class {{classname}}Controller implements {{classname}} { +{{#operation}} +{{#contents}} + + @Override + public SinglereturnTypes}}>> {{operationId}}({{#parameters}}{{#useBeanValidation}}{{! + Bean validation spec for path parameters (PathParam is always required) +}}{{#isPathParam}}{{>beanValidationParams}}{{/isPathParam}}{{! + Bean validation spec for any other parameters +}}{{^isPathParam}}{{>nullableBeanValidationParams}}{{/isPathParam}}{{/useBeanValidation}}{{! + Method argument type and name +}}{{>optionalDataType}} {{paramName}}{{! + Arguments separator, if required +}}{{#hasMore}}, {{/hasMore}}{{/parameters}}) { + // TODO: Implement me + return {{classname}}.super.{{operationId}}({{#parameters}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/parameters}}); + } +{{/contents}} +{{/operation}} +} +{{/operations}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/api_test.mustache b/src/main/resources/handlebars/JavaMicronaut/api_test.mustache index d965ccbd92..a3f012f24b 100644 --- a/src/main/resources/handlebars/JavaMicronaut/api_test.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/api_test.mustache @@ -5,10 +5,12 @@ package {{package}}; import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; -import io.micronaut.test.annotation.MicronautTest; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; import org.junit.jupiter.api.Test; - -import javax.inject.Inject; +{{#useReactor}} +import reactor.core.publisher.Mono; +{{/useReactor}} +import jakarta.inject.Inject; import java.util.*; @@ -23,18 +25,20 @@ class {{classname}}ControllerTest { {{#operations}} {{#operation}} {{#contents}} + {{#@first}} @Test - void {{operationId}}{{#isForm}}WithForm{{/isForm}}Test() { + void {{operationId}}{{#isForm}}Form{{/isForm}}Test() { {{#parameters}} - {{{dataType}}} {{paramName}} = {{{example}}}; + {{{dataType}}} {{paramName}} = null; {{/parameters}} try { - api.{{operationId}}({{#parameters}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/parameters}}).blockingGet(); + //TODO: {{#useReactor}}Mono.from({{/useReactor}}api.{{operationId}}({{#parameters}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/parameters}}){{#useReactor}}){{/useReactor}}{{^useReactor}}.blockingGet();{{/useReactor}}{{#useReactor}}.block();{{/useReactor}} } catch (UnsupportedOperationException e) { assumeTrue(false, "API is not yet implemented"); } } + {{/@first}} {{/contents}} {{/operation}} {{/operations}} diff --git a/src/main/resources/handlebars/JavaMicronaut/beanValidation.mustache b/src/main/resources/handlebars/JavaMicronaut/beanValidation.mustache index 3e4ef612a4..0894c7cdbc 100644 --- a/src/main/resources/handlebars/JavaMicronaut/beanValidation.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/beanValidation.mustache @@ -3,4 +3,4 @@ {{/required}}{{#isContainer}}{{^isPrimitiveType}}{{^isEnum}} @Valid{{/isEnum}}{{/isPrimitiveType}}{{/isContainer}}{{#isNotContainer}}{{^isPrimitiveType}} @Valid{{/isPrimitiveType}}{{/isNotContainer}} -{{>beanValidationCore}} +{{>beanValidationCore}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/beanValidationHeaderParams.mustache b/src/main/resources/handlebars/JavaMicronaut/beanValidationHeaderParams.mustache deleted file mode 100644 index 6ff580a67c..0000000000 --- a/src/main/resources/handlebars/JavaMicronaut/beanValidationHeaderParams.mustache +++ /dev/null @@ -1 +0,0 @@ -{{#required}}@NotNull {{/required}}{{^required}}@Nullable {{/required}}{{>beanValidationCore}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/beanValidationParams.mustache b/src/main/resources/handlebars/JavaMicronaut/beanValidationParams.mustache new file mode 100644 index 0000000000..b01b404811 --- /dev/null +++ b/src/main/resources/handlebars/JavaMicronaut/beanValidationParams.mustache @@ -0,0 +1 @@ +{{#useBeanValidation}}{{>beanValidationParamsInner}}{{>beanValidationCore}}{{/useBeanValidation}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/beanValidationParamsInner.mustache b/src/main/resources/handlebars/JavaMicronaut/beanValidationParamsInner.mustache new file mode 100644 index 0000000000..aaa696691e --- /dev/null +++ b/src/main/resources/handlebars/JavaMicronaut/beanValidationParamsInner.mustache @@ -0,0 +1,5 @@ +{{^isPrimitiveType}}{{^isEnum}}{{! + Non-container +}}{{^isContainer}}@Valid {{/isContainer}}{{! + Container +}}{{#isContainer}}{{#items}}{{>beanValidationParamsInner}}{{/items}}{{/isContainer}}{{/isEnum}}{{/isPrimitiveType}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/beanValidationPathParams.mustache b/src/main/resources/handlebars/JavaMicronaut/beanValidationPathParams.mustache deleted file mode 100644 index 051bd53c0a..0000000000 --- a/src/main/resources/handlebars/JavaMicronaut/beanValidationPathParams.mustache +++ /dev/null @@ -1 +0,0 @@ -{{! PathParam is always required, no @NotNull necessary }}{{>beanValidationCore}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/beanValidationQueryParams.mustache b/src/main/resources/handlebars/JavaMicronaut/beanValidationQueryParams.mustache deleted file mode 100644 index 6ff580a67c..0000000000 --- a/src/main/resources/handlebars/JavaMicronaut/beanValidationQueryParams.mustache +++ /dev/null @@ -1 +0,0 @@ -{{#required}}@NotNull {{/required}}{{^required}}@Nullable {{/required}}{{>beanValidationCore}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/bodyParams.mustache b/src/main/resources/handlebars/JavaMicronaut/bodyParams.mustache index 3fffbee7e8..8bd655d9fa 100644 --- a/src/main/resources/handlebars/JavaMicronaut/bodyParams.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/bodyParams.mustache @@ -1 +1 @@ -{{#isBodyParam}}@Parameter(description = "{{{description}}}") {{#useBeanValidation}}@Valid {{/useBeanValidation}}@Body {{{dataType}}} {{paramName}}{{/isBodyParam}} \ No newline at end of file +{{#isBodyParam}}{{>nullableBeanValidationParams}}@Parameter(description = "{{{description}}}") @Body {{{dataType}}} {{paramName}}{{/isBodyParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/cookieParams.mustache b/src/main/resources/handlebars/JavaMicronaut/cookieParams.mustache new file mode 100644 index 0000000000..9e4c72a8ab --- /dev/null +++ b/src/main/resources/handlebars/JavaMicronaut/cookieParams.mustache @@ -0,0 +1 @@ +{{#isCookieParam}}{{>nullableBeanValidationParams}}@Parameter(description = "{{{description}}}") @CookieValue(value="{{baseName}}") {{>optionalDataType}} {{paramName}}{{/isCookieParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/enumClass.mustache b/src/main/resources/handlebars/JavaMicronaut/enumClass.mustache index 8884062720..f52f371d2d 100644 --- a/src/main/resources/handlebars/JavaMicronaut/enumClass.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/enumClass.mustache @@ -2,23 +2,16 @@ * {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}} */ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { + {{#allowableValues}} + {{#enumVars}} {{#gson}} - {{#allowableValues}} - {{#enumVars}} - @SerializedName({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) - {{{name}}}({{{value}}}){{^@last}}, - {{/@last}}{{#@last}};{{/@last}} - {{/enumVars}} - {{/allowableValues}} - {{/gson}} - {{^gson}} - {{#allowableValues}} - {{#enumVars}} - {{{name}}}({{{value}}}){{^@last}}, - {{/@last}}{{#@last}};{{/@last}} - {{/enumVars}} - {{/allowableValues}} + {{#value}} + @SerializedName({{{toQuotedWord value}}}) + {{/value}} {{/gson}} + {{{name}}}({{#value}}{{{value}}}{{/value}}{{^value}}null{{/value}}){{^@last}},{{/@last}}{{#@last}};{{/@last}} + {{/enumVars}} + {{/allowableValues}} private {{{datatype}}} value; diff --git a/src/main/resources/handlebars/JavaMicronaut/enumOuterClass.mustache b/src/main/resources/handlebars/JavaMicronaut/enumOuterClass.mustache index 8d9e187986..14858672f1 100644 --- a/src/main/resources/handlebars/JavaMicronaut/enumOuterClass.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/enumOuterClass.mustache @@ -6,17 +6,16 @@ import com.fasterxml.jackson.annotation.JsonCreator; * {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}} */ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} { - {{#gson}} - {{#allowableValues}}{{#enumVars}} - @SerializedName({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) - {{{name}}}({{{value}}}){{^@last}}, - {{/@last}}{{#@last}};{{/@last}}{{/enumVars}}{{/allowableValues}} - {{/gson}} - {{^gson}} - {{#allowableValues}}{{#enumVars}} - {{{name}}}({{{value}}}){{^@last}}, - {{/@last}}{{#@last}};{{/@last}}{{/enumVars}}{{/allowableValues}} - {{/gson}} + {{#allowableValues}} + {{#enumVars}} + {{#gson}} + {{#value}} + @SerializedName({{{toQuotedWord value}}}) + {{/value}} + {{/gson}} + {{{name}}}({{#value}}{{{value}}}{{/value}}{{^value}}null{{/value}}){{^@last}},{{/@last}}{{#@last}};{{/@last}} + {{/enumVars}} + {{/allowableValues}} private {{{dataType}}} value; diff --git a/src/main/resources/handlebars/JavaMicronaut/formParams.mustache b/src/main/resources/handlebars/JavaMicronaut/formParams.mustache index 5b5e062853..494a4fb912 100644 --- a/src/main/resources/handlebars/JavaMicronaut/formParams.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/formParams.mustache @@ -1 +1 @@ -{{#isFormParam}}{{#notFile}}@Parameter(description = "{{{description}}}") @QueryValue(value = "{{baseName}}") {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}@Parameter(description = "file detail") {{#useBeanValidation}}@Valid {{/useBeanValidation}}MultipartFile {{baseName}}{{/isFile}}{{/isFormParam}} +{{#isFormParam}}{{#notFile}}{{>nullableBeanValidationParams}}@Parameter(description = "{{{description}}}") @Body(value = "{{baseName}}") {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}@Parameter(description = "file detail") {{#useBeanValidation}}@Valid {{/useBeanValidation}}File {{baseName}}{{/isFile}}{{/isFormParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/generatedAnnotation.mustache b/src/main/resources/handlebars/JavaMicronaut/generatedAnnotation.mustache index ad17a426e9..c6c0883bcb 100644 --- a/src/main/resources/handlebars/JavaMicronaut/generatedAnnotation.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/generatedAnnotation.mustache @@ -1,3 +1 @@ -{{^hideGenerationTimestamp}} -@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}") -{{/hideGenerationTimestamp}} \ No newline at end of file +{{^hideGenerationTimestamp}}@{{#jakarta}}jakarta{{/jakarta}}{{^jakarta}}javax{{/jakarta}}.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} diff --git a/src/main/resources/handlebars/JavaMicronaut/headerParams.mustache b/src/main/resources/handlebars/JavaMicronaut/headerParams.mustache index b56740532b..5f6dcf0b3e 100644 --- a/src/main/resources/handlebars/JavaMicronaut/headerParams.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/headerParams.mustache @@ -1 +1 @@ -{{#isHeaderParam}}{{#useBeanValidation}}{{>beanValidationHeaderParams}}{{/useBeanValidation}}@Parameter(description = "{{{description}}}") {{#useBeanValidation}}@Valid {{/useBeanValidation}}@Header(value = "{{baseName}}") {{>optionalDataType}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file +{{#isHeaderParam}}{{>nullableBeanValidationParams}}@Parameter(description = "{{{description}}}") @Header(value = "{{baseName}}") {{>optionalDataType}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/mainApplication.mustache b/src/main/resources/handlebars/JavaMicronaut/mainApplication.mustache index b3ace528b9..653395132d 100644 --- a/src/main/resources/handlebars/JavaMicronaut/mainApplication.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/mainApplication.mustache @@ -8,7 +8,7 @@ import io.swagger.v3.oas.annotations.info.*; info = @Info( title = "{{appName}}", version = "{{appVersion}}", - description = "{{appDescription}}", + description = "{{{appDescription}}}", contact = @Contact( name = "{{infoName}}", email = "{{infoEmail}}" diff --git a/src/main/resources/handlebars/JavaMicronaut/model.mustache b/src/main/resources/handlebars/JavaMicronaut/model.mustache index b34290e15e..5c26b09746 100644 --- a/src/main/resources/handlebars/JavaMicronaut/model.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/model.mustache @@ -7,9 +7,16 @@ import java.util.Objects; import java.io.Serializable; {{/serializableModel}} {{#useBeanValidation}} +import io.micronaut.core.annotation.Introspected; import io.micronaut.validation.Validated; +{{#jakarta}} +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.Valid; import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{#jackson}} {{#withXml}} @@ -18,7 +25,12 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; {{/withXml}} {{/jackson}} {{#withXml}} +{{#jakarta}} +import jakarta.xml.bind.annotation.*; +{{/jakarta}} +{{^jakarta}} import javax.xml.bind.annotation.*; +{{/jakarta}} {{/withXml}} {{#models}} diff --git a/src/main/resources/handlebars/JavaMicronaut/nullableBeanValidationParams.mustache b/src/main/resources/handlebars/JavaMicronaut/nullableBeanValidationParams.mustache new file mode 100644 index 0000000000..5d387de368 --- /dev/null +++ b/src/main/resources/handlebars/JavaMicronaut/nullableBeanValidationParams.mustache @@ -0,0 +1 @@ +{{#useBeanValidation}}{{#required}}@NotNull {{/required}}{{^required}}@Nullable {{/required}}{{>beanValidationParams}}{{/useBeanValidation}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/pathParams.mustache b/src/main/resources/handlebars/JavaMicronaut/pathParams.mustache index 2e51d583bb..4ac4b0ecd0 100644 --- a/src/main/resources/handlebars/JavaMicronaut/pathParams.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/pathParams.mustache @@ -1 +1,3 @@ -{{#isPathParam}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}@Parameter(description = "{{{description}}}") @PathVariable("{{baseName}}") {{>optionalDataType}} {{paramName}}{{/isPathParam}} \ No newline at end of file +{{#isPathParam}}{{! + PathParam is always required, no @NotNull necessary +}}{{>beanValidationParams}}@Parameter(description = "{{{description}}}") @PathVariable("{{baseName}}") {{>optionalDataType}} {{paramName}}{{/isPathParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/pojo.mustache b/src/main/resources/handlebars/JavaMicronaut/pojo.mustache index 55669741b3..5e86ef1bcb 100644 --- a/src/main/resources/handlebars/JavaMicronaut/pojo.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/pojo.mustache @@ -2,7 +2,10 @@ * {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} */{{#description}} @Schema(description = "{{{description}}}"){{/description}} -{{#useBeanValidation}}@Validated{{/useBeanValidation}} +{{#useBeanValidation}} +@Validated +@Introspected +{{/useBeanValidation}} {{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}} public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#serializableModel}}implements Serializable{{/serializableModel}} { {{#serializableModel}} diff --git a/src/main/resources/handlebars/JavaMicronaut/pom.mustache b/src/main/resources/handlebars/JavaMicronaut/pom.mustache index 85318c9f5f..d5db343bf6 100644 --- a/src/main/resources/handlebars/JavaMicronaut/pom.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/pom.mustache @@ -1,73 +1,106 @@ - + + 4.0.0 {{groupId}} {{artifactId}} {{artifactVersion}} + ${packaging} + + + io.micronaut + micronaut-parent + 3.0.0 + + - 1.1.4 + jar 1.8 - UTF-8 + + + 3.0.0 {{basePackage}}.MainApplication + netty + - jcenter.bintray.com - https://jcenter.bintray.com + central + https://repo.maven.apache.org/maven2 - - - - io.micronaut - micronaut-bom - ${micronaut.version} - pom - import - - - + io.micronaut micronaut-inject compile +{{#useBeanValidation}} io.micronaut micronaut-validation compile +{{/useBeanValidation}} io.micronaut - micronaut-runtime + micronaut-http-client compile - io.swagger.core.v3 - swagger-annotations + io.micronaut + micronaut-http-server-netty compile io.micronaut - micronaut-http-client + micronaut-runtime compile - io.micronaut - micronaut-http-server-netty +{{#useRxJava3}} + io.micronaut.rxjava3 + micronaut-rxjava3 +{{/useRxJava3}} +{{^useRxJava3}} +{{#useRxJava2}} + io.micronaut.rxjava2 + micronaut-rxjava2 +{{/useRxJava2}} +{{/useRxJava3}} + +{{#useReactor}} + io.micronaut.reactor + micronaut-reactor +{{/useReactor}} compile ch.qos.logback logback-classic - 1.2.3 runtime + + io.swagger.core.v3 + swagger-annotations + compile + +{{#useBeanValidation}} + + com.google.code.findbugs + jsr305 + +{{/useBeanValidation}} +{{#threetenbp}} com.github.joschi.jackson jackson-datatype-threetenbp 2.6.4 +{{/threetenbp}} +{{#generateApiTests}} + org.junit.jupiter junit-jupiter-api @@ -83,114 +116,40 @@ micronaut-test-junit5 test +{{/generateApiTests}} + - org.apache.maven.plugins - maven-shade-plugin - 3.1.0 - - - package - - shade - - - - - ${exec.mainClass} - - - - - - + io.micronaut.build + micronaut-maven-plugin + - org.codehaus.mojo - exec-maven-plugin - 1.6.0 + org.apache.maven.plugins + maven-compiler-plugin - java - - -noverify - -XX:TieredStopAtLevel=1 - -Dcom.sun.management.jmxremote - -classpath - - ${exec.mainClass} - + + + +{{#useBeanValidation}} + + + io.micronaut + micronaut-http-validation + ${micronaut.version} + + +{{/useBeanValidation}} + + -Amicronaut.processing.group={{groupId}} + -Amicronaut.processing.module={{artifactId}} + - - maven-surefire-plugin - 2.22.0 - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.7.0 - - ${jdk.version} - ${jdk.version} - UTF-8 - - -parameters - - - - io.micronaut - micronaut-inject-java - ${micronaut.version} - - - io.micronaut - micronaut-validation - ${micronaut.version} - - - io.micronaut.configuration - micronaut-openapi - 1.1.1 - - - - - - test-compile - - testCompile - - - - -parameters - - - - io.micronaut - micronaut-inject-java - ${micronaut.version} - - - io.micronaut - micronaut-validation - ${micronaut.version} - - - io.micronaut.configuration - micronaut-openapi - 1.1.1 - - - - - - - - + + diff --git a/src/main/resources/handlebars/JavaMicronaut/publisher.mustache b/src/main/resources/handlebars/JavaMicronaut/publisher.mustache new file mode 100644 index 0000000000..e76087e08e --- /dev/null +++ b/src/main/resources/handlebars/JavaMicronaut/publisher.mustache @@ -0,0 +1 @@ +{{#useReactor}}Publisher{{/useReactor}}{{^useReactor}}Single{{/useReactor}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/queryParams.mustache b/src/main/resources/handlebars/JavaMicronaut/queryParams.mustache index eb1cbbb525..a27659430f 100644 --- a/src/main/resources/handlebars/JavaMicronaut/queryParams.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/queryParams.mustache @@ -1 +1 @@ -{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}@Parameter(description = "{{{description}}}") {{#useBeanValidation}}@Valid {{/useBeanValidation}}@QueryValue(value = "{{baseName}}"{{#defaultValue}}, defaultValue = "{{{defaultValue}}}"{{/defaultValue}}) {{>optionalDataType}} {{paramName}}{{/isQueryParam}} \ No newline at end of file +{{#isQueryParam}}{{>nullableBeanValidationParams}}@Parameter(description = "{{{description}}}") @QueryValue(value = "{{baseName}}"{{#defaultValue}}, defaultValue = "{{{defaultValue}}}"{{/defaultValue}}) {{>optionalDataType}} {{paramName}}{{/isQueryParam}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaMicronaut/typeInfoAnnotation.mustache b/src/main/resources/handlebars/JavaMicronaut/typeInfoAnnotation.mustache index 9fbced41d8..52695c64fe 100644 --- a/src/main/resources/handlebars/JavaMicronaut/typeInfoAnnotation.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/typeInfoAnnotation.mustache @@ -1,7 +1,14 @@ {{#jackson}} -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator.propertyName}}", visible = true ) -@JsonSubTypes({ - {{#children}} - @JsonSubTypes.Type(value = {{classname}}.class, name = "{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}"), - {{/children}} -}){{/jackson}} \ No newline at end of file + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator.propertyName}}", visible = true ) + @JsonSubTypes({ + {{#if discriminator.mapping}} + {{#each discriminator.mapping}} + @JsonSubTypes.Type(value = {{this}}.class, name = "{{@key}}"), + {{/each}} + {{else}} + {{#children}} + @JsonSubTypes.Type(value = {{classname}}.class, name = "{{name}}"), + {{/children}} + {{/if}} + }) +{{/jackson}} diff --git a/src/main/resources/handlebars/JavaMicronaut/unsupportedOperationExceptionHandler.mustache b/src/main/resources/handlebars/JavaMicronaut/unsupportedOperationExceptionHandler.mustache index 8322cd7af4..1ea8ed604f 100644 --- a/src/main/resources/handlebars/JavaMicronaut/unsupportedOperationExceptionHandler.mustache +++ b/src/main/resources/handlebars/JavaMicronaut/unsupportedOperationExceptionHandler.mustache @@ -7,8 +7,7 @@ import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; import io.micronaut.http.annotation.Produces; import io.micronaut.http.server.exceptions.ExceptionHandler; - -import javax.inject.Singleton; +import jakarta.inject.Singleton; @Produces @Singleton @@ -19,4 +18,4 @@ public class UnsupportedOperationExceptionHandler implements ExceptionHandler { + private final DateTimeFormatter formatter; + + public LocalDateConverter(String dateFormat) { + this.formatter = DateTimeFormatter.ofPattern(dateFormat); + } + + @Override + public LocalDate convert(String source) { + if(source == null || source.isEmpty()) { + return null; + } + return LocalDate.parse(source, this.formatter); + } +} diff --git a/src/main/resources/handlebars/JavaSpring/LocalDateTimeConverter.mustache b/src/main/resources/handlebars/JavaSpring/LocalDateTimeConverter.mustache new file mode 100644 index 0000000000..e45f5f8b32 --- /dev/null +++ b/src/main/resources/handlebars/JavaSpring/LocalDateTimeConverter.mustache @@ -0,0 +1,27 @@ +package {{configPackage}}; + +import org.springframework.core.convert.converter.Converter; +{{^isJava8or11}} +import org.threeten.bp.LocalDateTime; +import org.threeten.bp.format.DateTimeFormatter; +{{/isJava8or11}} +{{#isJava8or11}} +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +{{/isJava8or11}} + +public class LocalDateTimeConverter implements Converter { + private final DateTimeFormatter formatter; + + public LocalDateTimeConverter(String dateFormat) { + this.formatter = DateTimeFormatter.ofPattern(dateFormat); + } + + @Override + public LocalDateTime convert(String source) { + if(source == null || source.isEmpty()) { + return null; + } + return LocalDateTime.parse(source, this.formatter); + } +} diff --git a/src/main/resources/handlebars/JavaSpring/api.mustache b/src/main/resources/handlebars/JavaSpring/api.mustache index a14b7666bc..6546e1008d 100644 --- a/src/main/resources/handlebars/JavaSpring/api.mustache +++ b/src/main/resources/handlebars/JavaSpring/api.mustache @@ -44,11 +44,22 @@ import org.springframework.web.multipart.MultipartFile; import org.springframework.web.bind.annotation.CookieValue; {{#jdk8-no-delegate}} +{{#jakarta}} +import jakarta.servlet.http.HttpServletRequest; +{{/jakarta}} +{{^jakarta}} import javax.servlet.http.HttpServletRequest; +{{/jakarta}} {{/jdk8-no-delegate}} {{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.Valid; import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{#jdk8-no-delegate}} import java.io.IOException; @@ -64,7 +75,7 @@ import java.util.Optional; {{/useOptional}} {{/jdk8-no-delegate}} {{#async}} -import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture{{/jdk8}}; +import java.util.concurrent.{{^isJava8or11}}Callable{{/isJava8or11}}{{#isJava8or11}}CompletableFuture{{/isJava8or11}}; {{/async}} {{>generatedAnnotation}} @@ -76,7 +87,7 @@ import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture {{/useOas2}} {{#operations}} public interface {{classname}} { -{{#jdk8}} +{{#isJava8or11}} {{^isDelegate}} Logger log = LoggerFactory.getLogger({{classname}}.class); @@ -96,7 +107,7 @@ public interface {{classname}} { {{#isDelegate}} {{classname}}Delegate getDelegate(); {{/isDelegate}} -{{/jdk8}} +{{/isJava8or11}} {{#operation}} {{#contents}} {{#@first}} diff --git a/src/main/resources/handlebars/JavaSpring/apiController.mustache b/src/main/resources/handlebars/JavaSpring/apiController.mustache index 812bf53fd9..0ef9f4f16c 100644 --- a/src/main/resources/handlebars/JavaSpring/apiController.mustache +++ b/src/main/resources/handlebars/JavaSpring/apiController.mustache @@ -41,15 +41,26 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; {{#useBeanValidation}} -import javax.validation.constraints.*; +{{#jakarta}} +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.Valid; +import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{/fullController}} {{^isDelegate}} + {{#jakarta}} +import jakarta.servlet.http.HttpServletRequest; + {{/jakarta}} + {{^jakarta}} import javax.servlet.http.HttpServletRequest; - {{#jdk8}} + {{/jakarta}} + {{#isJava8or11}} import java.util.Optional; - {{/jdk8}} + {{/isJava8or11}} {{/isDelegate}} {{^jdk8-no-delegate}} {{#useOptional}} @@ -84,13 +95,13 @@ public class {{classname}}Controller implements {{classname}} { public {{classname}}Controller({{classname}}Delegate delegate) { this.delegate = delegate; } - {{#jdk8}} + {{#isJava8or11}} @Override public {{classname}}Delegate getDelegate() { return delegate; } - {{/jdk8}} + {{/isJava8or11}} {{/isDelegate}} {{^isDelegate}} {{#fullController}} @@ -106,7 +117,7 @@ public class {{classname}}Controller implements {{classname}} { this.objectMapper = objectMapper; this.request = request; } - {{#jdk8}} + {{#isJava8or11}} @Override public Optional getObjectMapper() { @@ -117,7 +128,7 @@ public class {{classname}}Controller implements {{classname}} { public Optional getRequest() { return Optional.ofNullable(request); } - {{/jdk8}} + {{/isJava8or11}} {{/isDelegate}} {{#fullController}} diff --git a/src/main/resources/handlebars/JavaSpring/apiDelegate.mustache b/src/main/resources/handlebars/JavaSpring/apiDelegate.mustache index 884352a081..3654d6ee78 100644 --- a/src/main/resources/handlebars/JavaSpring/apiDelegate.mustache +++ b/src/main/resources/handlebars/JavaSpring/apiDelegate.mustache @@ -2,9 +2,9 @@ package {{package}}; {{#imports}}import {{import}}; {{/imports}} -{{#jdk8}} +{{#isJava8or11}} import com.fasterxml.jackson.databind.ObjectMapper; -{{/jdk8}} +{{/isJava8or11}} {{#useOas2}} import io.swagger.annotations.*; {{/useOas2}} @@ -18,32 +18,37 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.security.SecurityRequirement; {{/useOas2}} -{{#jdk8}} +{{#isJava8or11}} import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; -{{/jdk8}} +{{/isJava8or11}} import org.springframework.http.ResponseEntity; import org.springframework.web.multipart.MultipartFile; -{{#jdk8}} +{{#isJava8or11}} import java.io.IOException; -{{/jdk8}} +{{/isJava8or11}} -{{#jdk8}} +{{#isJava8or11}} +{{#jakarta}} +import jakarta.servlet.http.HttpServletRequest; +{{/jakarta}} +{{^jakarta}} import javax.servlet.http.HttpServletRequest; -{{/jdk8}} +{{/jakarta}} +{{/isJava8or11}} import java.util.List; import java.util.Map; -{{#jdk8}} +{{#isJava8or11}} import java.util.Optional; -{{/jdk8}} -{{^jdk8}} +{{/isJava8or11}} +{{^isJava8or11}} {{#useOptional}} import java.util.Optional; {{/useOptional}} -{{/jdk8}} +{{/isJava8or11}} {{#async}} -import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture{{/jdk8}}; +import java.util.concurrent.{{^isJava8or11}}Callable{{/isJava8or11}}{{#isJava8or11}}CompletableFuture{{/isJava8or11}}; {{/async}} {{#operations}} @@ -53,7 +58,7 @@ import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture */ {{>generatedAnnotation}} public interface {{classname}}Delegate { -{{#jdk8}} +{{#isJava8or11}} Logger log = LoggerFactory.getLogger({{classname}}.class); @@ -68,7 +73,7 @@ public interface {{classname}}Delegate { {{#defaultInterfaces}}default Optional getAcceptHeader() { return getRequest().map(r -> r.getHeader("Accept")); }{{/defaultInterfaces}} -{{/jdk8}} +{{/isJava8or11}} {{#operation}} {{#contents}} diff --git a/src/main/resources/handlebars/JavaSpring/apiOriginFilter.mustache b/src/main/resources/handlebars/JavaSpring/apiOriginFilter.mustache index 5cf72a7dc4..fca340e13a 100644 --- a/src/main/resources/handlebars/JavaSpring/apiOriginFilter.mustache +++ b/src/main/resources/handlebars/JavaSpring/apiOriginFilter.mustache @@ -2,11 +2,17 @@ package {{apiPackage}}; import java.io.IOException; +{{#jakarta}} +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletResponse; +{{/jakarta}} +{{^jakarta}} import javax.servlet.*; import javax.servlet.http.HttpServletResponse; +{{/jakarta}} {{>generatedAnnotation}} -public class ApiOriginFilter implements javax.servlet.Filter { +public class ApiOriginFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { diff --git a/src/main/resources/handlebars/JavaSpring/apiResponseMessage.mustache b/src/main/resources/handlebars/JavaSpring/apiResponseMessage.mustache index 17b155f3b6..a978341556 100644 --- a/src/main/resources/handlebars/JavaSpring/apiResponseMessage.mustache +++ b/src/main/resources/handlebars/JavaSpring/apiResponseMessage.mustache @@ -1,9 +1,19 @@ package {{apiPackage}}; +{{#jakarta}} +import jakarta.xml.bind.annotation.XmlTransient; +{{/jakarta}} +{{^jakarta}} import javax.xml.bind.annotation.XmlTransient; +{{/jakarta}} {{>generatedAnnotation}} +{{#jakarta}} +@jakarta.xml.bind.annotation.XmlRootElement +{{/jakarta}} +{{^jakarta}} @javax.xml.bind.annotation.XmlRootElement +{{/jakarta}} public class ApiResponseMessage { public static final int ERROR = 1; public static final int WARNING = 2; diff --git a/src/main/resources/handlebars/JavaSpring/application.mustache b/src/main/resources/handlebars/JavaSpring/application.mustache index 8d8da0b4da..5ef27edcf1 100644 --- a/src/main/resources/handlebars/JavaSpring/application.mustache +++ b/src/main/resources/handlebars/JavaSpring/application.mustache @@ -1,15 +1,10 @@ -{{^springBootV2}} -springfox.documentation.swagger.v2.path=/api-docs -{{/springBootV2}} -{{#springBootV2}} {{#useOas2}} springfox.documentation.swagger.v2.path=/api-docs server.contextPath={{^contextPath}}/{{/contextPath}}{{#contextPath}}{{contextPath}}{{/contextPath}} {{/useOas2}} {{^useOas2}} -springfox.documentation.open-api.v3.path=/api-docs +springdoc.api-docs.path=/api-docs {{/useOas2}} -{{/springBootV2}} server.servlet.contextPath={{^contextPath}}/{{/contextPath}}{{#contextPath}}{{contextPath}}{{/contextPath}} server.port={{serverPort}} spring.jackson.date-format={{basePackage}}.RFC3339DateFormat diff --git a/src/main/resources/handlebars/JavaSpring/application.properties.mustache b/src/main/resources/handlebars/JavaSpring/application.properties.mustache index 1384ae964d..325adf0c5c 100644 --- a/src/main/resources/handlebars/JavaSpring/application.properties.mustache +++ b/src/main/resources/handlebars/JavaSpring/application.properties.mustache @@ -2,5 +2,5 @@ springfox.documentation.swagger.v2.path=/api-docs {{/useOas2}} {{^useOas2}} -springfox.documentation.open-api.v3.path=/api-docs +springdoc.api-docs.path=/api-docs {{/useOas2}} diff --git a/src/main/resources/handlebars/JavaSpring/formParams.mustache b/src/main/resources/handlebars/JavaSpring/formParams.mustache index 72949e8e5b..88a2a231cd 100644 --- a/src/main/resources/handlebars/JavaSpring/formParams.mustache +++ b/src/main/resources/handlebars/JavaSpring/formParams.mustache @@ -1 +1 @@ -{{#isFormParam}}{{^isBinary}}{{#useOas2}}@ApiParam(value = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}){{/useOas2}}{{^useOas2}}@Parameter(in = ParameterIn.DEFAULT, description = "{{{description}}}"{{#required}}, required=true{{/required}},schema=@Schema({{#allowableValues}}{{> allowableValues }}{{/allowableValues}}{{#defaultValue}}{{#allowableValues}},{{/allowableValues}} defaultValue="{{{defaultValue}}}"{{/defaultValue}})){{/useOas2}} @RequestParam(value="{{baseName}}"{{#required}}, required=true{{/required}}{{^required}}, required=false{{/required}}) {{{dataType}}} {{paramName}}{{/isBinary}}{{#isBinary}}{{#useOas2}}@ApiParam(value = "file detail"){{/useOas2}}{{^useOas2}}@Parameter(description = "file detail"){{/useOas2}} {{#useBeanValidation}}@Valid{{/useBeanValidation}} @RequestPart("file") MultipartFile {{baseName}}{{/isBinary}}{{/isFormParam}} \ No newline at end of file +{{#isFormParam}}{{^isBinary}}{{#useOas2}}@ApiParam(value = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}){{/useOas2}}{{^useOas2}}@Parameter(in = ParameterIn.DEFAULT, description = "{{{description}}}"{{#required}}, required=true{{/required}},schema=@Schema({{#allowableValues}}{{> allowableValues }}{{/allowableValues}}{{#defaultValue}}{{#allowableValues}},{{/allowableValues}} defaultValue="{{{defaultValue}}}"{{/defaultValue}})){{/useOas2}} {{#isMultipart}}@RequestPart{{/isMultipart}}{{^isMultipart}}@RequestParam{{/isMultipart}}(value="{{baseName}}"{{#required}}, required=true{{/required}}{{^required}}, required=false{{/required}}) {{{dataType}}} {{paramName}}{{/isBinary}}{{#isBinary}}{{#useOas2}}@ApiParam(value = "{{{description}}}"){{/useOas2}}{{^useOas2}}@Parameter(description = "{{{description}}}"){{/useOas2}} {{#useBeanValidation}}@Valid{{/useBeanValidation}} @RequestPart(value="{{baseName}}"{{#required}}, required=true{{/required}}{{^required}}, required=false{{/required}}) MultipartFile {{baseName}}{{/isBinary}}{{/isFormParam}} diff --git a/src/main/resources/handlebars/JavaSpring/generatedAnnotation.mustache b/src/main/resources/handlebars/JavaSpring/generatedAnnotation.mustache index ad17a426e9..c6c0883bcb 100644 --- a/src/main/resources/handlebars/JavaSpring/generatedAnnotation.mustache +++ b/src/main/resources/handlebars/JavaSpring/generatedAnnotation.mustache @@ -1,3 +1 @@ -{{^hideGenerationTimestamp}} -@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}") -{{/hideGenerationTimestamp}} \ No newline at end of file +{{^hideGenerationTimestamp}}@{{#jakarta}}jakarta{{/jakarta}}{{^jakarta}}javax{{/jakarta}}.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} diff --git a/src/main/resources/handlebars/JavaSpring/interface.mustache b/src/main/resources/handlebars/JavaSpring/interface.mustache index becc0c5549..0d08bbe545 100644 --- a/src/main/resources/handlebars/JavaSpring/interface.mustache +++ b/src/main/resources/handlebars/JavaSpring/interface.mustache @@ -1,6 +1,26 @@ +{{#jackson}} +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +{{/jackson}} /** * {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} */ +{{#jackson}} +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "type") +@JsonSubTypes({ + {{#subTypes}} + @JsonSubTypes.Type(value = {{classname}}.class, name = "{{classname}}"){{^@last}},{{/@last}} + {{/subTypes}} +}) +{{/jackson}} public interface {{{classname}}} { +{{#vendorExtensions}} +{{#x-discriminator-type-getter}} + {{x-discriminator-type}} {{x-discriminator-type-getter}}(); +{{/x-discriminator-type-getter}} +{{/vendorExtensions}} } diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/homeController.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/homeController.mustache index 25bb3495c4..c632a2f872 100644 --- a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/homeController.mustache +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/homeController.mustache @@ -11,11 +11,9 @@ public class HomeController { @RequestMapping(value = "/") public String index() { {{#useOas2}} - System.out.println("swagger-ui.html"); return "redirect:swagger-ui.html"; {{/useOas2}} {{^useOas2}} - System.out.println("/swagger-ui/index.html"); return "redirect:/swagger-ui/"; {{/useOas2}} } diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/pom.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/pom.mustache index 9e6a9e515e..54fbe99edd 100644 --- a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/pom.mustache +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/pom.mustache @@ -6,19 +6,14 @@ {{artifactId}} {{artifactVersion}} - {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} ${java.version} ${java.version} {{#useOas2}} 2.9.2 {{/useOas2}} {{^useOas2}} - {{^springBootV2}} - 1.2.9 - {{/springBootV2}} - {{#springBootV2}} - 3.0.0 - {{/springBootV2}} + 1.7.0 {{/useOas2}} @@ -44,6 +39,24 @@ {{/interfaceOnly}} + {{#java11}} + + + jdk11 + + [11,) + + + + com.sun.xml.ws + jaxws-rt + {{#jakarta}}4.0.0{{/jakarta}}{{^jakarta}}2.3.3{{/jakarta}} + pom + + + + + {{/java11}} org.springframework.boot @@ -61,22 +74,6 @@ springfox-swagger2 ${springfox-version} - {{/useOas2}} - {{^useOas2}} - {{#springBootV2}} - - io.springfox - springfox-oas - ${springfox-version} - - - io.springfox - springfox-swagger-ui - ${springfox-version} - - {{/springBootV2}} - {{/useOas2}} - {{#useOas2}} io.springfox springfox-swagger-ui @@ -84,14 +81,12 @@ {{/useOas2}} {{^useOas2}} - {{^springBootV2}} org.springdoc springdoc-openapi-ui ${springdoc-version} - {{/springBootV2}} {{/useOas2}} {{#withXml}} @@ -103,13 +98,13 @@ {{/withXml}} - {{#java8}} + {{#isJava8or11}} com.fasterxml.jackson.datatype jackson-datatype-jsr310 - {{/java8}} + {{/isJava8or11}} {{#joda}} @@ -128,10 +123,18 @@ {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + + {{/jakarta}} + {{^jakarta}} javax.validation validation-api + {{/jakarta}} {{/useBeanValidation}} {{#notNullJacksonAnnotation}} diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/swagger2SpringBoot.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/swagger2SpringBoot.mustache index 4ab0bfdfdd..42167055ab 100644 --- a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/swagger2SpringBoot.mustache +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/swagger2SpringBoot.mustache @@ -1,5 +1,8 @@ package {{basePackage}}; +import {{configPackage}}.LocalDateConverter; +import {{configPackage}}.LocalDateTimeConverter; + import org.springframework.boot.CommandLineRunner; import org.springframework.boot.ExitCodeGenerator; import org.springframework.boot.SpringApplication; @@ -9,17 +12,15 @@ import org.springframework.context.annotation.ComponentScan; {{#useOas2}} import springfox.documentation.swagger2.annotations.EnableSwagger2; {{/useOas2}} -{{^useOas2}} -import springfox.documentation.oas.annotations.EnableOpenApi; -{{/useOas2}} + +import org.springframework.context.annotation.Configuration; +import org.springframework.format.FormatterRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @SpringBootApplication {{#useOas2}} @EnableSwagger2 {{/useOas2}} -{{^useOas2}} -@EnableOpenApi -{{/useOas2}} @ComponentScan(basePackages = { "{{basePackage}}", "{{apiPackage}}" , "{{configPackage}}"}) public class Swagger2SpringBoot implements CommandLineRunner { @@ -34,6 +35,15 @@ public class Swagger2SpringBoot implements CommandLineRunner { new SpringApplication(Swagger2SpringBoot.class).run(args); } + @Configuration + static class CustomDateConfig extends WebMvcConfigurerAdapter { + @Override + public void addFormatters(FormatterRegistry registry) { + registry.addConverter(new LocalDateConverter("{{#datePattern}}{{datePattern}}{{/datePattern}}{{^datePattern}}yyyy-MM-dd{{/datePattern}}")); + registry.addConverter(new LocalDateTimeConverter("{{#dateTimePattern}}{{dateTimePattern}}{{/dateTimePattern}}{{^dateTimePattern}}yyyy-MM-dd'T'HH:mm:ss.SSS{{/dateTimePattern}}")); + } + } + class ExitException extends RuntimeException implements ExitCodeGenerator { private static final long serialVersionUID = 1L; diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/swaggerUiConfiguration.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/swaggerUiConfiguration.mustache index 165f02b49d..4a8833d465 100644 --- a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/swaggerUiConfiguration.mustache +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot/swaggerUiConfiguration.mustache @@ -8,9 +8,11 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; {{>generatedAnnotation}} @Configuration public class SwaggerUiConfiguration implements WebMvcConfigurer { + @Override + {{#useOas2}} public void addResourceHandlers(ResourceHandlerRegistry registry) { - {{#useOas2}} + registry .addResourceHandler("/swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); @@ -18,19 +20,15 @@ public class SwaggerUiConfiguration implements WebMvcConfigurer { registry .addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); - {{/useOas2}} - {{^useOas2}} registry. addResourceHandler("/swagger-ui/**") .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/") .resourceChain(false); - {{/useOas2}} } - - @Override + {{/useOas2}} + {{^useOas2}} public void addViewControllers(ViewControllerRegistry registry) { - {{^useOas2}} registry.addViewController("/swagger-ui/").setViewName("forward:/swagger-ui/index.html"); - {{/useOas2}} } + {{/useOas2}} } diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/LocalDateConverter.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/LocalDateConverter.mustache new file mode 100644 index 0000000000..75481b41de --- /dev/null +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/LocalDateConverter.mustache @@ -0,0 +1,21 @@ +package {{configPackage}}; + +import org.springframework.core.convert.converter.Converter; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +public class LocalDateConverter implements Converter { + private final DateTimeFormatter formatter; + + public LocalDateConverter(String dateFormat) { + this.formatter = DateTimeFormatter.ofPattern(dateFormat); + } + + @Override + public LocalDate convert(String source) { + if(source == null || source.isEmpty()) { + return null; + } + return LocalDate.parse(source, this.formatter); + } +} diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/LocalDateTimeConverter.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/LocalDateTimeConverter.mustache new file mode 100644 index 0000000000..4854688eb6 --- /dev/null +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/LocalDateTimeConverter.mustache @@ -0,0 +1,21 @@ +package {{configPackage}}; + +import org.springframework.core.convert.converter.Converter; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class LocalDateTimeConverter implements Converter { + private final DateTimeFormatter formatter; + + public LocalDateTimeConverter(String dateFormat) { + this.formatter = DateTimeFormatter.ofPattern(dateFormat); + } + + @Override + public LocalDateTime convert(String source) { + if(source == null || source.isEmpty()) { + return null; + } + return LocalDateTime.parse(source, this.formatter); + } +} diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/README.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/README.mustache new file mode 100644 index 0000000000..8e5dd7bb11 --- /dev/null +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/README.mustache @@ -0,0 +1,37 @@ +{{^interfaceOnly}}# Swagger generated server + +Spring Boot Server + + +## Overview +This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. +By using the [OpenAPI-Spec](https://github.com/swagger-api/swagger-core), you can easily generate a server stub. +This is an example of building a swagger-enabled server in Java using the SpringBoot framework. + +The underlying library integrating swagger to SpringBoot is [springdoc-openapi](https://github.com/springdoc/springdoc-openapi) + +Start your server as an simple java application + +You can view the api documentation in swagger-ui by pointing to +http://localhost:8080/ + +Change default port value in application.properties{{/interfaceOnly}}{{#interfaceOnly}} +# Swagger generated API stub + +Spring Framework stub + + +## Overview +This code was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. +By using the [OpenAPI-Spec](https://github.com/swagger-api/swagger-core), you can easily generate an API stub. +This is an example of building API stub interfaces in Java using the Spring framework. + +The stubs generated can be used in your existing Spring-MVC or Spring-Boot application to create controller endpoints +by adding ```@Controller``` classes that implement the interface. Eg: +```java +@Controller +public class PetController implements PetApi { +// implement all PetApi methods +} +``` +{{/interfaceOnly}} diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/application.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/application.mustache new file mode 100644 index 0000000000..93b903a3c2 --- /dev/null +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/application.mustache @@ -0,0 +1,3 @@ +springdoc.api-docs.path=/api-docs +server.servlet.contextPath={{^contextPath}}/{{/contextPath}}{{#contextPath}}{{contextPath}}{{/contextPath}} +server.port={{serverPort}} diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/homeController.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/homeController.mustache new file mode 100644 index 0000000000..89f4069854 --- /dev/null +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/homeController.mustache @@ -0,0 +1,16 @@ +package {{configPackage}}; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * Home redirection to swagger api documentation + */ +@Controller +public class HomeController { + @RequestMapping(value = "/") + public String index() { + System.out.println("/swagger-ui/index.html"); + return "redirect:/swagger-ui/"; + } +} diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/openAPISpringBoot.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/openAPISpringBoot.mustache new file mode 100644 index 0000000000..876248c766 --- /dev/null +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/openAPISpringBoot.mustache @@ -0,0 +1,48 @@ +package {{basePackage}}; + +import {{configPackage}}.LocalDateConverter; +import {{configPackage}}.LocalDateTimeConverter; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.ExitCodeGenerator; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.format.FormatterRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; + +@SpringBootApplication +@ComponentScan(basePackages = { "{{basePackage}}", "{{apiPackage}}" , "{{configPackage}}"}) +public class OpenAPISpringBoot implements CommandLineRunner { + + @Override + public void run(String... arg0) throws Exception { + if (arg0.length > 0 && arg0[0].equals("exitcode")) { + throw new ExitException(); + } + } + + public static void main(String[] args) throws Exception { + new SpringApplication(OpenAPISpringBoot.class).run(args); + } + + @Configuration + static class CustomDateConfig extends WebMvcConfigurationSupport { + @Override + public void addFormatters(FormatterRegistry registry) { + registry.addConverter(new LocalDateConverter("{{#datePattern}}{{datePattern}}{{/datePattern}}{{^datePattern}}yyyy-MM-dd{{/datePattern}}")); + registry.addConverter(new LocalDateTimeConverter("{{#dateTimePattern}}{{dateTimePattern}}{{/dateTimePattern}}{{^dateTimePattern}}yyyy-MM-dd'T'HH:mm:ss.SSS{{/dateTimePattern}}")); + } + } + + class ExitException extends RuntimeException implements ExitCodeGenerator { + private static final long serialVersionUID = 1L; + + @Override + public int getExitCode() { + return 10; + } + + } +} diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/pom.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/pom.mustache new file mode 100644 index 0000000000..ccd6595351 --- /dev/null +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/pom.mustache @@ -0,0 +1,103 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{artifactVersion}} + + UTF-8 + 17 + 3.1.1 + 2.2.14 + 1.7.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.1.1 + + + src/main/java + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + + org.springframework.boot + spring-boot-starter-web + ${springboot-version} + + + org.springframework.boot + spring-boot-starter-tomcat + ${springboot-version} + + {{#withXml}} + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + + {{/withXml}} + {{#useBeanValidation}} + + + jakarta.validation + jakarta.validation-api + 3.0.2 + + + jakarta.xml.bind + jakarta.xml.bind-api + 4.0.0 + + + com.sun.xml.bind + jaxb-impl + 4.0.3 + + {{/useBeanValidation}} + {{#notNullJacksonAnnotation}} + + com.fasterxml.jackson.core + jackson-annotations + 2.10.1 + + {{/notNullJacksonAnnotation}} + + + org.springdoc + springdoc-openapi-ui + ${springdoc-version} + + + + io.swagger.core.v3 + swagger-annotations + ${swagger-annotations-version} + + + org.springframework.plugin + spring-plugin-core + 3.0.0 + + + + org.springframework.boot + spring-boot-starter-test + ${springboot-version} + test + + + diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/swaggerUiConfiguration.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/swaggerUiConfiguration.mustache new file mode 100644 index 0000000000..94e7f86bbc --- /dev/null +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-boot3/swaggerUiConfiguration.mustache @@ -0,0 +1,16 @@ +package {{configPackage}}; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +{{>generatedAnnotation}} +@Configuration +public class SwaggerUiConfiguration implements WebMvcConfigurer { + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/swagger-ui/").setViewName("forward:/swagger-ui/index.html"); + } +} diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-cloud/apiClient.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-cloud/apiClient.mustache index dc4afa0ea3..029b0030a9 100644 --- a/src/main/resources/handlebars/JavaSpring/libraries/spring-cloud/apiClient.mustache +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-cloud/apiClient.mustache @@ -8,8 +8,6 @@ import org.springframework.cloud.openfeign.FeignClient; {{/isOpenFeign}} import {{configPackage}}.ClientConfiguration; -{{=<% %>=}} -@FeignClient(<%#isOpenFeign%>contextId="<%classname%>Client", <%/isOpenFeign%>name="${<%title%>.name:<%title%>}", url="${<%title%>.url:<%basePath%>}", configuration = ClientConfiguration.class) -<%={{ }}=%> +@FeignClient({{#isOpenFeign}}contextId="{{classname}}Client", {{/isOpenFeign}}name="${{braces "left"}}{{title}}.name:{{title}}{{braces "right"}}", url="${{braces "left"}}{{title}}.url:{{^wiremock}}{{basePath}}{{/wiremock}}{{#wiremock}}wiremock.base.path{{/wiremock}}{{braces "right"}}", configuration = ClientConfiguration.class) public interface {{classname}}Client extends {{classname}} { } diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-cloud/application-test.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-cloud/application-test.mustache index 49e253e9ae..bb1b707127 100644 --- a/src/main/resources/handlebars/JavaSpring/libraries/spring-cloud/application-test.mustache +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-cloud/application-test.mustache @@ -9,3 +9,7 @@ hystrix.command.default.execution.timeout.enabled: false logging.level.{{apiPackage}}: DEBUG feign.hystrix.enabled: true + +{{#wiremock}} +wiremock.base.path: http://localhost:33333 +{{/wiremock}} diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-cloud/pom.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-cloud/pom.mustache index ec0c8eeab3..6a68c8141c 100644 --- a/src/main/resources/handlebars/JavaSpring/libraries/spring-cloud/pom.mustache +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-cloud/pom.mustache @@ -6,7 +6,7 @@ {{artifactId}} {{artifactVersion}} - {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} ${java.version} ${java.version} {{#useOas2}} @@ -113,12 +113,22 @@ {{/threetenbp}} {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + {{/jakarta}} + {{^jakarta}} javax.validation validation-api 1.1.0.Final provided + {{/jakarta}} {{/useBeanValidation}} org.springframework.boot @@ -132,11 +142,28 @@ 2.10.1 {{/notNullJacksonAnnotation}} - + +{{#jakarta}} + + jakarta.servlet + jakarta-api + provided + +{{/jakarta}} +{{^jakarta}} javax.servlet javax.servlet-api provided +{{/jakarta}} + {{#wiremock}} + + com.github.tomakehurst + wiremock + 2.27.2 + test + + {{/wiremock}} diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-mvc/pom.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-mvc/pom.mustache index 46ab3155bc..764393a6bd 100644 --- a/src/main/resources/handlebars/JavaSpring/libraries/spring-mvc/pom.mustache +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-mvc/pom.mustache @@ -65,6 +65,24 @@ + {{#java11}} + + + jdk11 + + [11,) + + + + com.sun.xml.ws + jaxws-rt + 2.3.3 + pom + + + + + {{/java11}} org.slf4j @@ -157,19 +175,38 @@ ${junit-version} test +{{#jakarta}} + + jakarta.servlet + jakarta-api + ${servlet-api-version} + +{{/jakarta}} +{{^jakarta}} javax.servlet servlet-api ${servlet-api-version} +{{/jakarta}} {{#useBeanValidation}} + {{#jakarta}} + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + {{/jakarta}} + {{^jakarta}} javax.validation validation-api 1.1.0.Final provided + {{/jakarta}} {{/useBeanValidation}} org.testng @@ -206,13 +243,13 @@ - {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} ${java.version} ${java.version} 9.3.28.v20191105 1.7.21 4.13.1 - 2.5 + {{#jakarta}}6.0.0{{/jakarta}}{{^jakarta}}2.5{{/jakarta}} {{#useOas2}} 2.9.2 {{/useOas2}} @@ -221,6 +258,6 @@ {{/useOas2}} 2.9.10 2.9.10 - 5.0.18.RELEASE + 5.3.27 diff --git a/src/main/resources/handlebars/JavaSpring/libraries/spring-mvc/swaggerUiConfiguration.mustache b/src/main/resources/handlebars/JavaSpring/libraries/spring-mvc/swaggerUiConfiguration.mustache index 91fdef7acb..0da481857f 100644 --- a/src/main/resources/handlebars/JavaSpring/libraries/spring-mvc/swaggerUiConfiguration.mustache +++ b/src/main/resources/handlebars/JavaSpring/libraries/spring-mvc/swaggerUiConfiguration.mustache @@ -10,6 +10,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Bean; +import org.springframework.format.FormatterRegistry; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; @@ -92,6 +93,12 @@ public class SwaggerUiConfiguration extends WebMvcConfigurerAdapter { super.configureMessageConverters(converters); } + @Override + public void addFormatters(FormatterRegistry registry) { + registry.addConverter(new LocalDateConverter("{{#datePattern}}{{datePattern}}{{/datePattern}}{{^datePattern}}yyyy-MM-dd{{/datePattern}}")); + registry.addConverter(new LocalDateTimeConverter("{{#dateTimePattern}}{{dateTimePattern}}{{/dateTimePattern}}{{^dateTimePattern}}yyyy-MM-dd'T'HH:mm:ss.SSS{{/dateTimePattern}}")); + } + @Bean public ObjectMapper objectMapper(){ return builder().build(); diff --git a/src/main/resources/handlebars/JavaSpring/model.mustache b/src/main/resources/handlebars/JavaSpring/model.mustache index c0f606fb66..681b07890c 100644 --- a/src/main/resources/handlebars/JavaSpring/model.mustache +++ b/src/main/resources/handlebars/JavaSpring/model.mustache @@ -9,8 +9,14 @@ import java.io.Serializable; {{/serializableModel}} {{#useBeanValidation}} import org.springframework.validation.annotation.Validated; +{{#jakarta}} +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +{{/jakarta}} +{{^jakarta}} import javax.validation.Valid; import javax.validation.constraints.*; +{{/jakarta}} {{/useBeanValidation}} {{#jackson}} {{#withXml}} @@ -19,7 +25,12 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; {{/withXml}} {{/jackson}} {{#withXml}} +{{#jakarta}} +import jakarta.xml.bind.annotation.*; +{{/jakarta}} +{{^jakarta}} import javax.xml.bind.annotation.*; +{{/jakarta}} {{/withXml}} {{/x-is-composed-model}} diff --git a/src/main/resources/handlebars/JavaSpring/swaggerDocumentationConfig.mustache b/src/main/resources/handlebars/JavaSpring/swaggerDocumentationConfig.mustache index 544600aed9..c251cfe49c 100644 --- a/src/main/resources/handlebars/JavaSpring/swaggerDocumentationConfig.mustache +++ b/src/main/resources/handlebars/JavaSpring/swaggerDocumentationConfig.mustache @@ -3,12 +3,14 @@ package {{configPackage}}; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +{{#useOas2}} import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.service.ApiInfo; +{{/useOas2}} {{^useOas2}} import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; @@ -22,14 +24,11 @@ import java.util.Optional; @Configuration public class SwaggerDocumentationConfig { + {{#useOas2}} @Bean public Docket customImplementation(){ - {{#useOas2}} + return new Docket(DocumentationType.SWAGGER_2) - {{/useOas2}} - {{^useOas2}} - return new Docket(DocumentationType.OAS_30) - {{/useOas2}} .select() .apis(RequestHandlerSelectors.basePackage("{{apiPackage}}")) .build() @@ -62,8 +61,8 @@ public class SwaggerDocumentationConfig { .contact(new Contact("","", "{{infoEmail}}")) .build(); } - -{{^useOas2}} + {{/useOas2}} + {{^useOas2}} @Bean public OpenAPI openApi() { return new OpenAPI() @@ -78,6 +77,6 @@ public class SwaggerDocumentationConfig { .contact(new io.swagger.v3.oas.models.info.Contact() .email("{{infoEmail}}"))); } -{{/useOas2}} + {{/useOas2}} } diff --git a/src/main/resources/handlebars/JavaVertXServer/DataObjectMapper.mustache b/src/main/resources/handlebars/JavaVertXServer/DataObjectMapper.mustache new file mode 100644 index 0000000000..9126854940 --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/DataObjectMapper.mustache @@ -0,0 +1,55 @@ +package {{modelPackage}}; + +{{#java8}} +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +{{/java8}} +{{#threetenbp}} +import org.threeten.bp.Instant; +import org.threeten.bp.OffsetDateTime; +import org.threeten.bp.ZonedDateTime; +{{/threetenbp}} +{{#joda}} +import org.joda.time.LocalDate; +import org.joda.time.DateTime; +{{/joda}} + +public class DataObjectMapper { + {{#java8}} + public static String serializeOffsetDateTime(OffsetDateTime value) { + return value.toString(); + } + + public static String serializeLocalDateTime(LocalDateTime value) { + return value.toString(); + } + + public static String serializeLocalDate(LocalDate value) { + return value.toString(); + } + {{/java8}} + {{#threetenbp}} + public static String serializeThreetenbpInstant(org.threeten.bp.Instant value) { + return value.toString(); + } + + public static String serializeThreetenbpOffsetDateTime(org.threeten.bp.OffsetDateTime value) { + return value.toString(); + } + + public static String serializeThreetenbpZonedDateTime(org.threeten.bp.ZonedDateTime value) { + return value.toString(); + } + {{/threetenbp}} + {{#joda}} + public static String serializeJodaLocalDate(org.joda.time.LocalDate value) { + return value.toString(); + } + + public static String serializeJodaDateTime(org.joda.time.DateTime value) { + return value.toString(); + } + {{/joda}} + +} diff --git a/src/main/resources/handlebars/JavaVertXServer/MainApiVerticle.mustache b/src/main/resources/handlebars/JavaVertXServer/MainApiVerticle.mustache new file mode 100644 index 0000000000..be3c5c1c62 --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/MainApiVerticle.mustache @@ -0,0 +1,36 @@ +package {{rootPackage}}; + +{{#rxInterface}} +import io.reactivex.Completable; +import io.vertx.reactivex.core.AbstractVerticle; +{{/rxInterface}} +{{^rxInterface}} +import io.vertx.core.AbstractVerticle; +import io.vertx.core.Promise; +{{/rxInterface}} +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MainApiVerticle extends AbstractVerticle { + static final Logger LOGGER = LoggerFactory.getLogger(MainApiVerticle.class); + + @Override + {{^rxInterface}}public void start(Promise startPromise) throws Exception { + vertx.deployVerticle("{{verticlePackage}}.{{title}}Verticle") + .onFailure(error -> { + LOGGER.error("{{title}}Verticle : Deployment failed"); + startPromise.fail(error); + }) + .onSuccess(server -> { + LOGGER.info("{{title}}Verticle : Deployed"); + startPromise.complete(); + }); + }{{/rxInterface}} + {{#rxInterface}}public Completable rxStart() { + return vertx.rxDeployVerticle("{{verticlePackage}}.{{title}}Verticle") + .doOnError(error -> LOGGER.error("{{title}}Verticle : Deployment failed")) + .doOnSuccess(server -> LOGGER.info("{{title}}Verticle : Deployed")) + .ignoreElement(); + }{{/rxInterface}} + +} diff --git a/src/main/resources/handlebars/JavaVertXServer/README.mustache b/src/main/resources/handlebars/JavaVertXServer/README.mustache new file mode 100644 index 0000000000..ac03f0bc7c --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/README.mustache @@ -0,0 +1 @@ +Project generated on : {{generatedDate}} diff --git a/src/main/resources/handlebars/JavaVertXServer/api.mustache b/src/main/resources/handlebars/JavaVertXServer/api.mustache new file mode 100644 index 0000000000..c2a2b1de84 --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/api.mustache @@ -0,0 +1,37 @@ +package {{package}}; + +{{#imports}}import {{import}}; +{{/imports}} + +{{#useFuture}} +import io.vertx.core.Future; +{{/useFuture}} +{{^useFuture}} +import io.vertx.core.Handler; +import io.vertx.core.AsyncResult; +{{/useFuture}} +import io.vertx.ext.web.validation.RequestParameter; +import io.vertx.ext.web.api.service.ServiceRequest; +import io.vertx.ext.web.api.service.ServiceResponse; +{{#mountFromExtensions}} +import io.vertx.ext.web.api.service.WebApiServiceGen; +{{/mountFromExtensions}} + +import java.util.List; +import java.util.Map; + +{{#mountFromExtensions}}@WebApiServiceGen{{/mountFromExtensions}} +public interface {{classname}} { + +{{#operations}}{{#operation}}{{#@first}} String WEBSERVICE_ADDRESS_{{#lambda.uppercase}}{{classname}}{{/lambda.uppercase}} = "{{#mountFromExtensions}}{{#vendorExtensions}}{{x-event-bus-address}}{{/vendorExtensions}}{{/mountFromExtensions}}{{#mountFromInterface}}{{baseName}}.address{{/mountFromInterface}}";{{/@first}}{{/operation}}{{/operations}} +{{#operations}}{{#operation}} String OPERATION_ID_{{#lambda.uppercase}}{{operationId}}{{/lambda.uppercase}} = "{{operationId}}"; +{{/operation}}{{/operations}} + +{{#operations}} +{{#operation}} +{{#contents}} + {{#useFuture}}Future{{/useFuture}}{{^useFuture}}void{{/useFuture}} {{#vendorExtensions}}{{x-serviceid}}{{/vendorExtensions}}({{#useDataObject}}{{#parameters}}{{^isBodyParam}}{{^isEnum}}{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}{{/isEnum}}{{#isEnum}}{{{dataType}}}{{/isEnum}} {{paramName}}{{/isBodyParam}}{{#isBodyParam}}{{^isBinary}}{{^parent}}{{^children}}{{{dataType}}} body{{/children}}{{/parent}}{{/isBinary}}{{/isBodyParam}}{{#hasMore}}{{^isBinary}}, {{/isBinary}}{{/hasMore}}{{^hasMore}}{{^isBinary}}, {{/isBinary}}{{/hasMore}}{{/parameters}}{{/useDataObject}}{{^useDataObject}}RequestParameter body, {{/useDataObject}}ServiceRequest request{{^useFuture}}, Handler> resultHandler{{/useFuture}}); +{{/contents}} +{{/operation}} +{{/operations}} +} diff --git a/src/main/resources/handlebars/JavaVertXServer/apiVerticle.mustache b/src/main/resources/handlebars/JavaVertXServer/apiVerticle.mustache new file mode 100644 index 0000000000..cbdda4c679 --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/apiVerticle.mustache @@ -0,0 +1,92 @@ +package {{verticlePackage}}; + +{{#mountFromInterface}}{{#apiInfo}}{{#apis}}import {{{package}}}.{{{classFilename}}}; +import static {{{package}}}.{{{classFilename}}}.WEBSERVICE_ADDRESS_{{#lambda.uppercase}}{{{classFilename}}}{{/lambda.uppercase}}; +{{/apis}}{{/apiInfo}}{{/mountFromInterface}} + +{{#rxInterface}} +import io.reactivex.Completable; +import io.vertx.reactivex.core.AbstractVerticle; +import io.vertx.reactivex.core.eventbus.MessageConsumer; +import io.vertx.reactivex.core.http.HttpServer; +import io.vertx.reactivex.ext.web.Router; +import io.vertx.reactivex.ext.web.openapi.RouterBuilder; +{{/rxInterface}} +{{^rxInterface}} +import io.vertx.core.AbstractVerticle; +import io.vertx.core.Future; +import io.vertx.core.Promise; +import io.vertx.core.http.HttpServer; +import io.vertx.ext.web.Router; +import io.vertx.ext.web.openapi.RouterBuilder; +{{/rxInterface}} +import io.vertx.core.http.HttpServerOptions; +import io.vertx.core.json.JsonObject; +import io.vertx.ext.web.openapi.RouterBuilderOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class {{title}}Verticle extends AbstractVerticle { + static final Logger LOGGER = LoggerFactory.getLogger({{title}}Verticle.class); + + HttpServer server; + + @Override + {{^rxInterface}}public void start(Promise startPromise) throws Exception { + RouterBuilder.create(this.vertx, "{{specLocation}}") + .flatMap(routerBuilder -> { {{/rxInterface}} + {{#rxInterface}}public Completable rxStart() { + return RouterBuilder.rxCreate(this.vertx, "{{specLocation}}") + .map(routerBuilder -> { {{/rxInterface}} + RouterBuilderOptions factoryOptions = new RouterBuilderOptions() + .setRequireSecurityHandlers(false) + .setMountResponseContentTypeHandler(true); + routerBuilder.setOptions(factoryOptions); + +{{#mountFromExtensions}} routerBuilder.mountServicesFromExtensions();{{/mountFromExtensions}} +{{#mountFromInterface}}{{#apiInfo}}{{#apis}} routerBuilder.mountServiceInterface({{{classFilename}}}.class, WEBSERVICE_ADDRESS_{{#lambda.uppercase}}{{{classFilename}}}{{/lambda.uppercase}}); + {{/apis}}{{/apiInfo}}{{/mountFromInterface}} + + return {{#rxInterface}}routerBuilder.createRouter(){{/rxInterface}}{{^rxInterface}}Future.succeededFuture(routerBuilder.createRouter()){{/rxInterface}}; + }) + .flatMap(openapiRouter -> { + Router router = Router.router(vertx); + + server = vertx.createHttpServer(new HttpServerOptions().setPort({{serverPort}}).setHost("localhost")) + .requestHandler(router); + + router.route("/*").subRouter(openapiRouter); + + router.route().last().handler(context -> + context.response() + .setStatusCode(404) + .end(new JsonObject() + .put("message", "Resource not found") + .encode()) + ); + + {{#rxInterface}}return server.rxListen() + .doOnSuccess(server -> LOGGER.info("SwaggerPetstoreVerticle started on port " + server.actualPort())); + }) + .ignoreElement(); + } + + @Override + public Completable rxStop() { + return this.server.rxClose(); + }{{/rxInterface}} + {{^rxInterface}}return server.listen() + .onSuccess(server -> LOGGER.info("{{title}}Verticle started on port " + server.actualPort())); + }) + .onSuccess(server -> startPromise.complete()) + .onFailure(startPromise::fail); + } + + @Override + public void stop(Promise stopPromise) throws Exception { + this.server.close() + .onSuccess(server -> stopPromise.complete()) + .onFailure(stopPromise::fail); + }{{/rxInterface}} + +} diff --git a/src/main/resources/handlebars/JavaVertXServer/beanValidation.mustache b/src/main/resources/handlebars/JavaVertXServer/beanValidation.mustache new file mode 100644 index 0000000000..3e4ef612a4 --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/beanValidation.mustache @@ -0,0 +1,6 @@ +{{#required}} + @NotNull +{{/required}}{{#isContainer}}{{^isPrimitiveType}}{{^isEnum}} + @Valid{{/isEnum}}{{/isPrimitiveType}}{{/isContainer}}{{#isNotContainer}}{{^isPrimitiveType}} + @Valid{{/isPrimitiveType}}{{/isNotContainer}} +{{>beanValidationCore}} diff --git a/src/main/resources/handlebars/JavaVertXServer/beanValidationCore.mustache b/src/main/resources/handlebars/JavaVertXServer/beanValidationCore.mustache new file mode 100644 index 0000000000..29d043cc77 --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/beanValidationCore.mustache @@ -0,0 +1,20 @@ +{{#pattern}}@Pattern(regexp="{{{pattern}}}"{{#vendorExtensions.x-pattern-message}}, message="{{vendorExtensions.x-pattern-message}}"{{/vendorExtensions.x-pattern-message}}) {{/pattern}}{{! +minLength && maxLength set +}}{{#minLength}}{{#maxLength}}@Size(min={{minLength}},max={{maxLength}}) {{/maxLength}}{{/minLength}}{{! +minLength set, maxLength not +}}{{#minLength}}{{^maxLength}}@Size(min={{minLength}}) {{/maxLength}}{{/minLength}}{{! +minLength not set, maxLength set +}}{{^minLength}}{{#maxLength}}@Size(max={{maxLength}}) {{/maxLength}}{{/minLength}}{{! +@Size: minItems && maxItems set +}}{{#minItems}}{{#maxItems}}@Size(min={{minItems}},max={{maxItems}}) {{/maxItems}}{{/minItems}}{{! +@Size: minItems set, maxItems not +}}{{#minItems}}{{^maxItems}}@Size(min={{minItems}}) {{/maxItems}}{{/minItems}}{{! +@Size: minItems not set && maxItems set +}}{{^minItems}}{{#maxItems}}@Size(max={{maxItems}}) {{/maxItems}}{{/minItems}}{{! +check for integer or long / all others=decimal type with @Decimal* +isInteger set +}}{{#isInteger}}{{#minimum}}@Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}) {{/maximum}}{{/isInteger}}{{! +isLong set +}}{{#isLong}}{{#minimum}}@Min({{minimum}}L){{/minimum}}{{#maximum}} @Max({{maximum}}L) {{/maximum}}{{/isLong}}{{! +Not Integer, not Long => we have a decimal value! +}}{{^isInteger}}{{^isLong}}{{#minimum}}@DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}") {{/maximum}}{{/isLong}}{{/isInteger}} \ No newline at end of file diff --git a/src/main/resources/handlebars/JavaVertXServer/enumClass.mustache b/src/main/resources/handlebars/JavaVertXServer/enumClass.mustache new file mode 100644 index 0000000000..17981cd6d2 --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/enumClass.mustache @@ -0,0 +1,35 @@ + /** + * {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}} + */ + public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { + {{#allowableValues}}{{#enumVars}}{{{name}}}({{{value}}}){{^@last}}, + {{/@last}}{{#@last}};{{/@last}}{{/enumVars}}{{/allowableValues}} + + private {{{datatype}}} value; + + {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}({{{datatype}}} value) { + this.value = value; + } + + public {{{datatype}}} getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue({{{datatype}}} value) { + for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) { + if (b.value.equals(value)) { + return b; + } + } + {{^errorOnUnknownEnum}}return null;{{/errorOnUnknownEnum}}{{#errorOnUnknownEnum}}throw new IllegalArgumentException("Unexpected value '" + value + "' for '{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}' enum.");{{/errorOnUnknownEnum}} + } + {{#useDataObject}} + public static {{{datatype}}} serialize({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} enumValue) { + return enumValue.getValue(); + }{{/useDataObject}} + } diff --git a/src/main/resources/handlebars/JavaVertXServer/enumOuterClass.mustache b/src/main/resources/handlebars/JavaVertXServer/enumOuterClass.mustache new file mode 100644 index 0000000000..f90c462a72 --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/enumOuterClass.mustache @@ -0,0 +1,35 @@ +/** + * {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}} + */ +public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} { + {{#allowableValues}}{{#enumVars}}{{{name}}}({{{value}}}){{^@last}}, + {{/@last}}{{#@last}};{{/@last}}{{/enumVars}}{{/allowableValues}} + + private {{{dataType}}} value; + + {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}({{{dataType}}} value) { + this.value = value; + } + + public {{{dataType}}} getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue({{{dataType}}} value) { + for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) { + if (b.value.equals(value)) { + return b; + } + } + {{^errorOnUnknownEnum}}return null;{{/errorOnUnknownEnum}}{{#errorOnUnknownEnum}}throw new IllegalArgumentException("Unexpected value '" + value + "' for '{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}' enum.");{{/errorOnUnknownEnum}} + } + {{#useDataObject}} + public static {{{dataType}}} serialize({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} enumValue) { + return enumValue.getValue(); + }{{/useDataObject}} +} diff --git a/src/main/resources/handlebars/JavaVertXServer/generatedAnnotation.mustache b/src/main/resources/handlebars/JavaVertXServer/generatedAnnotation.mustache new file mode 100644 index 0000000000..64e613df8c --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/generatedAnnotation.mustache @@ -0,0 +1,3 @@ +{{^hideGenerationTimestamp}} +@{{#jakarta}}jakarta{{/jakarta}}{{^jakarta}}javax{{/jakarta}}.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}") +{{/hideGenerationTimestamp}} diff --git a/src/main/resources/handlebars/JavaVertXServer/json-mappers.mustache b/src/main/resources/handlebars/JavaVertXServer/json-mappers.mustache new file mode 100644 index 0000000000..a15f23ed1a --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/json-mappers.mustache @@ -0,0 +1,38 @@ +{{#models}} +{{#model}} +{{#isEnum}} +{{modelPackage}}.{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.serializer={{modelPackage}}.{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}#serialize +{{modelPackage}}.{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.deserializer={{modelPackage}}.{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}#fromValue +{{/isEnum}} +{{^isEnum}} + {{#vars}} + {{#isEnum}} +{{modelPackage}}.{{classname}}.{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.serializer={{modelPackage}}.{{classname}}.{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}#serialize +{{modelPackage}}.{{classname}}.{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.deserializer={{modelPackage}}.{{classname}}.{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}#fromValue + {{/isEnum}} + {{/vars}} +{{/isEnum}} +{{/model}} +{{/models}} +{{#java8}} +java.time.LocalDate.serializer={{modelPackage}}.DataObjectMapper#serializeLocalDate +java.time.LocalDate.deserializer=java.time.LocalDate#parse +java.time.LocalDateTime.serializer={{modelPackage}}.DataObjectMapper#serializeLocalDateTime +java.time.LocalDateTime.deserializer=java.time.LocalDateTime#parse +java.time.OffsetDateTime.serializer={{modelPackage}}.DataObjectMapper#serializeOffsetDateTime +java.time.OffsetDateTime.deserializer=java.time.OffsetDateTime#parse +{{/java8}} +{{#threetenbp}} +org.threeten.bp.Instant.serializer={{modelPackage}}.DataObjectMapper#serializeThreetenbpInstant +org.threeten.bp.Instant.deserializer=org.threeten.bp.Instant#parse +org.threeten.bp.OffsetDateTime.serializer={{modelPackage}}.DataObjectMapper#serializeThreetenbpOffsetDateTime +org.threeten.bp.OffsetDateTime.deserializer=org.threeten.bp.OffsetDateTime#parse +org.threeten.bp.ZonedDateTime.serializer={{modelPackage}}.DataObjectMapper#serializeThreetenbpZonedDateTime +org.threeten.bp.ZonedDateTime.deserializer=org.threeten.bp.ZonedDateTime#parse +{{/threetenbp}} +{{#joda}} +org.joda.time.LocalDate.serializer={{modelPackage}}.DataObjectMapper#serializeJodaLocalDate +org.joda.time.LocalDate.deserializer=org.joda.time.LocalDate#parse +org.joda.time.DateTime.serializer={{modelPackage}}.DataObjectMapper#serializeJodaDateTime +org.joda.time.DateTime.deserializer=org.joda.time.DateTime#parse +{{/joda}} diff --git a/src/main/resources/handlebars/JavaVertXServer/model.mustache b/src/main/resources/handlebars/JavaVertXServer/model.mustache new file mode 100644 index 0000000000..4ae1bca668 --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/model.mustache @@ -0,0 +1,37 @@ +package {{package}}; + +{{^x-is-composed-model}} +import java.util.Objects; +{{#imports}}import {{import}}; +{{/imports}} +{{#serializableModel}} +import java.io.Serializable; +{{/serializableModel}} +{{#useBeanValidation}} +{{#jakarta}} +import jakarta.validation.constraints.*; +import jakarta.validation.Valid; +{{/jakarta}} +{{^jakarta}} +import javax.validation.constraints.*; +import javax.validation.Valid; +{{/jakarta}} +{{/useBeanValidation}} +{{/x-is-composed-model}} +import io.vertx.core.json.JsonObject; +import io.vertx.codegen.annotations.DataObject; +{{#models}} +{{#model}} +{{#isComposedModel}} +{{>interface}} +{{/isComposedModel}} +{{^isComposedModel}} +{{#isEnum}} +{{>enumOuterClass}} +{{/isEnum}} +{{^isEnum}} +{{>pojo}} +{{/isEnum}} +{{/isComposedModel}} +{{/model}} +{{/models}} diff --git a/src/main/resources/handlebars/JavaVertXServer/package-info-model.mustache b/src/main/resources/handlebars/JavaVertXServer/package-info-model.mustache new file mode 100644 index 0000000000..4d5382212e --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/package-info-model.mustache @@ -0,0 +1,4 @@ +@ModuleGen(name = "model", groupPackage = "{{modelPackage}}") +package {{modelPackage}}; + +import io.vertx.codegen.annotations.ModuleGen; diff --git a/src/main/resources/handlebars/JavaVertXServer/package-info-service.mustache b/src/main/resources/handlebars/JavaVertXServer/package-info-service.mustache new file mode 100644 index 0000000000..af43bd8038 --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/package-info-service.mustache @@ -0,0 +1,4 @@ +@ModuleGen(name = "service", groupPackage = "{{apiPackage}}", useFutures = {{#useFuture}}true{{/useFuture}}{{^useFuture}}false{{/useFuture}}) +package {{apiPackage}}; + +import io.vertx.codegen.annotations.ModuleGen; diff --git a/src/main/resources/handlebars/JavaVertXServer/pojo.mustache b/src/main/resources/handlebars/JavaVertXServer/pojo.mustache new file mode 100644 index 0000000000..930b070c71 --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/pojo.mustache @@ -0,0 +1,147 @@ +/** + * {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} + */ +{{#useBeanValidation}}@Valid{{/useBeanValidation}} +{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}} +{{#notNullJacksonAnnotation}}@JsonInclude(JsonInclude.Include.NON_NULL){{/notNullJacksonAnnotation}} +{{#useDataObject}}@DataObject(generateConverter = true, publicConverter = false){{/useDataObject}} + +public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#serializableModel}}implements Serializable {{#interfaceModels}}, {{classname}}{{^@last}}, {{/@last}}{{#@last}} {{/@last}}{{/interfaceModels}}{{/serializableModel}}{{^serializableModel}}{{#interfaceModels}}{{#@first}}implements {{/@first}}{{classname}}{{^@last}}, {{/@last}}{{#@last}}{{/@last}}{{/interfaceModels}}{{/serializableModel}} { +{{#serializableModel}} + private static final long serialVersionUID = 1L; + +{{/serializableModel}} + {{#vars}} + {{#baseItems this}} + {{#isEnum}} +{{>enumClass}} + {{/isEnum}} + {{/baseItems}} + {{#jackson}} + {{#vendorExtensions.x-is-discriminator-property}} + @JsonTypeId + {{/vendorExtensions.x-is-discriminator-property}} + {{^vendorExtensions.x-is-discriminator-property}} + @JsonProperty("{{baseName}}") + {{/vendorExtensions.x-is-discriminator-property}} + {{/jackson}} + {{#isContainer}} + {{#useBeanValidation}}@Valid{{/useBeanValidation}} + private {{{datatypeWithEnum}}} {{name}}{{#required}} = {{{defaultValue}}}{{/required}}{{^required}} = null{{/required}}; + {{/isContainer}} + {{^isContainer}} + private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}}; + {{/isContainer}} + + {{/vars}} +{{#useDataObject}} + public {{classname}}(JsonObject json) { + {{#parent}}{{#hasVars}}super(json);{{/hasVars}}{{/parent}} + {{classname}}Converter.fromJson(json, this); + } + + public JsonObject toJson() { + JsonObject json = new JsonObject(); + {{classname}}Converter.toJson(this, json); + return json; + } +{{/useDataObject}} + {{#vars}} + public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) { + this.{{name}} = {{name}}; + return this; + } + {{#isListContainer}} + + public {{classname}} add{{nameInCamelCase}}Item({{{items.datatypeWithEnum}}} {{name}}Item) { + {{^required}} + if (this.{{name}} == null) { + this.{{name}} = {{{defaultValue}}}; + } + {{/required}} + this.{{name}}.add({{name}}Item); + return this; + } + {{/isListContainer}} + {{#isMapContainer}} + + public {{classname}} put{{nameInCamelCase}}Item(String key, {{{items.datatypeWithEnum}}} {{name}}Item) { + {{^required}} + if (this.{{name}} == null) { + this.{{name}} = {{{defaultValue}}}; + } + {{/required}} + this.{{name}}.put(key, {{name}}Item); + return this; + } + {{/isMapContainer}} + + /** + {{#description}} + * {{{description}}} + {{/description}} + {{^description}} + * Get {{name}} + {{/description}} + {{#minimum}} + * minimum: {{minimum}} + {{/minimum}} + {{#maximum}} + * maximum: {{maximum}} + {{/maximum}} + * @return {{name}} + **/ + {{#vendorExtensions.extraAnnotation}} + {{{vendorExtensions.extraAnnotation}}} + {{/vendorExtensions.extraAnnotation}} + {{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}} public {{{datatypeWithEnum}}} {{getter}}() { + return {{name}}; + } + + public void {{setter}}({{{datatypeWithEnum}}} {{name}}) { + this.{{name}} = {{name}}; + } + + {{/vars}} + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + }{{#hasVars}} + {{classname}} {{classVarName}} = ({{classname}}) o; + return {{#vars}}Objects.equals(this.{{name}}, {{classVarName}}.{{name}}){{#hasMore}} && + {{/hasMore}}{{/vars}}{{#parent}} && + super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}} + return true;{{/hasVars}} + } + + @Override + public int hashCode() { + return Objects.hash({{#vars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}}); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class {{classname}} {\n"); + {{#parent}}sb.append(" ").append(toIndentedString(super.toString())).append("\n");{{/parent}} + {{#vars}}sb.append(" {{name}}: ").append(toIndentedString({{name}})).append("\n"); + {{/vars}}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(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/src/main/resources/handlebars/JavaVertXServer/pom.mustache b/src/main/resources/handlebars/JavaVertXServer/pom.mustache new file mode 100644 index 0000000000..e1127c0993 --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/pom.mustache @@ -0,0 +1,156 @@ + + 4.0.0 + + {{groupId}} + {{artifactId}} + {{artifactVersion}} + jar + + {{appName}} + + + UTF-8 + {{#java11}}11{{/java11}}{{^java11}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/java11}} + 5.9.1 + 4.4.1 + 3.8.1 + 3.2.4 + 2.14.2 + 2.12.5 + 2.0.6 + + + + + + io.vertx + vertx-web-openapi + ${vertx.version} + + + io.vertx + vertx-web-api-service + ${vertx.version} + + {{#rxInterface}} + + io.vertx + vertx-rx-java2 + ${vertx.version} + + {{/rxInterface}} + + org.slf4j + slf4j-api + ${slf4j-version} + + + + io.vertx + vertx-codegen + ${vertx.version} + provided + + + + io.vertx + vertx-codegen + ${vertx.version} + processor + + + {{#java8}} + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson.version} + + {{/java8}} + {{#joda}} + + com.fasterxml.jackson.datatype + jackson-datatype-joda + ${jackson.version} + + {{/joda}} + {{#threetenbp}} + + com.github.joschi.jackson + jackson-datatype-threetenbp + ${joschi.version} + + {{/threetenbp}} + + {{#useBeanValidation}} + + + jakarta.validation + jakarta.validation-api + {{#jakarta}}3.0.2{{/jakarta}}{{^jakarta}}2.0.2{{/jakarta}} + + {{/useBeanValidation}} + {{#notNullJacksonAnnotation}} + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + {{/notNullJacksonAnnotation}} + + + io.vertx + vertx-junit5 + ${vertx.version} + test + + + + org.junit.jupiter + junit-jupiter + ${jupiter.version} + test + + + + + + + + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + ${java.version} + + + + + org.apache.maven.plugins + maven-shade-plugin + ${maven-shade-plugin.version} + + + package + + shade + + + + + + io.vertx.core.Launcher + {{rootPackage}}.MainApiVerticle + + + + + ${project.build.directory}/${project.artifactId}-${project.version}-fat.jar + + + + + + + diff --git a/src/main/resources/handlebars/JavaVertXServer/typeInfoAnnotation.mustache b/src/main/resources/handlebars/JavaVertXServer/typeInfoAnnotation.mustache new file mode 100644 index 0000000000..f3ed515976 --- /dev/null +++ b/src/main/resources/handlebars/JavaVertXServer/typeInfoAnnotation.mustache @@ -0,0 +1,14 @@ +{{#jackson}} +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator.propertyName}}", visible = true ) +@JsonSubTypes({ + {{#if discriminator.mapping}} + {{#each discriminator.mapping}} + @JsonSubTypes.Type(value = {{this}}.class, name = "{{@key}}"), + {{/each}} + {{else}} + {{#children}} + @JsonSubTypes.Type(value = {{classname}}.class, name = "{{name}}"), + {{/children}} + {{/if}} +}) +{{/jackson}} \ No newline at end of file diff --git a/src/main/resources/handlebars/aspnetcore/3.0/Project.csproj.mustache b/src/main/resources/handlebars/aspnetcore/3.0/Project.csproj.mustache index 82f6e1a838..c841ad7c41 100644 --- a/src/main/resources/handlebars/aspnetcore/3.0/Project.csproj.mustache +++ b/src/main/resources/handlebars/aspnetcore/3.0/Project.csproj.mustache @@ -10,9 +10,9 @@ - - - + + + diff --git a/src/main/resources/handlebars/aspnetcore/3.1/Project.csproj.mustache b/src/main/resources/handlebars/aspnetcore/3.1/Project.csproj.mustache index 930c1a5685..845f036303 100644 --- a/src/main/resources/handlebars/aspnetcore/3.1/Project.csproj.mustache +++ b/src/main/resources/handlebars/aspnetcore/3.1/Project.csproj.mustache @@ -2,18 +2,18 @@ {{packageName}} {{packageName}} - netcoreapp{{aspNetCoreVersion}} + {{targetFramework}} true true {{packageName}} {{packageName}} - - - - - + + + + + diff --git a/src/main/resources/handlebars/aspnetcore/NuGet.Config b/src/main/resources/handlebars/aspnetcore/NuGet.Config index 01f3d1f203..5db080cb7d 100644 --- a/src/main/resources/handlebars/aspnetcore/NuGet.Config +++ b/src/main/resources/handlebars/aspnetcore/NuGet.Config @@ -3,7 +3,6 @@ - diff --git a/src/main/resources/handlebars/aspnetcore/model.mustache b/src/main/resources/handlebars/aspnetcore/model.mustache index b1fbc3722a..4711055e90 100644 --- a/src/main/resources/handlebars/aspnetcore/model.mustache +++ b/src/main/resources/handlebars/aspnetcore/model.mustache @@ -13,12 +13,14 @@ using Newtonsoft.Json; {{#models}} {{#model}} namespace {{packageName}}.Models -{ {{#isEnum}}{{>enumClass}}{{/isEnum}}{{^isEnum}} +{ + {{^isComposedModel}} + {{#isEnum}}{{>enumClass}}{{/isEnum}}{{^isEnum}} ///

/// {{description}} /// [DataContract] - public partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}}IEquatable<{{classname}}> + public partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}}IEquatable<{{classname}}>{{#interfaceModels}}{{#@first}}, {{/@first}}{{classname}}{{^@last}}, {{/@last}}{{#@last}} {{/@last}}{{/interfaceModels}} { {{#vars}}{{#isEnum}}{{^isContainer}}{{>enumClass}}{{/isContainer}}{{/isEnum}}{{#items.isEnum}}{{#items}}{{^isContainer}}{{>enumClass}}{{/isContainer}}{{/items}}{{/items.isEnum}} /// /// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}} @@ -101,7 +103,7 @@ namespace {{packageName}}.Models {{name}} == other.{{name}} || {{name}} != null && {{name}}.SequenceEqual(other.{{name}}) - ){{#hasMore}} && {{/hasMore}}{{/isNotContainer}}{{/vars}}{{^vars}}false{{/vars}}; + ){{#hasMore}} && {{/hasMore}}{{/isNotContainer}}{{/vars}}{{^vars}}false{{/vars}}{{#parent}} && base.Equals(other){{/parent}}; } /// @@ -139,6 +141,20 @@ namespace {{packageName}}.Models #endregion Operators } {{/isEnum}} +{{/isComposedModel}} +{{#isComposedModel}} + /// + /// {{description}} + /// + public interface {{{classname}}} + { + {{#vendorExtensions}} + {{#x-discriminator-type-getter}} + {{x-discriminator-type}} {{x-discriminator-type-getter}}(); + {{/x-discriminator-type-getter}} + {{/vendorExtensions}} + } +{{/isComposedModel}} {{/model}} {{/models}} } diff --git a/src/main/resources/handlebars/csharp/interface.mustache b/src/main/resources/handlebars/csharp/interface.mustache new file mode 100644 index 0000000000..9158acb850 --- /dev/null +++ b/src/main/resources/handlebars/csharp/interface.mustache @@ -0,0 +1,12 @@ +/// +/// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} +/// +public interface {{{classname}}} +{ + +{{#vendorExtensions}} +{{#x-discriminator-type-getter}} + {{x-discriminator-type}} {{x-discriminator-type-getter}}(); +{{/x-discriminator-type-getter}} +{{/vendorExtensions}} +} diff --git a/src/main/resources/handlebars/csharp/model.mustache b/src/main/resources/handlebars/csharp/model.mustache index 9f49989303..7d562abbe7 100644 --- a/src/main/resources/handlebars/csharp/model.mustache +++ b/src/main/resources/handlebars/csharp/model.mustache @@ -1,4 +1,5 @@ {{>partial_header}} +{{^x-is-composed-model}} using System; using System.Linq; using System.IO; @@ -27,12 +28,17 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; {{/netStandard}} using SwaggerDateConverter = {{packageName}}.Client.SwaggerDateConverter; - +{{/x-is-composed-model}} {{#models}} {{#model}} namespace {{packageName}}.{{modelPackage}} { +{{#isComposedModel}} + {{>interface}} +{{/isComposedModel}} +{{^isComposedModel}} {{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{>modelGeneric}}{{/isEnum}} +{{/isComposedModel}} {{/model}} {{/models}} } diff --git a/src/main/resources/handlebars/csharp/modelGeneric.mustache b/src/main/resources/handlebars/csharp/modelGeneric.mustache index 43adaffee6..6168a7ccb9 100644 --- a/src/main/resources/handlebars/csharp/modelGeneric.mustache +++ b/src/main/resources/handlebars/csharp/modelGeneric.mustache @@ -9,7 +9,7 @@ {{#generatePropertyChanged}} [ImplementPropertyChanged] {{/generatePropertyChanged}} - {{>visibility}} partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}>{{^netStandard}}{{#validatable}}, IValidatableObject{{/validatable}}{{/netStandard}} + {{>visibility}} partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}>{{^netStandard}}{{#validatable}}, IValidatableObject{{/validatable}}{{/netStandard}}{{#interfaceModels}}{{#@first}}, {{/@first}}{{classname}}{{^@last}}, {{/@last}}{{#@last}} {{/@last}}{{/interfaceModels}} { {{#vars}} {{#items.isEnum}} diff --git a/src/main/resources/handlebars/csharp/nuspec.mustache b/src/main/resources/handlebars/csharp/nuspec.mustache index e061877340..0585152685 100644 --- a/src/main/resources/handlebars/csharp/nuspec.mustache +++ b/src/main/resources/handlebars/csharp/nuspec.mustache @@ -30,7 +30,7 @@ - + {{#generatePropertyChanged}} diff --git a/src/main/resources/handlebars/dart/api_client.mustache b/src/main/resources/handlebars/dart/api_client.mustache index 8195bb9dd9..f20af46c7b 100644 --- a/src/main/resources/handlebars/dart/api_client.mustache +++ b/src/main/resources/handlebars/dart/api_client.mustache @@ -105,7 +105,7 @@ class ApiClient { _updateParamsForAuth(authNames, queryParams, headerParams); - var ps = queryParams.where((p) => p.value != null).map((p) => '${p.name}=${p.value}'); + var ps = queryParams.where((p) => p.value != null).map((p) => '${Uri.encodeComponent(p.name)}=${Uri.encodeComponent(p.value)}'); String queryString = ps.isNotEmpty ? '?' + ps.join('&') : ''; diff --git a/src/main/resources/handlebars/htmlDocs/index.mustache b/src/main/resources/handlebars/htmlDocs/index.mustache index 42803c1435..6d2c20019f 100644 --- a/src/main/resources/handlebars/htmlDocs/index.mustache +++ b/src/main/resources/handlebars/htmlDocs/index.mustache @@ -52,9 +52,9 @@
Up
{{httpMethod}} {{path}}
-
{{summary}} ({{nickname}})
+
{{{summary}}} ({{nickname}})
{{! notes is operation.description. So why rename it and make it super confusing???? }} -
{{notes}}
+
{{{notes}}}
{{#hasPathParams}}

Path parameters

diff --git a/src/main/resources/handlebars/htmlDocs2/index.mustache b/src/main/resources/handlebars/htmlDocs2/index.mustache index ea738f4556..fca92bbe49 100644 --- a/src/main/resources/handlebars/htmlDocs2/index.mustache +++ b/src/main/resources/handlebars/htmlDocs2/index.mustache @@ -352,7 +352,7 @@