mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2026-01-07 03:17:09 +00:00
Compare commits
62 Commits
docusaurus
...
fix_issue_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1641e5f60b | ||
|
|
376e1bacac | ||
|
|
f498681c68 | ||
|
|
2a09e8f90f | ||
|
|
7037ca88ee | ||
|
|
b63242219c | ||
|
|
faf1f5d81d | ||
|
|
d584833781 | ||
|
|
992ca3e8ed | ||
|
|
12a5ba2bee | ||
|
|
814a697c81 | ||
|
|
3b7f4c3879 | ||
|
|
b87a507a13 | ||
|
|
87d5484f2e | ||
|
|
581bac83e9 | ||
|
|
8539831126 | ||
|
|
539ec23298 | ||
|
|
189849319c | ||
|
|
60dd3d51be | ||
|
|
4c14c85542 | ||
|
|
9331df791f | ||
|
|
9ccf872290 | ||
|
|
293066bb0d | ||
|
|
fbf570e7bd | ||
|
|
ed5bd5ffb0 | ||
|
|
233ce093e5 | ||
|
|
b7971e2e3d | ||
|
|
1ef56b44c2 | ||
|
|
22a3f7ee0e | ||
|
|
6e4556772c | ||
|
|
549197cce5 | ||
|
|
60776b8cb5 | ||
|
|
eff0c5e8d0 | ||
|
|
1189362466 | ||
|
|
f0f214743e | ||
|
|
651395d426 | ||
|
|
fda35ea263 | ||
|
|
c65ef987af | ||
|
|
b015ac9307 | ||
|
|
bdf32775fb | ||
|
|
1a2deb016b | ||
|
|
b25eeebf03 | ||
|
|
8f561f1ef3 | ||
|
|
b931da2909 | ||
|
|
fa9bd1f567 | ||
|
|
d35f4b08d9 | ||
|
|
be262384cd | ||
|
|
5729ce176c | ||
|
|
3d59d8b58f | ||
|
|
59db7cc568 | ||
|
|
ad5184efc1 | ||
|
|
92db181d97 | ||
|
|
8fd474d4a7 | ||
|
|
af6757ccde | ||
|
|
9334dd391a | ||
|
|
d6fa9e60c6 | ||
|
|
6abb9ddf30 | ||
|
|
e559474880 | ||
|
|
354db2f3e6 | ||
|
|
f96e64bd9e | ||
|
|
3ec90a86cb | ||
|
|
2f6381cb19 |
8
.github/ISSUE_TEMPLATE/bug_report.md
vendored
8
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -7,6 +7,14 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
#### Bug Report Checklist
|
||||
|
||||
- [ ] Have you provided a full/minimal spec to reproduce the issue?
|
||||
- [ ] What's the version of OpenAPI Generator used?
|
||||
- [ ] Have you search for related issues/PRs?
|
||||
- [ ] What's the actual output vs expected output?
|
||||
- [ ] [Optional] Bounty to sponsor the fix ([example](https://www.bountysource.com/issues/66123212-javascript-client-produces-a-wrong-object-for-a-string-enum-type-that-is-used-with-ref))
|
||||
|
||||
<!--
|
||||
Please follow the issue template below for bug reports.
|
||||
Also please indicate in the issue title which language/library is concerned. Eg: [BUG][JAVA] Bug generating foo with bar
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -27,6 +27,7 @@ packages/
|
||||
.packages
|
||||
.vagrant/
|
||||
.vscode/
|
||||
**/.vs
|
||||
|
||||
.settings
|
||||
|
||||
@@ -128,7 +129,6 @@ samples/client/petstore/swift3/**/SwaggerClientTests/Podfile.lock
|
||||
# C#
|
||||
*.csproj.user
|
||||
samples/client/petstore/csharp/SwaggerClient/IO.Swagger.userprefs
|
||||
samples/client/petstore/csharp/SwaggerClientTest/.vs
|
||||
samples/client/petstore/csharp/SwaggerClientTest/obj
|
||||
samples/client/petstore/csharp/SwaggerClientTest/bin
|
||||
samples/client/petstore/csharp/SwaggerClientTest/packages
|
||||
|
||||
12
README.md
12
README.md
@@ -504,6 +504,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
|
||||
- [b<>com](https://b-com.com/en)
|
||||
- [Bithost GmbH](https://www.bithost.ch)
|
||||
- [Boxever](https://www.boxever.com/)
|
||||
- [GenFlow](https://github.com/RepreZen/GenFlow)
|
||||
- [GMO Pepabo](https://pepabo.com/en/)
|
||||
- [JustStar](https://www.juststarinfo.com)
|
||||
- [Klarna](https://www.klarna.com/)
|
||||
@@ -529,9 +530,12 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
|
||||
- 2018/06/27 - [Lessons Learned from Leading an Open-Source Project Supporting 30+ Programming Languages](https://speakerdeck.com/wing328/lessons-learned-from-leading-an-open-source-project-supporting-30-plus-programming-languages) - [William Cheng](https://github.com/wing328) at [LinuxCon + ContainerCon + CloudOpen China 2018](http://bit.ly/2waDKKX)
|
||||
- 2018/07/19 - [OpenAPI Generator Contribution Quickstart - RingCentral Go SDK](https://medium.com/ringcentral-developers/openapi-generator-for-go-contribution-quickstart-8cc72bf37b53) by [John Wang](https://github.com/grokify)
|
||||
- 2018/08/22 - [OpenAPI Generatorのプロジェクト構成などのメモ](https://yinm.info/20180822/) by [Yusuke Iinuma](https://github.com/yinm)
|
||||
- 2018/09/12 - [RepreZen and OpenAPI 3.0: Now is the Time](https://www.reprezen.com/blog/reprezen-openapi-3.0-upgrade-now-is-the-time) by [Miles Daffin](https://www.reprezen.com/blog/author/miles-daffin)
|
||||
- 2018/10/31 - [A node package wrapper for openapi-generator](https://github.com/HarmoWatch/openapi-generator-cli)
|
||||
- 2018/11/03 - [OpenAPI Generator + golang + Flutter でアプリ開発](http://ryuichi111std.hatenablog.com/entry/2018/11/03/214005) by [Ryuichi Daigo](https://github.com/ryuichi111)
|
||||
- 2018/11/19 - [OpenAPIs are everywhere](https://youtu.be/-lDot4Yn7Dg) by [Jeremie Bresson (Unblu)](https://github.com/jmini) at [EclipseCon Europe 2018](https://www.eclipsecon.org/europe2018)
|
||||
- 2018/12/09 - [openapi-generator をカスタマイズする方法](https://qiita.com/watiko/items/0961287c02eac9211572) by [@watiko](https://qiita.com/watiko)
|
||||
- 2019/01/03 - [Calling a Swagger service from Apex using openapi-generator](https://lekkimworld.com/2019/01/03/calling-a-swagger-service-from-apex-using-openapi-generator/) by [Mikkel Flindt Heisterberg](https://lekkimworld.com)
|
||||
|
||||
## [6 - About Us](#table-of-contents)
|
||||
|
||||
@@ -566,7 +570,7 @@ Here is a list of template creators:
|
||||
* Dart 2: @swipesight
|
||||
* Dart (Jaguar): @jaumard
|
||||
* Elixir: @niku
|
||||
* Elm: @trenneman
|
||||
* Elm: @eriktim
|
||||
* Eiffel: @jvelilla
|
||||
* Erlang: @tsloughter
|
||||
* Erlang (PropEr): @jfacorro @robertoaloi
|
||||
@@ -692,8 +696,8 @@ If you want to join the committee, please kindly apply by sending an email to te
|
||||
| Clojure | |
|
||||
| Dart | @ircecho (2017/07) @swipesight (2018/09) @jaumard (2018/09) |
|
||||
| Eiffel | @jvelilla (2017/09) |
|
||||
| Elixir | |
|
||||
| Elm | @trenneman (2018/09) |
|
||||
| Elixir | @mrmstn (2018/12) |
|
||||
| Elm | @eriktim (2018/09) |
|
||||
| Erlang | @tsloughter (2017/11) @jfacorro (2018/10) @robertoaloi (2018/10) |
|
||||
| Go | @antihax (2017/11) @bvwells (2017/12) @grokify (2018/07) @kemokemo (2018/09 |
|
||||
| GraphQL | @renepardon (2018/12) |
|
||||
@@ -732,7 +736,7 @@ OpenAPI Generator is a fork of [Swagger Codegen](https://github.com/swagger-api/
|
||||
- [Daiki Matsudate](https://github.com/d-date)
|
||||
- [Daniel](https://github.com/Danielku15)
|
||||
- [Emiliano Bonassi](https://github.com/emilianobonassi)
|
||||
- [Erik Timmers](https://github.com/trenneman)
|
||||
- [Erik Timmers](https://github.com/eriktim)
|
||||
- [Esteban Marin](https://github.com/macjohnny)
|
||||
- [Gustavo Paz](https://github.com/gustavoapaz)
|
||||
- [Javier Velilla](https://github.com/jvelilla)
|
||||
|
||||
@@ -29,7 +29,6 @@ fi
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="generate -t modules/openapi-generator/src/main/resources/Javascript/es6 \
|
||||
-i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g javascript \
|
||||
-o samples/client/petstore/javascript-es6 \
|
||||
--additional-properties useES6=true $@"
|
||||
-o samples/client/petstore/javascript-es6 $@"
|
||||
|
||||
java -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags
|
||||
|
||||
38
bin/openapi3/go-petstore.sh
Executable file
38
bin/openapi3/go-petstore.sh
Executable file
@@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
SCRIPT="$0"
|
||||
echo "# START SCRIPT: $SCRIPT"
|
||||
|
||||
while [ -h "$SCRIPT" ] ; do
|
||||
ls=`ls -ld "$SCRIPT"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
SCRIPT="$link"
|
||||
else
|
||||
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ! -d "${APP_DIR}" ]; then
|
||||
APP_DIR=`dirname "$SCRIPT"`/..
|
||||
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||
fi
|
||||
|
||||
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
|
||||
|
||||
if [ ! -f "$executable" ]
|
||||
then
|
||||
mvn -B clean package
|
||||
fi
|
||||
|
||||
SPEC="modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml"
|
||||
GENERATOR="go"
|
||||
STUB_DIR="samples/openapi3/client/petstore/go/go-petstore"
|
||||
echo "Removing files and folders under $STUB_DIR"
|
||||
rm -rf $STUB_DIR
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="generate -t modules/openapi-generator/src/main/resources/go -i $SPEC -g $GENERATOR -o $STUB_DIR -DpackageName=petstore $@"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
||||
@@ -12,7 +12,7 @@ codegen="${cli}/target/openapi-generator-cli.jar"
|
||||
# We code in a list of commands here as source processing is potentially buggy (requires undocumented conventional use of annotations).
|
||||
# A list of known commands helps us determine if we should compile CLI. There's an edge-case where a new command not added to this
|
||||
# list won't be considered a "real" command. We can get around that a bit by checking CLI completions beforehand if it exists.
|
||||
commands="list,generate,meta,langs,help,config-help,validate,version"
|
||||
commands="list,generate,meta,help,config-help,validate,version"
|
||||
|
||||
# if CLI jar exists, check $1 against completions available in the CLI
|
||||
if [[ -f "${codegen}" && -n "$(java ${JAVA_OPTS} -jar "${codegen}" completion | grep "^$1\$" )" ]]; then
|
||||
|
||||
19
docs/generators/c.md
Normal file
19
docs/generators/c.md
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
CONFIG OPTIONS for c
|
||||
|
||||
sortParamsByRequiredFlag
|
||||
Sort method arguments to place required parameters before optional parameters. (Default: true)
|
||||
|
||||
ensureUniqueParams
|
||||
Whether to ensure parameter names are unique in an operation (rename parameters that are not). (Default: true)
|
||||
|
||||
allowUnicodeIdentifiers
|
||||
boolean, toggles whether unicode identifiers are allowed in names or not, default is false (Default: false)
|
||||
|
||||
prependFormOrBodyParameters
|
||||
Add form or body parameters to the beginning of the parameter list. (Default: false)
|
||||
|
||||
hideGenerationTimestamp
|
||||
Hides the generation timestamp when files are generated. (Default: true)
|
||||
|
||||
Back to the [generators list](README.md)
|
||||
25
docs/generators/cpp-qt5-client.md
Normal file
25
docs/generators/cpp-qt5-client.md
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
CONFIG OPTIONS for cpp-qt5-client
|
||||
|
||||
sortParamsByRequiredFlag
|
||||
Sort method arguments to place required parameters before optional parameters. (Default: true)
|
||||
|
||||
ensureUniqueParams
|
||||
Whether to ensure parameter names are unique in an operation (rename parameters that are not). (Default: true)
|
||||
|
||||
allowUnicodeIdentifiers
|
||||
boolean, toggles whether unicode identifiers are allowed in names or not, default is false (Default: false)
|
||||
|
||||
prependFormOrBodyParameters
|
||||
Add form or body parameters to the beginning of the parameter list. (Default: false)
|
||||
|
||||
cppNamespace
|
||||
C++ namespace (convention: name::space::for::api). (Default: OpenAPI)
|
||||
|
||||
cppNamespace
|
||||
C++ namespace (convention: name::space::for::api). (Default: OpenAPI)
|
||||
|
||||
optionalProjectFile
|
||||
Generate client.pri. (Default: true)
|
||||
|
||||
Back to the [generators list](README.md)
|
||||
10
docs/generators/erlang-proper.md
Normal file
10
docs/generators/erlang-proper.md
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
CONFIG OPTIONS for erlang-proper
|
||||
|
||||
packageName
|
||||
Erlang application name (convention: lowercase). (Default: openapi)
|
||||
|
||||
packageName
|
||||
Erlang application version (Default: 1.0.0)
|
||||
|
||||
Back to the [generators list](README.md)
|
||||
13
docs/generators/graphql-schema.md
Normal file
13
docs/generators/graphql-schema.md
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
CONFIG OPTIONS for graphql-schema
|
||||
|
||||
packageName
|
||||
GraphQL package name (convention: lowercase). (Default: openapi2graphql)
|
||||
|
||||
packageVersion
|
||||
GraphQL package version. (Default: 1.0.0)
|
||||
|
||||
hideGenerationTimestamp
|
||||
Hides the generation timestamp when files are generated. (Default: true)
|
||||
|
||||
Back to the [generators list](README.md)
|
||||
13
docs/generators/graphql-server.md
Normal file
13
docs/generators/graphql-server.md
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
CONFIG OPTIONS for graphql-server
|
||||
|
||||
packageName
|
||||
GraphQL express server package name (convention: lowercase). (Default: openapi3graphql-server)
|
||||
|
||||
packageVersion
|
||||
GraphQL express server package version. (Default: 1.0.0)
|
||||
|
||||
hideGenerationTimestamp
|
||||
Hides the generation timestamp when files are generated. (Default: true)
|
||||
|
||||
Back to the [generators list](README.md)
|
||||
@@ -59,7 +59,7 @@ CONFIG OPTIONS for javascript
|
||||
Hides the generation timestamp when files are generated. (Default: true)
|
||||
|
||||
useES6
|
||||
use JavaScript ES6 (ECMAScript 6) (beta). Default is ES5. (Default: false)
|
||||
use JavaScript ES6 (ECMAScript 6) (beta). Default is ES6. (Default: true)
|
||||
|
||||
modelPropertyNaming
|
||||
Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name (Default: camelCase)
|
||||
|
||||
@@ -156,7 +156,7 @@ Corresponding java code: `CodegenProperty.datatype` is renamed to `CodegenProper
|
||||
`.swagger-codegen-ignore` is replaced by `.openapi-generator-ignore`.
|
||||
The syntax inside the file stays the same.
|
||||
|
||||
You don't need to rename the file manually, OpenAPI Generator will do it when your run it against an existing an existing output directory.
|
||||
You don't need to rename the file manually, OpenAPI Generator will do it when your run it against an existing output directory.
|
||||
(When there is no `.openapi-generator-ignore` in a folder, if a `.swagger-codegen-ignore` file is present it will be considered and renamed to `.openapi-generator-ignore`).
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Version `4.0.0` is a major release, which contains some breaking changes without
|
||||
The option is replaced with `-g` (`--generator-name`).
|
||||
|
||||
* `-g` allows the same values as `-l`
|
||||
* See `langs` command for the list of generator name
|
||||
* See `list` command for the list of generator name
|
||||
|
||||
=== From 3.1.x to 3.2.0
|
||||
|
||||
|
||||
@@ -50,7 +50,6 @@ public class OpenAPIGenerator {
|
||||
ListGenerators.class,
|
||||
Generate.class,
|
||||
Meta.class,
|
||||
Langs.class,
|
||||
Help.class,
|
||||
ConfigHelp.class,
|
||||
Validate.class,
|
||||
|
||||
@@ -50,7 +50,7 @@ public class Generate implements Runnable {
|
||||
private Boolean verbose;
|
||||
|
||||
@Option(name = {"-g", "--generator-name"}, title = "generator name",
|
||||
description = "generator to use (see langs command for list)")
|
||||
description = "generator to use (see list command for list)")
|
||||
private String generatorName;
|
||||
|
||||
@Option(name = {"-o", "--output"}, title = "output directory",
|
||||
@@ -208,6 +208,9 @@ public class Generate implements Runnable {
|
||||
@Option(name = {"--enable-post-process-file"}, title = "enable post-process file", description = CodegenConstants.ENABLE_POST_PROCESS_FILE)
|
||||
private Boolean enablePostProcessFile;
|
||||
|
||||
@Option(name = {"--generate-alias-as-model"}, title = "generate alias (array, map) as model", description = CodegenConstants.GENERATE_ALIAS_AS_MODEL_DESC)
|
||||
private Boolean generateAliasAsModel;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (logToStderr != null) {
|
||||
@@ -334,6 +337,10 @@ public class Generate implements Runnable {
|
||||
configurator.setEnablePostProcessFile(enablePostProcessFile);
|
||||
}
|
||||
|
||||
if (generateAliasAsModel != null) {
|
||||
configurator.setGenerateAliasAsModel(generateAliasAsModel);
|
||||
}
|
||||
|
||||
applySystemPropertiesKvpList(systemProperties, configurator);
|
||||
applyInstantiationTypesKvpList(instantiationTypes, configurator);
|
||||
applyImportMappingsKvpList(importMappings, configurator);
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
* Copyright 2018 SmartBear Software
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
package org.openapitools.codegen.cmd;
|
||||
|
||||
import ch.lambdaj.collection.LambdaIterable;
|
||||
import io.airlift.airline.Command;
|
||||
import org.openapitools.codegen.CodegenConfig;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import static ch.lambdaj.Lambda.on;
|
||||
import static ch.lambdaj.collection.LambdaCollections.with;
|
||||
import static java.util.ServiceLoader.load;
|
||||
|
||||
/**
|
||||
* User: lanwen Date: 24.03.15 Time: 20:25
|
||||
*/
|
||||
@Command(name = "langs", description = "Shows available languages (deprecated. use 'list' instead)")
|
||||
public class Langs implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
LambdaIterable<String> langs =
|
||||
with(load(CodegenConfig.class)).extract(on(CodegenConfig.class).getName());
|
||||
System.out.printf(Locale.ROOT, "Available languages (generators): %s%n", langs);
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
package org.openapitools.generator.gradle.plugin
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.invoke
|
||||
import org.openapitools.generator.gradle.plugin.extensions.OpenApiGeneratorGenerateExtension
|
||||
import org.openapitools.generator.gradle.plugin.extensions.OpenApiGeneratorMetaExtension
|
||||
import org.openapitools.generator.gradle.plugin.extensions.OpenApiGeneratorValidateExtension
|
||||
import org.openapitools.generator.gradle.plugin.tasks.GenerateTask
|
||||
import org.openapitools.generator.gradle.plugin.tasks.GeneratorsTask
|
||||
import org.openapitools.generator.gradle.plugin.tasks.MetaTask
|
||||
import org.openapitools.generator.gradle.plugin.tasks.ValidateTask
|
||||
|
||||
/**
|
||||
* A plugin providing common Open API Generator use cases.
|
||||
*
|
||||
* @author Jim Schubert
|
||||
*/
|
||||
@Suppress("unused")
|
||||
class OpenApiGeneratorPlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
project.run {
|
||||
val meta = extensions.create(
|
||||
"openApiMeta",
|
||||
OpenApiGeneratorMetaExtension::class.java,
|
||||
project
|
||||
)
|
||||
|
||||
val validate = extensions.create(
|
||||
"openApiValidate",
|
||||
OpenApiGeneratorValidateExtension::class.java,
|
||||
project
|
||||
)
|
||||
|
||||
val generate = extensions.create(
|
||||
"openApiGenerate",
|
||||
OpenApiGeneratorGenerateExtension::class.java,
|
||||
project
|
||||
)
|
||||
|
||||
generate.outputDir.set("$buildDir/generate-resources/main")
|
||||
|
||||
tasks {
|
||||
"openApiGenerators"(GeneratorsTask::class) {
|
||||
group = pluginGroup
|
||||
description = "Lists generators available via Open API Generators."
|
||||
}
|
||||
"openApiMeta"(MetaTask::class) {
|
||||
group = pluginGroup
|
||||
description = "Generates a new generator to be consumed via Open API Generator."
|
||||
|
||||
generatorName.set(meta.generatorName)
|
||||
packageName.set(meta.packageName)
|
||||
outputFolder.set(meta.outputFolder)
|
||||
}
|
||||
"openApiValidate"(ValidateTask::class) {
|
||||
group = pluginGroup
|
||||
description = "Validates an Open API 2.0 or 3.x specification document."
|
||||
|
||||
inputSpec.set(validate.inputSpec)
|
||||
}
|
||||
"openApiGenerate"(GenerateTask::class) {
|
||||
group = pluginGroup
|
||||
description = "Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents."
|
||||
|
||||
verbose.set(generate.verbose)
|
||||
validateSpec.set(generate.validateSpec)
|
||||
generatorName.set(generate.generatorName)
|
||||
outputDir.set(generate.outputDir)
|
||||
inputSpec.set(generate.inputSpec)
|
||||
templateDir.set(generate.templateDir)
|
||||
auth.set(generate.auth)
|
||||
systemProperties.set(generate.systemProperties)
|
||||
configFile.set(generate.configFile)
|
||||
skipOverwrite.set(generate.skipOverwrite)
|
||||
apiPackage.set(generate.apiPackage)
|
||||
modelPackage.set(generate.modelPackage)
|
||||
modelNamePrefix.set(generate.modelNamePrefix)
|
||||
modelNameSuffix.set(generate.modelNameSuffix)
|
||||
instantiationTypes.set(generate.instantiationTypes)
|
||||
typeMappings.set(generate.typeMappings)
|
||||
additionalProperties.set(generate.additionalProperties)
|
||||
languageSpecificPrimitives.set(generate.languageSpecificPrimitives)
|
||||
importMappings.set(generate.importMappings)
|
||||
invokerPackage.set(generate.invokerPackage)
|
||||
groupId.set(generate.groupId)
|
||||
id.set(generate.id)
|
||||
version.set(generate.version)
|
||||
library.set(generate.library)
|
||||
gitUserId.set(generate.gitUserId)
|
||||
gitRepoId.set(generate.gitRepoId)
|
||||
releaseNote.set(generate.releaseNote)
|
||||
httpUserAgent.set(generate.httpUserAgent)
|
||||
reservedWordsMappings.set(generate.reservedWordsMappings)
|
||||
ignoreFileOverride.set(generate.ignoreFileOverride)
|
||||
removeOperationIdPrefix.set(generate.removeOperationIdPrefix)
|
||||
apiFilesConstrainedTo.set(generate.apiFilesConstrainedTo)
|
||||
modelFilesConstrainedTo.set(generate.modelFilesConstrainedTo)
|
||||
supportingFilesConstrainedTo.set(generate.supportingFilesConstrainedTo)
|
||||
generateModelTests.set(generate.generateModelTests)
|
||||
generateModelDocumentation.set(generate.generateModelDocumentation)
|
||||
generateApiTests.set(generate.generateApiTests)
|
||||
generateApiDocumentation.set(generate.generateApiDocumentation)
|
||||
withXml.set(generate.withXml)
|
||||
configOptions.set(generate.configOptions)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val pluginGroup = "OpenAPI Tools"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,286 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
package org.openapitools.generator.gradle.plugin.extensions
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.listProperty
|
||||
import org.gradle.kotlin.dsl.property
|
||||
|
||||
/**
|
||||
* Gradle project level extension object definition for the generate task
|
||||
*
|
||||
* @author Jim Schubert
|
||||
*/
|
||||
open class OpenApiGeneratorGenerateExtension(project: Project) {
|
||||
|
||||
/**
|
||||
* The verbosity of generation
|
||||
*/
|
||||
val verbose = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* Whether or not an input specification should be validated upon generation.
|
||||
*/
|
||||
val validateSpec = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* The name of the generator which will handle codegen. (see "openApiGenerators" task)
|
||||
*/
|
||||
val generatorName = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* The output target directory into which code will be generated.
|
||||
*/
|
||||
val outputDir = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* The Open API 2.0/3.x specification location.
|
||||
*/
|
||||
val inputSpec = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* The template directory holding a custom template.
|
||||
*/
|
||||
val templateDir = project.objects.property<String?>()
|
||||
|
||||
/**
|
||||
* Adds authorization headers when fetching the OpenAPI definitions remotely.
|
||||
* Pass in a URL-encoded string of name:header with a comma separating multiple values
|
||||
*/
|
||||
val auth = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Sets specified system properties.
|
||||
*/
|
||||
val systemProperties = project.objects.property<Map<String, String>>()
|
||||
|
||||
/**
|
||||
* Path to json configuration file.
|
||||
* File content should be in a json format { "optionKey":"optionValue", "optionKey1":"optionValue1"...}
|
||||
* Supported options can be different for each language. Run config-help -g {generator name} command for language specific config options.
|
||||
*/
|
||||
val configFile = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Specifies if the existing files should be overwritten during the generation.
|
||||
*/
|
||||
val skipOverwrite = project.objects.property<Boolean?>()
|
||||
|
||||
/**
|
||||
* Package for generated api classes
|
||||
*/
|
||||
val apiPackage = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Package for generated models
|
||||
*/
|
||||
val modelPackage = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Prefix that will be prepended to all model names. Default is the empty string.
|
||||
*/
|
||||
val modelNamePrefix = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Suffix that will be appended to all model names. Default is the empty string.
|
||||
*/
|
||||
val modelNameSuffix = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Sets instantiation type mappings.
|
||||
*/
|
||||
val instantiationTypes = project.objects.property<Map<String, String>>()
|
||||
|
||||
/**
|
||||
* Sets mappings between OpenAPI spec types and generated code types.
|
||||
*/
|
||||
val typeMappings = project.objects.property<Map<String, String>>()
|
||||
|
||||
/**
|
||||
* Sets additional properties that can be referenced by the mustache templates.
|
||||
*/
|
||||
val additionalProperties = project.objects.property<Map<String, String>>()
|
||||
|
||||
/**
|
||||
* Specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double.
|
||||
*/
|
||||
val languageSpecificPrimitives = project.objects.listProperty<String>()
|
||||
|
||||
/**
|
||||
* Specifies mappings between a given class and the import that should be used for that class.
|
||||
*/
|
||||
val importMappings = project.objects.property<Map<String, String>>()
|
||||
|
||||
/**
|
||||
* Root package for generated code.
|
||||
*/
|
||||
val invokerPackage = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* GroupId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
|
||||
*/
|
||||
val groupId = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* ArtifactId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
|
||||
*/
|
||||
val id = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Artifact version in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
|
||||
*/
|
||||
val version = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Reference the library template (sub-template) of a generator.
|
||||
*/
|
||||
val library = project.objects.property<String?>()
|
||||
|
||||
/**
|
||||
* Git user ID, e.g. openapitools.
|
||||
*/
|
||||
val gitUserId = project.objects.property<String?>()
|
||||
|
||||
/**
|
||||
* Git repo ID, e.g. openapi-generator.
|
||||
*/
|
||||
val gitRepoId = project.objects.property<String?>()
|
||||
|
||||
/**
|
||||
* Release note, default to 'Minor update'.
|
||||
*/
|
||||
val releaseNote = project.objects.property<String?>()
|
||||
|
||||
/**
|
||||
* HTTP user agent, e.g. codegen_csharp_api_client, default to 'OpenAPI-Generator/{packageVersion}}/{language}'
|
||||
*/
|
||||
val httpUserAgent = project.objects.property<String?>()
|
||||
|
||||
/**
|
||||
* Specifies how a reserved name should be escaped to. Otherwise, the default _<name> is used.
|
||||
*/
|
||||
val reservedWordsMappings = project.objects.property<Map<String, String>>()
|
||||
|
||||
/**
|
||||
* Specifies an override location for the .openapi-generator-ignore file. Most useful on initial generation.
|
||||
*/
|
||||
val ignoreFileOverride = project.objects.property<String?>()
|
||||
|
||||
/**
|
||||
* Remove prefix of operationId, e.g. config_getId => getId
|
||||
*/
|
||||
val removeOperationIdPrefix = project.objects.property<Boolean?>()
|
||||
|
||||
/**
|
||||
* Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all).
|
||||
*
|
||||
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
|
||||
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
|
||||
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
|
||||
*/
|
||||
val apiFilesConstrainedTo = project.objects.listProperty<String>()
|
||||
|
||||
/**
|
||||
* Defines which model-related files should be generated. This allows you to create a subset of generated files (or none at all).
|
||||
*
|
||||
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
|
||||
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
|
||||
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
|
||||
*/
|
||||
val modelFilesConstrainedTo = project.objects.listProperty<String>()
|
||||
|
||||
/**
|
||||
* Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all).
|
||||
*
|
||||
* Supporting files are those related to projects/frameworks which may be modified
|
||||
* by consumers.
|
||||
*
|
||||
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
|
||||
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
|
||||
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
|
||||
*/
|
||||
val supportingFilesConstrainedTo = project.objects.listProperty<String>()
|
||||
|
||||
/**
|
||||
* Defines whether or not model-related _test_ files should be generated.
|
||||
*
|
||||
* This option enables/disables generation of ALL model-related _test_ files.
|
||||
*
|
||||
* For more control over generation of individual files, configure an ignore file and
|
||||
* refer to it via [ignoreFileOverride].
|
||||
*/
|
||||
val generateModelTests = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* Defines whether or not model-related _documentation_ files should be generated.
|
||||
*
|
||||
* This option enables/disables generation of ALL model-related _documentation_ files.
|
||||
*
|
||||
* For more control over generation of individual files, configure an ignore file and
|
||||
* refer to it via [ignoreFileOverride].
|
||||
*/
|
||||
val generateModelDocumentation = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* Defines whether or not api-related _test_ files should be generated.
|
||||
*
|
||||
* This option enables/disables generation of ALL api-related _test_ files.
|
||||
*
|
||||
* For more control over generation of individual files, configure an ignore file and
|
||||
* refer to it via [ignoreFileOverride].
|
||||
*/
|
||||
val generateApiTests = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* Defines whether or not api-related _documentation_ files should be generated.
|
||||
*
|
||||
* This option enables/disables generation of ALL api-related _documentation_ files.
|
||||
*
|
||||
* For more control over generation of individual files, configure an ignore file and
|
||||
* refer to it via [ignoreFileOverride].
|
||||
*/
|
||||
val generateApiDocumentation = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* A special-case setting which configures some generators with XML support. In some cases,
|
||||
* this forces json OR xml, so the default here is false.
|
||||
*/
|
||||
val withXml = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* A map of options specific to a generator.
|
||||
*/
|
||||
val configOptions = project.objects.property<Map<String, String>>()
|
||||
|
||||
init {
|
||||
applyDefaults()
|
||||
}
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
fun applyDefaults(){
|
||||
releaseNote.set("Minor update")
|
||||
modelNamePrefix.set("")
|
||||
modelNameSuffix.set("")
|
||||
generateModelTests.set(true)
|
||||
generateModelDocumentation.set(true)
|
||||
generateApiTests.set(true)
|
||||
generateApiDocumentation.set(true)
|
||||
withXml.set(false)
|
||||
configOptions.set(mapOf())
|
||||
validateSpec.set(true)
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
package org.openapitools.generator.gradle.plugin.extensions
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.property
|
||||
|
||||
/**
|
||||
* Gradle project level extension object definition for the meta-generator task
|
||||
*
|
||||
* @author Jim Schubert
|
||||
*/
|
||||
open class OpenApiGeneratorMetaExtension(project: Project) {
|
||||
/**
|
||||
* The human-readable generator name of the newly created template generator.
|
||||
*/
|
||||
val generatorName = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* The packageName generatorName to put the main class into (defaults to org.openapitools.codegen)
|
||||
*/
|
||||
val packageName = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Where to write the generated files (current dir by default).
|
||||
*/
|
||||
val outputFolder = project.objects.property<String>()
|
||||
|
||||
init {
|
||||
generatorName.set("default")
|
||||
packageName.set("org.openapitools.codegen")
|
||||
outputFolder.set("")
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
package org.openapitools.generator.gradle.plugin.extensions
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.property
|
||||
|
||||
/**
|
||||
* Gradle project level extension object definition for the generators task
|
||||
*
|
||||
* @author Jim Schubert
|
||||
*/
|
||||
open class OpenApiGeneratorValidateExtension(project: Project) {
|
||||
/**
|
||||
* The input specification to validate. Supports all formats supported by the Parser.
|
||||
*/
|
||||
val inputSpec = project.objects.property<String>()
|
||||
}
|
||||
@@ -1,549 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
package org.openapitools.generator.gradle.plugin.tasks
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.internal.logging.text.StyledTextOutput
|
||||
import org.gradle.internal.logging.text.StyledTextOutputFactory
|
||||
import org.gradle.kotlin.dsl.listProperty
|
||||
import org.gradle.kotlin.dsl.property
|
||||
import org.openapitools.codegen.CodegenConstants
|
||||
import org.openapitools.codegen.DefaultGenerator
|
||||
import org.openapitools.codegen.config.CodegenConfigurator
|
||||
import org.openapitools.codegen.config.GeneratorProperties
|
||||
|
||||
|
||||
/**
|
||||
* A task which generates the desired code.
|
||||
*
|
||||
* Example (CLI):
|
||||
*
|
||||
* ./gradlew -q openApiGenerate
|
||||
*
|
||||
* @author Jim Schubert
|
||||
*/
|
||||
open class GenerateTask : DefaultTask() {
|
||||
|
||||
/**
|
||||
* The verbosity of generation
|
||||
*/
|
||||
@get:Internal
|
||||
val verbose = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* Whether or not an input specification should be validated upon generation.
|
||||
*/
|
||||
@get:Internal
|
||||
val validateSpec = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* The name of the generator which will handle codegen. (see "openApiGenerators" task)
|
||||
*/
|
||||
@get:Internal
|
||||
val generatorName = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* The output target directory into which code will be generated.
|
||||
*/
|
||||
@get:Internal
|
||||
val outputDir = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* The Open API 2.0/3.x specification location.
|
||||
*/
|
||||
@get:Internal
|
||||
val inputSpec = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* The template directory holding a custom template.
|
||||
*/
|
||||
@get:Internal
|
||||
val templateDir = project.objects.property<String?>()
|
||||
|
||||
/**
|
||||
* Adds authorization headers when fetching the OpenAPI definitions remotely.
|
||||
* Pass in a URL-encoded string of name:header with a comma separating multiple values
|
||||
*/
|
||||
@get:Internal
|
||||
val auth = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Sets specified system properties.
|
||||
*/
|
||||
@get:Internal
|
||||
val systemProperties = project.objects.property<Map<String, String>>()
|
||||
|
||||
/**
|
||||
* Path to json configuration file.
|
||||
* File content should be in a json format { "optionKey":"optionValue", "optionKey1":"optionValue1"...}
|
||||
* Supported options can be different for each language. Run config-help -g {generator name} command for language specific config options.
|
||||
*/
|
||||
@get:Internal
|
||||
val configFile = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Specifies if the existing files should be overwritten during the generation.
|
||||
*/
|
||||
@get:Internal
|
||||
val skipOverwrite = project.objects.property<Boolean?>()
|
||||
|
||||
/**
|
||||
* Package for generated api classes
|
||||
*/
|
||||
@get:Internal
|
||||
val apiPackage = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Package for generated models
|
||||
*/
|
||||
@get:Internal
|
||||
val modelPackage = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Prefix that will be prepended to all model names. Default is the empty string.
|
||||
*/
|
||||
@get:Internal
|
||||
val modelNamePrefix = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Suffix that will be appended to all model names. Default is the empty string.
|
||||
*/
|
||||
@get:Internal
|
||||
val modelNameSuffix = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Sets instantiation type mappings.
|
||||
*/
|
||||
@get:Internal
|
||||
val instantiationTypes = project.objects.property<Map<String, String>>()
|
||||
|
||||
/**
|
||||
* Sets mappings between OpenAPI spec types and generated code types.
|
||||
*/
|
||||
@get:Internal
|
||||
val typeMappings = project.objects.property<Map<String, String>>()
|
||||
|
||||
/**
|
||||
* Sets additional properties that can be referenced by the mustache templates in the format of name=value,name=value.
|
||||
* You can also have multiple occurrences of this option.
|
||||
*/
|
||||
@get:Internal
|
||||
val additionalProperties = project.objects.property<Map<String, String>>()
|
||||
|
||||
/**
|
||||
* Specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double.
|
||||
*/
|
||||
@get:Internal
|
||||
val languageSpecificPrimitives = project.objects.listProperty<String>()
|
||||
|
||||
/**
|
||||
* Specifies mappings between a given class and the import that should be used for that class.
|
||||
*/
|
||||
@get:Internal
|
||||
val importMappings = project.objects.property<Map<String, String>>()
|
||||
|
||||
/**
|
||||
* Root package for generated code.
|
||||
*/
|
||||
@get:Internal
|
||||
val invokerPackage = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* GroupId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
|
||||
*/
|
||||
@get:Internal
|
||||
val groupId = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* ArtifactId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
|
||||
*/
|
||||
@get:Internal
|
||||
val id = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Artifact version in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
|
||||
*/
|
||||
@get:Internal
|
||||
val version = project.objects.property<String>()
|
||||
|
||||
/**
|
||||
* Reference the library template (sub-template) of a generator.
|
||||
*/
|
||||
@get:Internal
|
||||
val library = project.objects.property<String?>()
|
||||
|
||||
/**
|
||||
* Git user ID, e.g. openapitools.
|
||||
*/
|
||||
@get:Internal
|
||||
val gitUserId = project.objects.property<String?>()
|
||||
|
||||
/**
|
||||
* Git repo ID, e.g. openapi-generator.
|
||||
*/
|
||||
@get:Internal
|
||||
val gitRepoId = project.objects.property<String?>()
|
||||
|
||||
/**
|
||||
* Release note, default to 'Minor update'.
|
||||
*/
|
||||
@get:Internal
|
||||
val releaseNote = project.objects.property<String?>()
|
||||
|
||||
/**
|
||||
* HTTP user agent, e.g. codegen_csharp_api_client, default to 'OpenAPI-Generator/{packageVersion}}/{language}'
|
||||
*/
|
||||
@get:Internal
|
||||
val httpUserAgent = project.objects.property<String?>()
|
||||
|
||||
/**
|
||||
* Specifies how a reserved name should be escaped to.
|
||||
*/
|
||||
@get:Internal
|
||||
val reservedWordsMappings = project.objects.property<Map<String, String>>()
|
||||
|
||||
/**
|
||||
* Specifies an override location for the .openapi-generator-ignore file. Most useful on initial generation.
|
||||
*/
|
||||
@get:Internal
|
||||
val ignoreFileOverride = project.objects.property<String?>()
|
||||
|
||||
/**
|
||||
* Remove prefix of operationId, e.g. config_getId => getId
|
||||
*/
|
||||
@get:Internal
|
||||
val removeOperationIdPrefix = project.objects.property<Boolean?>()
|
||||
|
||||
/**
|
||||
* Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all).
|
||||
*
|
||||
* This option enables/disables generation of ALL api-related files.
|
||||
*
|
||||
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
|
||||
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
|
||||
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
|
||||
*/
|
||||
@get:Internal
|
||||
val apiFilesConstrainedTo = project.objects.listProperty<String>()
|
||||
|
||||
/**
|
||||
* Defines which model-related files should be generated. This allows you to create a subset of generated files (or none at all).
|
||||
*
|
||||
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
|
||||
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
|
||||
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
|
||||
*/
|
||||
@get:Internal
|
||||
val modelFilesConstrainedTo = project.objects.listProperty<String>()
|
||||
|
||||
/**
|
||||
* Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all).
|
||||
*
|
||||
* Supporting files are those related to projects/frameworks which may be modified
|
||||
* by consumers.
|
||||
*
|
||||
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
|
||||
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
|
||||
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
|
||||
*/
|
||||
@get:Internal
|
||||
val supportingFilesConstrainedTo = project.objects.listProperty<String>()
|
||||
|
||||
/**
|
||||
* Defines whether or not model-related _test_ files should be generated.
|
||||
*
|
||||
* This option enables/disables generation of ALL model-related _test_ files.
|
||||
*
|
||||
* For more control over generation of individual files, configure an ignore file and
|
||||
* refer to it via [ignoreFileOverride].
|
||||
*/
|
||||
@get:Internal
|
||||
val generateModelTests = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* Defines whether or not model-related _documentation_ files should be generated.
|
||||
*
|
||||
* This option enables/disables generation of ALL model-related _documentation_ files.
|
||||
*
|
||||
* For more control over generation of individual files, configure an ignore file and
|
||||
* refer to it via [ignoreFileOverride].
|
||||
*/
|
||||
@get:Internal
|
||||
val generateModelDocumentation = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* Defines whether or not api-related _test_ files should be generated.
|
||||
*
|
||||
* This option enables/disables generation of ALL api-related _test_ files.
|
||||
*
|
||||
* For more control over generation of individual files, configure an ignore file and
|
||||
* refer to it via [ignoreFileOverride].
|
||||
*/
|
||||
@get:Internal
|
||||
val generateApiTests = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* Defines whether or not api-related _documentation_ files should be generated.
|
||||
*
|
||||
* This option enables/disables generation of ALL api-related _documentation_ files.
|
||||
*
|
||||
* For more control over generation of individual files, configure an ignore file and
|
||||
* refer to it via [ignoreFileOverride].
|
||||
*/
|
||||
@get:Internal
|
||||
val generateApiDocumentation = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* A special-case setting which configures some generators with XML support. In some cases,
|
||||
* this forces json OR xml, so the default here is false.
|
||||
*/
|
||||
@get:Internal
|
||||
val withXml = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* A dynamic map of options specific to a generator.
|
||||
*/
|
||||
@get:Internal
|
||||
val configOptions = project.objects.property<Map<String, String>>()
|
||||
|
||||
private val originalEnvironmentVariables = mutableMapOf<String, String?>()
|
||||
|
||||
private fun <T : Any?> Property<T>.ifNotEmpty(block: Property<T>.(T) -> Unit) {
|
||||
if (isPresent) {
|
||||
val item: T? = get()
|
||||
if (item != null) {
|
||||
when (get()) {
|
||||
is String -> if ((get() as String).isNotEmpty()) {
|
||||
block(get())
|
||||
}
|
||||
is String? -> if (true == (get() as String?)?.isNotEmpty()) {
|
||||
block(get())
|
||||
}
|
||||
else -> block(get())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
@TaskAction
|
||||
fun doWork() {
|
||||
val configurator: CodegenConfigurator = if (configFile.isPresent) {
|
||||
CodegenConfigurator.fromFile(configFile.get())
|
||||
} else CodegenConfigurator()
|
||||
|
||||
try {
|
||||
if (systemProperties.isPresent) {
|
||||
systemProperties.get().forEach { (key, value) ->
|
||||
// GeneratorProperties.setProperty returns the original value for a key, or null.
|
||||
// Cache the original value or null…we will late put the properties back in their original state.
|
||||
originalEnvironmentVariables[key] = GeneratorProperties.setProperty(key, value)
|
||||
configurator.addSystemProperty(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
if (supportingFilesConstrainedTo.isPresent && supportingFilesConstrainedTo.get().isNotEmpty()) {
|
||||
GeneratorProperties.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesConstrainedTo.get().joinToString(","))
|
||||
} else {
|
||||
GeneratorProperties.clearProperty(CodegenConstants.SUPPORTING_FILES)
|
||||
}
|
||||
|
||||
if (modelFilesConstrainedTo.isPresent && modelFilesConstrainedTo.get().isNotEmpty()) {
|
||||
GeneratorProperties.setProperty(CodegenConstants.MODELS, modelFilesConstrainedTo.get().joinToString(","))
|
||||
} else {
|
||||
GeneratorProperties.clearProperty(CodegenConstants.MODELS)
|
||||
}
|
||||
|
||||
if (apiFilesConstrainedTo.isPresent && apiFilesConstrainedTo.get().isNotEmpty()) {
|
||||
GeneratorProperties.setProperty(CodegenConstants.APIS, apiFilesConstrainedTo.get().joinToString(","))
|
||||
} else {
|
||||
GeneratorProperties.clearProperty(CodegenConstants.APIS)
|
||||
}
|
||||
|
||||
GeneratorProperties.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.get().toString())
|
||||
GeneratorProperties.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.get().toString())
|
||||
GeneratorProperties.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.get().toString())
|
||||
GeneratorProperties.setProperty(CodegenConstants.API_TESTS, generateApiTests.get().toString())
|
||||
GeneratorProperties.setProperty(CodegenConstants.WITH_XML, withXml.get().toString())
|
||||
|
||||
// now override with any specified parameters
|
||||
verbose.ifNotEmpty { value ->
|
||||
configurator.isVerbose = value
|
||||
}
|
||||
|
||||
validateSpec.ifNotEmpty { value ->
|
||||
configurator.isValidateSpec = value
|
||||
}
|
||||
|
||||
skipOverwrite.ifNotEmpty { value ->
|
||||
configurator.isSkipOverwrite = value ?: false
|
||||
}
|
||||
|
||||
inputSpec.ifNotEmpty { value ->
|
||||
configurator.inputSpec = value
|
||||
}
|
||||
|
||||
generatorName.ifNotEmpty { value ->
|
||||
configurator.generatorName = value
|
||||
}
|
||||
|
||||
outputDir.ifNotEmpty { value ->
|
||||
configurator.outputDir = value
|
||||
}
|
||||
|
||||
auth.ifNotEmpty { value ->
|
||||
configurator.auth = value
|
||||
}
|
||||
|
||||
templateDir.ifNotEmpty { value ->
|
||||
configurator.templateDir = value
|
||||
}
|
||||
|
||||
apiPackage.ifNotEmpty { value ->
|
||||
configurator.apiPackage = value
|
||||
}
|
||||
|
||||
modelPackage.ifNotEmpty { value ->
|
||||
configurator.modelPackage = value
|
||||
}
|
||||
|
||||
modelNamePrefix.ifNotEmpty { value ->
|
||||
configurator.modelNamePrefix = value
|
||||
}
|
||||
|
||||
modelNameSuffix.ifNotEmpty { value ->
|
||||
configurator.modelNameSuffix = value
|
||||
}
|
||||
|
||||
invokerPackage.ifNotEmpty { value ->
|
||||
configurator.invokerPackage = value
|
||||
}
|
||||
|
||||
groupId.ifNotEmpty { value ->
|
||||
configurator.groupId = value
|
||||
}
|
||||
|
||||
id.ifNotEmpty { value ->
|
||||
configurator.artifactId = value
|
||||
}
|
||||
|
||||
version.ifNotEmpty { value ->
|
||||
configurator.artifactVersion = value
|
||||
}
|
||||
|
||||
library.ifNotEmpty { value ->
|
||||
configurator.library = value
|
||||
}
|
||||
|
||||
gitUserId.ifNotEmpty { value ->
|
||||
configurator.gitUserId = value
|
||||
}
|
||||
|
||||
gitRepoId.ifNotEmpty { value ->
|
||||
configurator.gitRepoId = value
|
||||
}
|
||||
|
||||
releaseNote.ifNotEmpty { value ->
|
||||
configurator.releaseNote = value
|
||||
}
|
||||
|
||||
httpUserAgent.ifNotEmpty { value ->
|
||||
configurator.httpUserAgent = value
|
||||
}
|
||||
|
||||
ignoreFileOverride.ifNotEmpty { value ->
|
||||
configurator.ignoreFileOverride = value
|
||||
}
|
||||
|
||||
removeOperationIdPrefix.ifNotEmpty { value ->
|
||||
configurator.removeOperationIdPrefix = value!!
|
||||
}
|
||||
|
||||
if (systemProperties.isPresent) {
|
||||
systemProperties.get().forEach { entry ->
|
||||
configurator.addSystemProperty(entry.key, entry.value)
|
||||
}
|
||||
}
|
||||
|
||||
if (instantiationTypes.isPresent) {
|
||||
instantiationTypes.get().forEach { entry ->
|
||||
configurator.addInstantiationType(entry.key, entry.value)
|
||||
}
|
||||
}
|
||||
|
||||
if (importMappings.isPresent) {
|
||||
importMappings.get().forEach { entry ->
|
||||
configurator.addImportMapping(entry.key, entry.value)
|
||||
}
|
||||
}
|
||||
|
||||
if (typeMappings.isPresent) {
|
||||
typeMappings.get().forEach { entry ->
|
||||
configurator.addTypeMapping(entry.key, entry.value)
|
||||
}
|
||||
}
|
||||
|
||||
if (additionalProperties.isPresent) {
|
||||
additionalProperties.get().forEach { entry ->
|
||||
configurator.addAdditionalProperty(entry.key, entry.value)
|
||||
}
|
||||
}
|
||||
|
||||
if (languageSpecificPrimitives.isPresent) {
|
||||
languageSpecificPrimitives.get().forEach {
|
||||
configurator.addLanguageSpecificPrimitive(it)
|
||||
}
|
||||
}
|
||||
|
||||
if (reservedWordsMappings.isPresent) {
|
||||
reservedWordsMappings.get().forEach { entry ->
|
||||
configurator.addAdditionalReservedWordMapping(entry.key, entry.value)
|
||||
}
|
||||
}
|
||||
|
||||
val clientOptInput = configurator.toClientOptInput()
|
||||
val codgenConfig = clientOptInput.config
|
||||
|
||||
if (configOptions.isPresent) {
|
||||
val userSpecifiedConfigOptions = configOptions.get()
|
||||
codgenConfig.cliOptions().forEach {
|
||||
if (userSpecifiedConfigOptions.containsKey(it.opt)) {
|
||||
clientOptInput.config.additionalProperties()[it.opt] = userSpecifiedConfigOptions[it.opt]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
val out = services.get(StyledTextOutputFactory::class.java).create("openapi")
|
||||
out.withStyle(StyledTextOutput.Style.Success)
|
||||
|
||||
DefaultGenerator().opts(clientOptInput).generate()
|
||||
|
||||
out.println("Successfully generated code to ${configurator.outputDir}")
|
||||
} catch (e: RuntimeException) {
|
||||
throw GradleException("Code generation failed.", e)
|
||||
}
|
||||
} finally {
|
||||
// Reset all modified system properties back to their original state
|
||||
GeneratorProperties.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
package org.openapitools.generator.gradle.plugin.tasks
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.internal.logging.text.StyledTextOutput
|
||||
import org.gradle.internal.logging.text.StyledTextOutputFactory
|
||||
import org.openapitools.codegen.CodegenConfigLoader
|
||||
import org.openapitools.codegen.CodegenType
|
||||
|
||||
/**
|
||||
* A task which lists out the generators available in OpenAPI Generator
|
||||
*
|
||||
* Example (CLI):
|
||||
*
|
||||
* ./gradlew -q openApiGenerators
|
||||
*
|
||||
* @author Jim Schubert
|
||||
*/
|
||||
open class GeneratorsTask : DefaultTask() {
|
||||
@Suppress("unused")
|
||||
@TaskAction
|
||||
fun doWork() {
|
||||
val generators = CodegenConfigLoader.getAll()
|
||||
|
||||
val out = services.get(StyledTextOutputFactory::class.java).create("openapi")
|
||||
|
||||
StringBuilder().apply {
|
||||
val types = CodegenType.values()
|
||||
|
||||
append("The following generators are available:")
|
||||
|
||||
append(System.lineSeparator())
|
||||
append(System.lineSeparator())
|
||||
|
||||
for (type in types) {
|
||||
append(type.name).append(" generators:")
|
||||
append(System.lineSeparator())
|
||||
|
||||
generators.filter { it.tag == type }
|
||||
.sortedBy { it.name }
|
||||
.forEach({ generator ->
|
||||
append(" - ")
|
||||
append(generator.name)
|
||||
append(System.lineSeparator())
|
||||
})
|
||||
|
||||
append(System.lineSeparator())
|
||||
append(System.lineSeparator())
|
||||
}
|
||||
|
||||
out.withStyle(StyledTextOutput.Style.Success)
|
||||
out.formatln("%s%n", toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
package org.openapitools.generator.gradle.plugin.tasks
|
||||
|
||||
import com.samskivert.mustache.Mustache
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.internal.logging.text.StyledTextOutput
|
||||
import org.gradle.internal.logging.text.StyledTextOutputFactory
|
||||
import org.gradle.kotlin.dsl.property
|
||||
import org.openapitools.codegen.CodegenConfig
|
||||
import org.openapitools.codegen.CodegenConstants
|
||||
import org.openapitools.codegen.DefaultGenerator
|
||||
import org.openapitools.codegen.SupportingFile
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.nio.charset.Charset
|
||||
|
||||
/**
|
||||
* A task which generates a new generator (meta). Useful for redistributable generator packages.
|
||||
*
|
||||
* @author Jim Schubert
|
||||
*/
|
||||
open class MetaTask : DefaultTask() {
|
||||
|
||||
@get:Internal
|
||||
val generatorName = project.objects.property<String>()
|
||||
|
||||
@get:Internal
|
||||
val packageName = project.objects.property<String>()
|
||||
|
||||
@get:Internal
|
||||
val outputFolder = project.objects.property<String>()
|
||||
|
||||
@Suppress("unused")
|
||||
@TaskAction
|
||||
fun doWork() {
|
||||
|
||||
val packageToPath = packageName.get().replace(".", File.separator)
|
||||
val dir = File(outputFolder.get())
|
||||
val klass = "${generatorName.get().titleCasedTextOnly()}Generator"
|
||||
|
||||
val templateResourceDir = generatorName.get().hyphenatedTextOnly()
|
||||
|
||||
val out = services.get(StyledTextOutputFactory::class.java).create("openapi")
|
||||
|
||||
out.withStyle(StyledTextOutput.Style.Info)
|
||||
|
||||
logger.debug("package: {}", packageName.get())
|
||||
logger.debug("dir: {}", dir.absolutePath)
|
||||
logger.debug("generator class: {}", klass)
|
||||
|
||||
val supportingFiles = listOf(
|
||||
SupportingFile("pom.mustache", "", "pom.xml"),
|
||||
SupportingFile("generatorClass.mustache", dir("src", "main", "java", packageToPath), "$klass.java"),
|
||||
SupportingFile("README.mustache", "", "README.md"),
|
||||
SupportingFile("api.template", dir("src", "main", "resources", templateResourceDir), "api.mustache"),
|
||||
SupportingFile("model.template", dir("src", "main", "resources", templateResourceDir), "model.mustache"),
|
||||
SupportingFile("myFile.template", dir("src", "main", "resources", templateResourceDir), "myFile.mustache"),
|
||||
SupportingFile("services.mustache", dir("src", "main", "resources", "META-INF", "services"), CodegenConfig::class.java.canonicalName))
|
||||
|
||||
val currentVersion = CodegenConstants::class.java.`package`.implementationVersion
|
||||
|
||||
val data = mapOf("generatorPackage" to packageToPath,
|
||||
"generatorClass" to klass,
|
||||
"name" to templateResourceDir,
|
||||
"fullyQualifiedGeneratorClass" to "${packageName.get()}.$klass",
|
||||
"openapiGeneratorVersion" to currentVersion)
|
||||
|
||||
val generator = DefaultGenerator()
|
||||
supportingFiles.map {
|
||||
try {
|
||||
val destinationFolder = File(File(dir.absolutePath), it.folder)
|
||||
destinationFolder.mkdirs()
|
||||
val outputFile = File(destinationFolder, it.destinationFilename)
|
||||
|
||||
val template = generator.readTemplate(File("codegen", it.templateFile).path)
|
||||
var formatted = template
|
||||
|
||||
if (it.templateFile.endsWith(".mustache")) {
|
||||
formatted = Mustache.compiler()
|
||||
.withLoader(loader(generator))
|
||||
.defaultValue("")
|
||||
.compile(template).execute(data)
|
||||
}
|
||||
|
||||
outputFile.writeText(formatted, Charset.forName("UTF8"))
|
||||
|
||||
out.formatln("Wrote file to %s", outputFile.absolutePath)
|
||||
|
||||
// TODO: register outputs
|
||||
// return outputFile
|
||||
} catch (e: IOException) {
|
||||
logger.error(e.message)
|
||||
throw GradleException("Can't generate project", e)
|
||||
}
|
||||
}
|
||||
out.withStyle(StyledTextOutput.Style.Success)
|
||||
out.formatln("Created generator %s", klass)
|
||||
}
|
||||
|
||||
private fun loader(generator: DefaultGenerator): Mustache.TemplateLoader {
|
||||
return Mustache.TemplateLoader { name ->
|
||||
generator.getTemplateReader("codegen${File.separator}$name.mustache")
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.titleCasedTextOnly(): String =
|
||||
this.split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "", transform = String::capitalize)
|
||||
|
||||
private fun String.hyphenatedTextOnly(): String =
|
||||
this.split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "-", transform = String::toLowerCase)
|
||||
|
||||
private fun dir(vararg parts: String): String =
|
||||
parts.joinToString(separator = File.separator)
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
package org.openapitools.generator.gradle.plugin.tasks
|
||||
|
||||
import io.swagger.parser.OpenAPIParser
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.api.tasks.options.Option
|
||||
import org.gradle.internal.logging.text.StyledTextOutput
|
||||
import org.gradle.internal.logging.text.StyledTextOutputFactory
|
||||
import org.gradle.kotlin.dsl.property
|
||||
|
||||
/**
|
||||
* A generator which validates an Open API spec. This task outputs a list of validation issues and errors.
|
||||
*
|
||||
* Example:
|
||||
* cli:
|
||||
*
|
||||
* ./gradlew openApiValidate --input=/path/to/file
|
||||
*
|
||||
* build.gradle:
|
||||
*
|
||||
* openApiMeta {
|
||||
* inputSpec = "path/to/spec.yaml"
|
||||
* }
|
||||
*
|
||||
* @author Jim Schubert
|
||||
*/
|
||||
open class ValidateTask : DefaultTask() {
|
||||
@get:Internal
|
||||
var inputSpec = project.objects.property<String>()
|
||||
|
||||
@Suppress("unused")
|
||||
@get:Internal
|
||||
@set:Option(option = "input", description = "The input specification.")
|
||||
var input: String? = null
|
||||
set(value) {
|
||||
inputSpec.set(value)
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
@TaskAction
|
||||
fun doWork() {
|
||||
val spec = inputSpec.get()
|
||||
logger.quiet("Validating spec $spec")
|
||||
val result = OpenAPIParser().readLocation(spec, null, null)
|
||||
val messages = result.messages.toSet()
|
||||
val out = services.get(StyledTextOutputFactory::class.java).create("openapi")
|
||||
|
||||
if (messages.isNotEmpty()) {
|
||||
|
||||
out.withStyle(StyledTextOutput.Style.Error)
|
||||
out.println("\nSpec is invalid.\nIssues:\n")
|
||||
|
||||
messages.forEach {
|
||||
out.withStyle(StyledTextOutput.Style.Error)
|
||||
out.println("\t$it\n")
|
||||
}
|
||||
|
||||
throw GradleException("Validation failed.")
|
||||
} else {
|
||||
out.withStyle(StyledTextOutput.Style.Success)
|
||||
out.println("Spec is valid.")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package org.openapitools.generator.gradle.plugin
|
||||
|
||||
import org.gradle.testkit.runner.GradleRunner
|
||||
import org.gradle.testkit.runner.TaskOutcome
|
||||
import org.testng.annotations.Test
|
||||
import java.io.File
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class GenerateTaskDslTest : TestBase() {
|
||||
override var temp: File = createTempDir(javaClass.simpleName)
|
||||
|
||||
private val defaultBuildGradle = """
|
||||
plugins {
|
||||
id 'org.openapi.generator'
|
||||
}
|
||||
openApiGenerate {
|
||||
generatorName = "kotlin"
|
||||
inputSpec = file("spec.yaml").absolutePath
|
||||
outputDir = file("build/kotlin").absolutePath
|
||||
apiPackage = "org.openapitools.example.api"
|
||||
invokerPackage = "org.openapitools.example.invoker"
|
||||
modelPackage = "org.openapitools.example.model"
|
||||
configOptions = [
|
||||
dateLibrary: "java8"
|
||||
]
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
@Test
|
||||
fun `openApiGenerate should create an expected file structure from DSL config`() {
|
||||
// Arrange
|
||||
val projectFiles = mapOf(
|
||||
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml")
|
||||
)
|
||||
withProject(defaultBuildGradle, projectFiles)
|
||||
|
||||
// Act
|
||||
val result = GradleRunner.create()
|
||||
.withProjectDir(temp)
|
||||
.withArguments("openApiGenerate")
|
||||
.withPluginClasspath()
|
||||
.build()
|
||||
|
||||
// Assert
|
||||
assertTrue(result.output.contains("Successfully generated code to"), "User friendly generate notice is missing.")
|
||||
|
||||
listOf(
|
||||
"build/kotlin/.openapi-generator-ignore",
|
||||
"build/kotlin/docs/PetsApi.md",
|
||||
"build/kotlin/docs/Pets.md",
|
||||
"build/kotlin/docs/Error.md",
|
||||
"build/kotlin/docs/Pet.md",
|
||||
"build/kotlin/README.md",
|
||||
"build/kotlin/build.gradle",
|
||||
"build/kotlin/.openapi-generator/VERSION",
|
||||
"build/kotlin/settings.gradle",
|
||||
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Pets.kt",
|
||||
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Pet.kt",
|
||||
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Error.kt",
|
||||
"build/kotlin/src/main/kotlin/org/openapitools/example/api/PetsApi.kt",
|
||||
"build/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt"
|
||||
).map {
|
||||
val f = File(temp, it)
|
||||
assertTrue(f.exists() && f.isFile, "An expected file was not generated when invoking the generation.")
|
||||
}
|
||||
|
||||
assertEquals(TaskOutcome.SUCCESS, result.task(":openApiGenerate")?.outcome,
|
||||
"Expected a successful run, but found ${result.task(":openApiGenerate")?.outcome}")
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package org.openapitools.generator.gradle.plugin
|
||||
|
||||
import org.gradle.testkit.runner.GradleRunner
|
||||
import org.gradle.testkit.runner.TaskOutcome
|
||||
import org.testng.annotations.Test
|
||||
import java.io.File
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class GeneratorsTaskDslTest : TestBase() {
|
||||
override var temp: File = createTempDir(javaClass.simpleName)
|
||||
|
||||
@Test
|
||||
fun `openApiGenerators should list generators available to the user`() {
|
||||
// Arrange
|
||||
withProject("""
|
||||
| plugins {
|
||||
| id 'org.openapi.generator'
|
||||
| }
|
||||
""".trimMargin())
|
||||
|
||||
// Act
|
||||
val result = GradleRunner.create()
|
||||
.withProjectDir(temp)
|
||||
.withArguments("openApiGenerators")
|
||||
.withPluginClasspath()
|
||||
.build()
|
||||
|
||||
// Assert
|
||||
assertTrue(result.output.contains("The following generators are available:"), "User friendly generator notice is missing.")
|
||||
assertTrue(result.output.contains("CLIENT generators:"), "Expected client generator header is missing.")
|
||||
assertTrue(result.output.contains("android"), "Spot-checking listed client generators is missing a client generator.")
|
||||
assertTrue(result.output.contains("SERVER generators:"), "Expected server generator header is missing.")
|
||||
assertTrue(result.output.contains("kotlin-server"), "Spot-checking listed server generators is missing a server generator.")
|
||||
assertEquals(TaskOutcome.SUCCESS, result.task(":openApiGenerators")?.outcome,
|
||||
"Expected a successful run, but found ${result.task(":openApiGenerators")?.outcome}")
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package org.openapitools.generator.gradle.plugin
|
||||
|
||||
import org.gradle.testkit.runner.GradleRunner
|
||||
import org.gradle.testkit.runner.TaskOutcome
|
||||
import org.testng.annotations.Test
|
||||
import java.io.File
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class MetaTaskDslTest : TestBase() {
|
||||
override var temp: File = createTempDir(javaClass.simpleName)
|
||||
|
||||
@Test
|
||||
fun `openApiMeta should generate desired project contents`() {
|
||||
// Arrange
|
||||
val buildDirReplacement = "\$buildDir/meta"
|
||||
withProject("""
|
||||
| plugins {
|
||||
| id 'org.openapi.generator'
|
||||
| }
|
||||
|
|
||||
| openApiMeta {
|
||||
| generatorName = "Sample"
|
||||
| packageName = "org.openapitools.example"
|
||||
| outputFolder = "$buildDirReplacement".toString()
|
||||
| }
|
||||
""".trimMargin())
|
||||
|
||||
// Act
|
||||
val result = GradleRunner.create()
|
||||
.withProjectDir(temp)
|
||||
.withArguments("openApiMeta")
|
||||
.withPluginClasspath()
|
||||
.build()
|
||||
|
||||
// Assert
|
||||
assertTrue(result.output.contains("Wrote file to"), "User friendly write notice is missing.")
|
||||
|
||||
// To avoid any OS-specific output causing issues with our stdout comparisons, only compare on expected filenames.
|
||||
listOf(
|
||||
"SampleGenerator.java",
|
||||
"README.md",
|
||||
"api.mustache",
|
||||
"model.mustache",
|
||||
"myFile.mustache",
|
||||
"org.openapitools.codegen.CodegenConfig",
|
||||
"pom.xml"
|
||||
).map {
|
||||
assertTrue(result.output.contains(it), "Expected $it to be listed in gradle stdout.")
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
TaskOutcome.SUCCESS,
|
||||
result.task(":openApiMeta")?.outcome,
|
||||
"Expected a successful run, but found ${result.task(":openApiMeta")?.outcome}"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package org.openapitools.generator.gradle.plugin
|
||||
|
||||
import org.testng.annotations.AfterMethod
|
||||
import org.testng.annotations.BeforeMethod
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
|
||||
abstract class TestBase {
|
||||
protected open lateinit var temp: File
|
||||
|
||||
@BeforeMethod
|
||||
protected fun before() {
|
||||
temp = createTempDir(javaClass.simpleName)
|
||||
temp.deleteOnExit()
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
protected fun after(){
|
||||
temp.deleteRecursively()
|
||||
}
|
||||
|
||||
protected fun withProject(
|
||||
buildContents: String,
|
||||
projectFiles: Map<String, InputStream> = mapOf()
|
||||
) {
|
||||
val buildFile = File(temp,"build.gradle")
|
||||
buildFile.writeText(buildContents)
|
||||
|
||||
projectFiles.forEach { entry ->
|
||||
val target = File(temp, entry.key)
|
||||
entry.value.copyTo(target.outputStream())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
package org.openapitools.generator.gradle.plugin
|
||||
|
||||
import org.gradle.testkit.runner.GradleRunner
|
||||
import org.gradle.testkit.runner.TaskOutcome.FAILED
|
||||
import org.gradle.testkit.runner.TaskOutcome.SUCCESS
|
||||
import org.testng.annotations.Test
|
||||
import java.io.File
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class ValidateTaskDslTest : TestBase() {
|
||||
override var temp: File = createTempDir(javaClass.simpleName)
|
||||
|
||||
@Test
|
||||
fun `openApiValidate should fail on non-file spec`() {
|
||||
// Arrange
|
||||
withProject("""
|
||||
| plugins {
|
||||
| id 'org.openapi.generator'
|
||||
| }
|
||||
|
|
||||
| openApiValidate {
|
||||
| inputSpec = "some_location"
|
||||
| }
|
||||
""".trimMargin())
|
||||
|
||||
// Act
|
||||
val result = GradleRunner.create()
|
||||
.withProjectDir(temp)
|
||||
.withArguments("openApiValidate")
|
||||
.withPluginClasspath()
|
||||
.buildAndFail()
|
||||
|
||||
// Assert
|
||||
assertTrue(result.output.contains("unable to read location `some_location`"), "Unexpected/no message presented to the user for a spec pointing to an invalid URI.")
|
||||
assertEquals(FAILED, result.task(":openApiValidate")?.outcome,
|
||||
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `openApiValidate should succeed on valid spec`() {
|
||||
// Arrange
|
||||
val projectFiles = mapOf(
|
||||
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml")
|
||||
)
|
||||
|
||||
withProject("""
|
||||
| plugins {
|
||||
| id 'org.openapi.generator'
|
||||
| }
|
||||
|
|
||||
| openApiValidate {
|
||||
| inputSpec = file("spec.yaml").absolutePath
|
||||
| }
|
||||
""".trimMargin(), projectFiles)
|
||||
|
||||
// Act
|
||||
val result = GradleRunner.create()
|
||||
.withProjectDir(temp)
|
||||
.withArguments("openApiValidate")
|
||||
.withPluginClasspath()
|
||||
.build()
|
||||
|
||||
// Assert
|
||||
assertTrue(result.output.contains("Spec is valid."), "Unexpected/no message presented to the user for a valid spec.")
|
||||
assertEquals(SUCCESS, result.task(":openApiValidate")?.outcome,
|
||||
"Expected a successful run, but found ${result.task(":openApiValidate")?.outcome}")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `openApiValidate should fail on invalid spec`() {
|
||||
// Arrange
|
||||
val projectFiles = mapOf(
|
||||
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0-invalid.yaml")
|
||||
)
|
||||
withProject("""
|
||||
| plugins {
|
||||
| id 'org.openapi.generator'
|
||||
| }
|
||||
|
|
||||
| openApiValidate {
|
||||
| inputSpec = file('spec.yaml').absolutePath
|
||||
| }
|
||||
""".trimMargin(), projectFiles)
|
||||
|
||||
// Act
|
||||
val result = GradleRunner.create()
|
||||
.withProjectDir(temp)
|
||||
.withArguments("openApiValidate")
|
||||
.withPluginClasspath()
|
||||
.buildAndFail()
|
||||
|
||||
// Assert
|
||||
assertTrue(result.output.contains("Spec is invalid."), "Unexpected/no message presented to the user for an invalid spec.")
|
||||
assertEquals(FAILED, result.task(":openApiValidate")?.outcome,
|
||||
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
openapi: "3.0.0"
|
||||
servers:
|
||||
- url: http://petstore.swagger.io/v1
|
||||
paths:
|
||||
/pets:
|
||||
get:
|
||||
summary: List all pets
|
||||
operationId: listPets
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: limit
|
||||
in: query
|
||||
description: How many items to return at one time (max 100)
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
responses:
|
||||
'200':
|
||||
description: A paged array of pets
|
||||
headers:
|
||||
x-next:
|
||||
description: A link to the next page of responses
|
||||
schema:
|
||||
type: string
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
post:
|
||||
summary: Create a pet
|
||||
tags:
|
||||
- pets
|
||||
responses:
|
||||
'201':
|
||||
description: Null response
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
/pets/{petId}:
|
||||
get:
|
||||
summary: Info for a specific pet
|
||||
operationId: showPetById
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
required: true
|
||||
description: The id of the pet to retrieve
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Expected response to a valid request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
components:
|
||||
schemas:
|
||||
Pet:
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
tag:
|
||||
type: string
|
||||
Pets:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
Error:
|
||||
required:
|
||||
- code
|
||||
- message
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int32
|
||||
message:
|
||||
type: string
|
||||
@@ -1,109 +0,0 @@
|
||||
openapi: "3.0.0"
|
||||
info:
|
||||
version: 1.0.0
|
||||
title: Swagger Petstore
|
||||
license:
|
||||
name: MIT
|
||||
servers:
|
||||
- url: http://petstore.swagger.io/v1
|
||||
paths:
|
||||
/pets:
|
||||
get:
|
||||
summary: List all pets
|
||||
operationId: listPets
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: limit
|
||||
in: query
|
||||
description: How many items to return at one time (max 100)
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
responses:
|
||||
'200':
|
||||
description: A paged array of pets
|
||||
headers:
|
||||
x-next:
|
||||
description: A link to the next page of responses
|
||||
schema:
|
||||
type: string
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
post:
|
||||
summary: Create a pet
|
||||
operationId: createPets
|
||||
tags:
|
||||
- pets
|
||||
responses:
|
||||
'201':
|
||||
description: Null response
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
/pets/{petId}:
|
||||
get:
|
||||
summary: Info for a specific pet
|
||||
operationId: showPetById
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
required: true
|
||||
description: The id of the pet to retrieve
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Expected response to a valid request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
components:
|
||||
schemas:
|
||||
Pet:
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
tag:
|
||||
type: string
|
||||
Pets:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
Error:
|
||||
required:
|
||||
- code
|
||||
- message
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int32
|
||||
message:
|
||||
type: string
|
||||
@@ -181,3 +181,5 @@ compileTestKotlin {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
}
|
||||
|
||||
uploadArchives.dependsOn 'check'
|
||||
|
||||
@@ -48,14 +48,12 @@ class GenerateTaskDslTest : TestBase() {
|
||||
listOf(
|
||||
"build/kotlin/.openapi-generator-ignore",
|
||||
"build/kotlin/docs/PetsApi.md",
|
||||
"build/kotlin/docs/Pets.md",
|
||||
"build/kotlin/docs/Error.md",
|
||||
"build/kotlin/docs/Pet.md",
|
||||
"build/kotlin/README.md",
|
||||
"build/kotlin/build.gradle",
|
||||
"build/kotlin/.openapi-generator/VERSION",
|
||||
"build/kotlin/settings.gradle",
|
||||
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Pets.kt",
|
||||
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Pet.kt",
|
||||
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Error.kt",
|
||||
"build/kotlin/src/main/kotlin/org/openapitools/example/api/PetsApi.kt",
|
||||
|
||||
@@ -145,12 +145,6 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
@Parameter(name = "skipOverwrite", required = false)
|
||||
private Boolean skipOverwrite;
|
||||
|
||||
/**
|
||||
* Specifies if the existing files should be overwritten during the generation.
|
||||
*/
|
||||
@Parameter(name = "removeOperationIdPrefix", required = false)
|
||||
private Boolean removeOperationIdPrefix;
|
||||
|
||||
/**
|
||||
* The package to use for generated api objects/classes
|
||||
*/
|
||||
@@ -211,6 +205,36 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
@Parameter(name = "ignoreFileOverride", required = false)
|
||||
private String ignoreFileOverride;
|
||||
|
||||
/**
|
||||
* To remove operationId prefix (e.g. user_getName => getName)
|
||||
*/
|
||||
@Parameter(name = "removeOperationIdPrefix", required = false)
|
||||
private Boolean removeOperationIdPrefix;
|
||||
|
||||
/**
|
||||
* To write all log messages (not just errors) to STDOUT
|
||||
*/
|
||||
@Parameter(name = "logToStderr", required = false)
|
||||
private Boolean logToStderr;
|
||||
|
||||
/**
|
||||
* To file post-processing hook
|
||||
*/
|
||||
@Parameter(name = "enablePostProcessFile", required = false)
|
||||
private Boolean enablePostProcessFile;
|
||||
|
||||
/**
|
||||
* To skip spec validation
|
||||
*/
|
||||
@Parameter(name = "skipValidateSpec", required = false)
|
||||
private Boolean skipValidateSpec;
|
||||
|
||||
/**
|
||||
* To generate alias (array, map) as model
|
||||
*/
|
||||
@Parameter(name = "generateAliasAsModel", required = false)
|
||||
private Boolean generateAliasAsModel;
|
||||
|
||||
/**
|
||||
* A map of language-specific parameters as passed with the -c option to the command line
|
||||
*/
|
||||
@@ -433,6 +457,22 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
configurator.setIgnoreFileOverride(ignoreFileOverride);
|
||||
}
|
||||
|
||||
if (skipValidateSpec != null) {
|
||||
configurator.setSkipOverwrite(skipValidateSpec);
|
||||
}
|
||||
|
||||
if (logToStderr != null) {
|
||||
configurator.setLogToStderr(logToStderr);
|
||||
}
|
||||
|
||||
if (enablePostProcessFile != null) {
|
||||
configurator.setEnablePostProcessFile(enablePostProcessFile);
|
||||
}
|
||||
|
||||
if (generateAliasAsModel != null) {
|
||||
configurator.setGenerateAliasAsModel(generateAliasAsModel);
|
||||
}
|
||||
|
||||
// TODO: After 3.0.0 release (maybe for 3.1.0): Fully deprecate lang.
|
||||
if (isNotEmpty(generatorName)) {
|
||||
configurator.setGeneratorName(generatorName);
|
||||
|
||||
@@ -264,11 +264,11 @@ public interface CodegenConfig {
|
||||
|
||||
boolean isEnablePostProcessFile();
|
||||
|
||||
public void setEnablePostProcessFile(boolean isEnablePostProcessFile);
|
||||
void setEnablePostProcessFile(boolean isEnablePostProcessFile);
|
||||
|
||||
// set OpenAPI and schemas
|
||||
public void setGlobalOpenAPI(OpenAPI openAPI);
|
||||
void setGlobalOpenAPI(OpenAPI openAPI);
|
||||
|
||||
public void setGlobalSchemas(OpenAPI openAPI);
|
||||
void setGlobalSchemas(OpenAPI openAPI);
|
||||
|
||||
}
|
||||
|
||||
@@ -284,6 +284,9 @@ public class CodegenConstants {
|
||||
|
||||
public static final String OPEN_API_SPEC_NAME = "openAPISpecName";
|
||||
|
||||
public static final String GENERATE_ALIAS_AS_MODEL = "generateAliasAsModel";
|
||||
public static final String GENERATE_ALIAS_AS_MODEL_DESC = "Generate alias to map, array as models";
|
||||
|
||||
public static final String USE_COMPARE_NET_OBJECTS = "useCompareNetObjects";
|
||||
public static final String USE_COMPARE_NET_OBJECTS_DESC = "Use KellermanSoftware.CompareNetObjects for deep recursive object comparison. WARNING: this option incurs potential performance impact.";
|
||||
}
|
||||
@@ -71,7 +71,6 @@ import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -83,8 +82,8 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.openapitools.codegen.utils.StringUtils.camelize;
|
||||
import static org.openapitools.codegen.utils.StringUtils.underscore;
|
||||
import static org.openapitools.codegen.utils.StringUtils.escape;
|
||||
import static org.openapitools.codegen.utils.StringUtils.underscore;
|
||||
|
||||
public class DefaultCodegen implements CodegenConfig {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
|
||||
@@ -209,6 +208,11 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
this.setEnablePostProcessFile(Boolean.valueOf(additionalProperties
|
||||
.get(CodegenConstants.ENABLE_POST_PROCESS_FILE).toString()));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.GENERATE_ALIAS_AS_MODEL)) {
|
||||
ModelUtils.setGenerateAliasAsModel(Boolean.valueOf(additionalProperties
|
||||
.get(CodegenConstants.GENERATE_ALIAS_AS_MODEL).toString()));
|
||||
}
|
||||
}
|
||||
|
||||
// override with any special post-processing for all models
|
||||
@@ -333,7 +337,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
enumVar.put("isString", isDataTypeString(cm.dataType));
|
||||
enumVars.add(enumVar);
|
||||
}
|
||||
// if "x-enum-varnames" defined, update varnames
|
||||
// if "x-enum-varnames" or "x-enum-descriptions" defined, update varnames
|
||||
updateEnumVarsWithExtensions(enumVars, cm.getVendorExtensions());
|
||||
cm.allowableValues.put("enumVars", enumVars);
|
||||
}
|
||||
@@ -1500,14 +1504,15 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Capitalize the string
|
||||
* Capitalize the string. Please use org.openapitools.codegen.utils.StringUtils.camelize instead as this method will be deprecated.
|
||||
*
|
||||
* @param name string to be capitalized
|
||||
* @return capitalized string
|
||||
* @deprecated
|
||||
*/
|
||||
@SuppressWarnings("static-method")
|
||||
public String initialCaps(String name) {
|
||||
return StringUtils.capitalize(name);
|
||||
return camelize(name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1603,7 +1608,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
* @return capitalized model name
|
||||
*/
|
||||
public String toModelName(final String name) {
|
||||
return initialCaps(modelNamePrefix + name + modelNameSuffix);
|
||||
return initialCaps(modelNamePrefix + "_" + name + "_" + modelNameSuffix);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1835,7 +1840,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
.map(s -> ModelUtils.getSimpleRef(s.get$ref()))
|
||||
.collect(Collectors.toSet());
|
||||
if (parentSchemas.contains(schemaName)) {
|
||||
discriminator.getMappedModels().add(new MappedModel(childName, childName));
|
||||
discriminator.getMappedModels().add(new MappedModel(childName, toModelName(childName)));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1858,18 +1863,21 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
protected void addProperties(Map<String, Schema> properties, List<String> required, Schema
|
||||
schema, Map<String, Schema> allSchemas) {
|
||||
if (schema instanceof ComposedSchema) {
|
||||
throw new RuntimeException("Please report the issue: Cannot process Composed Schema in addProperties: " + schema);
|
||||
/*
|
||||
ComposedSchema composedSchema = (ComposedSchema) schema;
|
||||
if (composedSchema.getAllOf() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Schema component : composedSchema.getAllOf()) {
|
||||
addProperties(properties, required, component, allSchemas);
|
||||
}
|
||||
|
||||
if (composedSchema.getOneOf() != null) {
|
||||
throw new RuntimeException("Please report the issue: Cannot process oneOf (Composed Scheme) in addProperties: " + schema);
|
||||
}
|
||||
|
||||
if (composedSchema.getAnyOf() != null) {
|
||||
throw new RuntimeException("Please report the issue: Cannot process anyOf (Composed Schema) in addProperties: " + schema);
|
||||
}
|
||||
|
||||
return;
|
||||
*/
|
||||
}
|
||||
|
||||
Schema unaliasSchema = ModelUtils.unaliasSchema(globalSchemas, schema);
|
||||
@@ -4026,6 +4034,9 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
if (Boolean.TRUE.equals(property.isFile)) {
|
||||
parameter.isFile = true;
|
||||
}
|
||||
if (Boolean.TRUE.equals(property.isModel)) {
|
||||
parameter.isModel = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4073,7 +4084,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
enumVar.put("isString", isDataTypeString(dataType));
|
||||
enumVars.add(enumVar);
|
||||
}
|
||||
// if "x-enum-varnames" defined, update varnames
|
||||
// if "x-enum-varnames" or "x-enum-descriptions" defined, update varnames
|
||||
Map<String, Object> extensions = var.mostInnerItems != null ? var.mostInnerItems.getVendorExtensions() : var.getVendorExtensions();
|
||||
updateEnumVarsWithExtensions(enumVars, extensions);
|
||||
allowableValues.put("enumVars", enumVars);
|
||||
@@ -4093,13 +4104,19 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEnumVarsWithExtensions
|
||||
(List<Map<String, Object>> enumVars, Map<String, Object> vendorExtensions) {
|
||||
if (vendorExtensions != null && vendorExtensions.containsKey("x-enum-varnames")) {
|
||||
List<String> alias = (List<String>) vendorExtensions.get("x-enum-varnames");
|
||||
int size = Math.min(enumVars.size(), alias.size());
|
||||
private void updateEnumVarsWithExtensions(List<Map<String, Object>> enumVars, Map<String, Object> vendorExtensions) {
|
||||
if (vendorExtensions != null) {
|
||||
updateEnumVarsWithExtensions(enumVars, vendorExtensions, "x-enum-varnames", "name");
|
||||
updateEnumVarsWithExtensions(enumVars, vendorExtensions, "x-enum-descriptions", "enumDescription");
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEnumVarsWithExtensions(List<Map<String, Object>> enumVars, Map<String, Object> vendorExtensions, String extensionKey, String key) {
|
||||
if (vendorExtensions.containsKey(extensionKey)) {
|
||||
List<String> values = (List<String>) vendorExtensions.get(extensionKey);
|
||||
int size = Math.min(enumVars.size(), values.size());
|
||||
for (int i = 0; i < size; i++) {
|
||||
enumVars.get(i).put("name", alias.get(i));
|
||||
enumVars.get(i).put(key, values.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4185,6 +4202,9 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
protected Parameter getParameterFromRef(String ref, OpenAPI openAPI) {
|
||||
String parameterName = ref.substring(ref.lastIndexOf('/') + 1);
|
||||
Map<String, Parameter> parameterMap = openAPI.getComponents().getParameters();
|
||||
if (parameterMap == null ) { // can't find the ref
|
||||
throw new RuntimeException(ref + " not defined in the spec.");
|
||||
}
|
||||
return parameterMap.get(parameterName);
|
||||
}
|
||||
|
||||
|
||||
@@ -434,13 +434,13 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
LOGGER.info("Model " + name + " not generated since it's a free-form object");
|
||||
continue;
|
||||
} else if (ModelUtils.isMapSchema(schema)) { // check to see if it's a "map" model
|
||||
if (schema.getProperties() == null || schema.getProperties().isEmpty()) {
|
||||
if (!ModelUtils.isGenerateAliasAsModel() && (schema.getProperties() == null || schema.getProperties().isEmpty())) {
|
||||
// schema without property, i.e. alias to map
|
||||
LOGGER.info("Model " + name + " not generated since it's an alias to map (without property)");
|
||||
continue;
|
||||
}
|
||||
} else if (ModelUtils.isArraySchema(schema)) { // check to see if it's an "array" model
|
||||
if (schema.getProperties() == null || schema.getProperties().isEmpty()) {
|
||||
if (!ModelUtils.isGenerateAliasAsModel() && (schema.getProperties() == null || schema.getProperties().isEmpty())) {
|
||||
// schema without property, i.e. alias to array
|
||||
LOGGER.info("Model " + name + " not generated since it's an alias to array (without property)");
|
||||
continue;
|
||||
@@ -839,6 +839,11 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
if (authMethods != null && !authMethods.isEmpty()) {
|
||||
bundle.put("authMethods", authMethods);
|
||||
bundle.put("hasAuthMethods", true);
|
||||
|
||||
if (hasOAuthMethods(authMethods)) {
|
||||
bundle.put("hasOAuthMethods", true);
|
||||
bundle.put("oauthMethods", getOAuthMethods(authMethods));
|
||||
}
|
||||
}
|
||||
|
||||
List<CodegenServer> servers = config.fromServers(openAPI.getServers());
|
||||
@@ -1182,4 +1187,26 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
}
|
||||
return authMethods;
|
||||
}
|
||||
|
||||
private boolean hasOAuthMethods(List<CodegenSecurity> authMethods) {
|
||||
for (CodegenSecurity cs : authMethods) {
|
||||
if (cs.isOAuth) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<CodegenSecurity> getOAuthMethods(List<CodegenSecurity> authMethods) {
|
||||
List<CodegenSecurity> oauthMethods = new ArrayList<>();
|
||||
|
||||
for (CodegenSecurity cs : authMethods) {
|
||||
if (cs.isOAuth) {
|
||||
oauthMethods.add(cs);
|
||||
}
|
||||
}
|
||||
|
||||
return oauthMethods;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,17 +17,16 @@
|
||||
|
||||
package org.openapitools.codegen;
|
||||
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.*;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||
import io.swagger.v3.oas.models.media.ObjectSchema;
|
||||
import io.swagger.v3.oas.models.media.*;
|
||||
import io.swagger.v3.oas.models.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.models.Operation;
|
||||
import io.swagger.v3.oas.models.PathItem;
|
||||
import io.swagger.v3.oas.models.parameters.Parameter;
|
||||
import io.swagger.v3.oas.models.parameters.RequestBody;
|
||||
import io.swagger.v3.core.util.Json;
|
||||
import io.swagger.v3.oas.models.responses.ApiResponses;
|
||||
import org.openapitools.codegen.utils.ModelUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -49,266 +48,270 @@ public class InlineModelResolver {
|
||||
this.openapi = openapi;
|
||||
|
||||
if (openapi.getComponents() == null) {
|
||||
return; // There's nothing here
|
||||
openapi.setComponents(new Components());
|
||||
}
|
||||
|
||||
if (openapi.getComponents().getSchemas() == null) {
|
||||
openapi.getComponents().setSchemas(new HashMap<String, Schema>());
|
||||
}
|
||||
// operations
|
||||
Map<String, PathItem> paths = openapi.getPaths();
|
||||
Map<String, Schema> models = openapi.getComponents().getSchemas();
|
||||
if (paths != null) {
|
||||
for (String pathname : paths.keySet()) {
|
||||
PathItem path = paths.get(pathname);
|
||||
for (Operation operation : path.readOperations()) {
|
||||
RequestBody requestBody = operation.getRequestBody();
|
||||
if (requestBody != null) {
|
||||
Schema model = ModelUtils.getSchemaFromRequestBody(requestBody);
|
||||
if (model instanceof ObjectSchema) {
|
||||
Schema obj = (Schema) model;
|
||||
if (obj.getType() == null || "object".equals(obj.getType())) {
|
||||
if (obj.getProperties() != null && obj.getProperties().size() > 0) {
|
||||
flattenProperties(obj.getProperties(), pathname);
|
||||
// for model name, use "title" if defined, otherwise default to 'inline_object'
|
||||
String modelName = resolveModelName(obj.getTitle(), "inline_object");
|
||||
addGenerated(modelName, model);
|
||||
openapi.getComponents().addSchemas(modelName, model);
|
||||
|
||||
// create request body
|
||||
RequestBody rb = new RequestBody();
|
||||
Content content = new Content();
|
||||
MediaType mt = new MediaType();
|
||||
Schema schema = new Schema();
|
||||
schema.set$ref(modelName);
|
||||
mt.setSchema(schema);
|
||||
flattenPaths(openapi);
|
||||
flattenComponents(openapi);
|
||||
}
|
||||
|
||||
// get "consumes", e.g. application/xml, application/json
|
||||
Set<String> consumes;
|
||||
if (requestBody == null || requestBody.getContent() == null || requestBody.getContent().isEmpty()) {
|
||||
consumes = new HashSet<>();
|
||||
consumes.add("application/json"); // default to application/json
|
||||
LOGGER.info("Default to application/json for inline body schema");
|
||||
} else {
|
||||
consumes = requestBody.getContent().keySet();
|
||||
}
|
||||
/**
|
||||
* Flatten inline models in Paths
|
||||
*
|
||||
* @param openAPI target spec
|
||||
*/
|
||||
private void flattenPaths(OpenAPI openAPI) {
|
||||
Paths paths = openAPI.getPaths();
|
||||
if (paths == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String consume : consumes) {
|
||||
content.addMediaType(consume, mt);
|
||||
}
|
||||
for (String pathname : paths.keySet()) {
|
||||
PathItem path = paths.get(pathname);
|
||||
for (Operation operation : path.readOperations()) {
|
||||
flattenRequestBody(openAPI, pathname, operation);
|
||||
flattenParameters(openAPI, pathname, operation);
|
||||
flattenResponses(openAPI, pathname, operation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rb.setContent(content);
|
||||
/**
|
||||
* Flatten inline models in RequestBody
|
||||
*
|
||||
* @param openAPI target spec
|
||||
* @param pathname target pathname
|
||||
* @param operation target operation
|
||||
*/
|
||||
private void flattenRequestBody(OpenAPI openAPI, String pathname, Operation operation) {
|
||||
RequestBody requestBody = operation.getRequestBody();
|
||||
if (requestBody == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// add to openapi "components"
|
||||
if (openapi.getComponents().getRequestBodies() == null) {
|
||||
Map<String, RequestBody> requestBodies = new HashMap<String, RequestBody>();
|
||||
requestBodies.put(modelName, rb);
|
||||
openapi.getComponents().setRequestBodies(requestBodies);
|
||||
} else {
|
||||
openapi.getComponents().getRequestBodies().put(modelName, rb);
|
||||
}
|
||||
Schema model = ModelUtils.getSchemaFromRequestBody(requestBody);
|
||||
if (model instanceof ObjectSchema) {
|
||||
Schema obj = (Schema) model;
|
||||
if (obj.getType() == null || "object".equals(obj.getType())) {
|
||||
if (obj.getProperties() != null && obj.getProperties().size() > 0) {
|
||||
flattenProperties(obj.getProperties(), pathname);
|
||||
// for model name, use "title" if defined, otherwise default to 'inline_object'
|
||||
String modelName = resolveModelName(obj.getTitle(), "inline_object");
|
||||
addGenerated(modelName, model);
|
||||
openAPI.getComponents().addSchemas(modelName, model);
|
||||
|
||||
// update requestBody to use $ref instead of inline def
|
||||
requestBody.set$ref(modelName);
|
||||
// create request body
|
||||
RequestBody rb = new RequestBody();
|
||||
Content content = new Content();
|
||||
MediaType mt = new MediaType();
|
||||
Schema schema = new Schema();
|
||||
schema.set$ref(modelName);
|
||||
mt.setSchema(schema);
|
||||
|
||||
}
|
||||
}
|
||||
} else if (model instanceof ArraySchema) {
|
||||
ArraySchema am = (ArraySchema) model;
|
||||
Schema inner = am.getItems();
|
||||
if (inner instanceof ObjectSchema) {
|
||||
ObjectSchema op = (ObjectSchema) inner;
|
||||
if (op.getProperties() != null && op.getProperties().size() > 0) {
|
||||
flattenProperties(op.getProperties(), pathname);
|
||||
String modelName = resolveModelName(op.getTitle(), null);
|
||||
Schema innerModel = modelFromProperty(op, modelName);
|
||||
String existing = matchGenerated(innerModel);
|
||||
if (existing != null) {
|
||||
Schema schema = new Schema().$ref(existing);
|
||||
schema.setRequired(op.getRequired());
|
||||
am.setItems(schema);
|
||||
} else {
|
||||
Schema schema = new Schema().$ref(modelName);
|
||||
schema.setRequired(op.getRequired());
|
||||
am.setItems(schema);
|
||||
addGenerated(modelName, innerModel);
|
||||
openapi.getComponents().addSchemas(modelName, innerModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// get "consumes", e.g. application/xml, application/json
|
||||
Set<String> consumes;
|
||||
if (requestBody == null || requestBody.getContent() == null || requestBody.getContent().isEmpty()) {
|
||||
consumes = new HashSet<>();
|
||||
consumes.add("application/json"); // default to application/json
|
||||
LOGGER.info("Default to application/json for inline body schema");
|
||||
} else {
|
||||
consumes = requestBody.getContent().keySet();
|
||||
}
|
||||
|
||||
List<Parameter> parameters = operation.getParameters();
|
||||
if (parameters != null) {
|
||||
for (Parameter parameter : parameters) {
|
||||
if (parameter.getSchema() != null) {
|
||||
Schema model = parameter.getSchema();
|
||||
if (model instanceof ObjectSchema) {
|
||||
Schema obj = (Schema) model;
|
||||
if (obj.getType() == null || "object".equals(obj.getType())) {
|
||||
if (obj.getProperties() != null && obj.getProperties().size() > 0) {
|
||||
flattenProperties(obj.getProperties(), pathname);
|
||||
String modelName = resolveModelName(obj.getTitle(), parameter.getName());
|
||||
|
||||
parameter.$ref(modelName);
|
||||
addGenerated(modelName, model);
|
||||
openapi.getComponents().addSchemas(modelName, model);
|
||||
}
|
||||
}
|
||||
} else if (model instanceof ArraySchema) {
|
||||
ArraySchema am = (ArraySchema) model;
|
||||
Schema inner = am.getItems();
|
||||
if (inner instanceof ObjectSchema) {
|
||||
ObjectSchema op = (ObjectSchema) inner;
|
||||
if (op.getProperties() != null && op.getProperties().size() > 0) {
|
||||
flattenProperties(op.getProperties(), pathname);
|
||||
String modelName = resolveModelName(op.getTitle(), parameter.getName());
|
||||
Schema innerModel = modelFromProperty(op, modelName);
|
||||
String existing = matchGenerated(innerModel);
|
||||
if (existing != null) {
|
||||
Schema schema = new Schema().$ref(existing);
|
||||
schema.setRequired(op.getRequired());
|
||||
am.setItems(schema);
|
||||
} else {
|
||||
Schema schema = new Schema().$ref(modelName);
|
||||
schema.setRequired(op.getRequired());
|
||||
am.setItems(schema);
|
||||
addGenerated(modelName, innerModel);
|
||||
openapi.getComponents().addSchemas(modelName, innerModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String consume : consumes) {
|
||||
content.addMediaType(consume, mt);
|
||||
}
|
||||
Map<String, ApiResponse> responses = operation.getResponses();
|
||||
if (responses != null) {
|
||||
for (String key : responses.keySet()) {
|
||||
ApiResponse response = responses.get(key);
|
||||
if (ModelUtils.getSchemaFromResponse(response) != null) {
|
||||
Schema property = ModelUtils.getSchemaFromResponse(response);
|
||||
if (property instanceof ObjectSchema) {
|
||||
ObjectSchema op = (ObjectSchema) property;
|
||||
if (op.getProperties() != null && op.getProperties().size() > 0) {
|
||||
String modelName = resolveModelName(op.getTitle(), "inline_response_" + key);
|
||||
Schema model = modelFromProperty(op, modelName);
|
||||
String existing = matchGenerated(model);
|
||||
Content content = response.getContent();
|
||||
for (MediaType mediaType : content.values()) {
|
||||
if (existing != null) {
|
||||
Schema schema = this.makeSchema(existing, property);
|
||||
schema.setRequired(op.getRequired());
|
||||
mediaType.setSchema(schema);
|
||||
} else {
|
||||
Schema schema = this.makeSchema(modelName, property);
|
||||
schema.setRequired(op.getRequired());
|
||||
mediaType.setSchema(schema);
|
||||
addGenerated(modelName, model);
|
||||
openapi.getComponents().addSchemas(modelName, model);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (property instanceof ArraySchema) {
|
||||
ArraySchema ap = (ArraySchema) property;
|
||||
Schema inner = ap.getItems();
|
||||
if (inner instanceof ObjectSchema) {
|
||||
ObjectSchema op = (ObjectSchema) inner;
|
||||
if (op.getProperties() != null && op.getProperties().size() > 0) {
|
||||
flattenProperties(op.getProperties(), pathname);
|
||||
String modelName = resolveModelName(op.getTitle(),
|
||||
"inline_response_" + key);
|
||||
Schema innerModel = modelFromProperty(op, modelName);
|
||||
String existing = matchGenerated(innerModel);
|
||||
if (existing != null) {
|
||||
Schema schema = this.makeSchema(existing, op);
|
||||
schema.setRequired(op.getRequired());
|
||||
ap.setItems(schema);
|
||||
} else {
|
||||
Schema schema = this.makeSchema(modelName, op);
|
||||
schema.setRequired(op.getRequired());
|
||||
ap.setItems(schema);
|
||||
addGenerated(modelName, innerModel);
|
||||
openapi.getComponents().addSchemas(modelName, innerModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (property instanceof MapSchema) {
|
||||
MapSchema mp = (MapSchema) property;
|
||||
Schema innerProperty = ModelUtils.getAdditionalProperties(mp);
|
||||
if (innerProperty instanceof ObjectSchema) {
|
||||
ObjectSchema op = (ObjectSchema) innerProperty;
|
||||
if (op.getProperties() != null && op.getProperties().size() > 0) {
|
||||
flattenProperties(op.getProperties(), pathname);
|
||||
String modelName = resolveModelName(op.getTitle(),
|
||||
"inline_response_" + key);
|
||||
Schema innerModel = modelFromProperty(op, modelName);
|
||||
String existing = matchGenerated(innerModel);
|
||||
if (existing != null) {
|
||||
Schema schema = new Schema().$ref(existing);
|
||||
schema.setRequired(op.getRequired());
|
||||
mp.setAdditionalProperties(schema);
|
||||
} else {
|
||||
Schema schema = new Schema().$ref(modelName);
|
||||
schema.setRequired(op.getRequired());
|
||||
mp.setAdditionalProperties(schema);
|
||||
addGenerated(modelName, innerModel);
|
||||
openapi.getComponents().addSchemas(modelName, innerModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rb.setContent(content);
|
||||
|
||||
// add to openapi "components"
|
||||
if (openAPI.getComponents().getRequestBodies() == null) {
|
||||
Map<String, RequestBody> requestBodies = new HashMap<String, RequestBody>();
|
||||
requestBodies.put(modelName, rb);
|
||||
openAPI.getComponents().setRequestBodies(requestBodies);
|
||||
} else {
|
||||
openAPI.getComponents().getRequestBodies().put(modelName, rb);
|
||||
}
|
||||
|
||||
// update requestBody to use $ref instead of inline def
|
||||
requestBody.set$ref(modelName);
|
||||
|
||||
}
|
||||
}
|
||||
} else if (model instanceof ArraySchema) {
|
||||
ArraySchema am = (ArraySchema) model;
|
||||
Schema inner = am.getItems();
|
||||
if (inner instanceof ObjectSchema) {
|
||||
ObjectSchema op = (ObjectSchema) inner;
|
||||
if (op.getProperties() != null && op.getProperties().size() > 0) {
|
||||
flattenProperties(op.getProperties(), pathname);
|
||||
String modelName = resolveModelName(op.getTitle(), null);
|
||||
Schema innerModel = modelFromProperty(op, modelName);
|
||||
String existing = matchGenerated(innerModel);
|
||||
if (existing != null) {
|
||||
Schema schema = new Schema().$ref(existing);
|
||||
schema.setRequired(op.getRequired());
|
||||
am.setItems(schema);
|
||||
} else {
|
||||
Schema schema = new Schema().$ref(modelName);
|
||||
schema.setRequired(op.getRequired());
|
||||
am.setItems(schema);
|
||||
addGenerated(modelName, innerModel);
|
||||
openAPI.getComponents().addSchemas(modelName, innerModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten inline models in parameters
|
||||
*
|
||||
* @param openAPI target spec
|
||||
* @param pathname target pathname
|
||||
* @param operation target operation
|
||||
*/
|
||||
private void flattenParameters(OpenAPI openAPI, String pathname, Operation operation) {
|
||||
List<Parameter> parameters = operation.getParameters();
|
||||
if (parameters == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Parameter parameter : parameters) {
|
||||
if (parameter.getSchema() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Schema model = parameter.getSchema();
|
||||
if (model instanceof ObjectSchema) {
|
||||
Schema obj = (Schema) model;
|
||||
if (obj.getType() == null || "object".equals(obj.getType())) {
|
||||
if (obj.getProperties() != null && obj.getProperties().size() > 0) {
|
||||
flattenProperties(obj.getProperties(), pathname);
|
||||
String modelName = resolveModelName(obj.getTitle(), parameter.getName());
|
||||
|
||||
parameter.$ref(modelName);
|
||||
addGenerated(modelName, model);
|
||||
openAPI.getComponents().addSchemas(modelName, model);
|
||||
}
|
||||
}
|
||||
} else if (model instanceof ArraySchema) {
|
||||
ArraySchema am = (ArraySchema) model;
|
||||
Schema inner = am.getItems();
|
||||
if (inner instanceof ObjectSchema) {
|
||||
ObjectSchema op = (ObjectSchema) inner;
|
||||
if (op.getProperties() != null && op.getProperties().size() > 0) {
|
||||
flattenProperties(op.getProperties(), pathname);
|
||||
String modelName = resolveModelName(op.getTitle(), parameter.getName());
|
||||
Schema innerModel = modelFromProperty(op, modelName);
|
||||
String existing = matchGenerated(innerModel);
|
||||
if (existing != null) {
|
||||
Schema schema = new Schema().$ref(existing);
|
||||
schema.setRequired(op.getRequired());
|
||||
am.setItems(schema);
|
||||
} else {
|
||||
Schema schema = new Schema().$ref(modelName);
|
||||
schema.setRequired(op.getRequired());
|
||||
am.setItems(schema);
|
||||
addGenerated(modelName, innerModel);
|
||||
openAPI.getComponents().addSchemas(modelName, innerModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// definitions
|
||||
if (models != null) {
|
||||
List<String> modelNames = new ArrayList<String>(models.keySet());
|
||||
for (String modelName : modelNames) {
|
||||
Schema model = models.get(modelName);
|
||||
if (model instanceof Schema) {
|
||||
Schema m = (Schema) model;
|
||||
Map<String, Schema> properties = m.getProperties();
|
||||
flattenProperties(properties, modelName);
|
||||
fixStringModel(m);
|
||||
} else if (ModelUtils.isArraySchema(model)) {
|
||||
ArraySchema m = (ArraySchema) model;
|
||||
Schema inner = m.getItems();
|
||||
if (inner instanceof ObjectSchema) {
|
||||
ObjectSchema op = (ObjectSchema) inner;
|
||||
if (op.getProperties() != null && op.getProperties().size() > 0) {
|
||||
String innerModelName = resolveModelName(op.getTitle(), modelName + "_inner");
|
||||
Schema innerModel = modelFromProperty(op, innerModelName);
|
||||
String existing = matchGenerated(innerModel);
|
||||
if (existing == null) {
|
||||
openapi.getComponents().addSchemas(innerModelName, innerModel);
|
||||
addGenerated(innerModelName, innerModel);
|
||||
Schema schema = new Schema().$ref(innerModelName);
|
||||
schema.setRequired(op.getRequired());
|
||||
m.setItems(schema);
|
||||
} else {
|
||||
Schema schema = new Schema().$ref(existing);
|
||||
schema.setRequired(op.getRequired());
|
||||
m.setItems(schema);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten inline models in ApiResponses
|
||||
*
|
||||
* @param openAPI target spec
|
||||
* @param pathname target pathname
|
||||
* @param operation target operation
|
||||
*/
|
||||
private void flattenResponses(OpenAPI openAPI, String pathname, Operation operation) {
|
||||
ApiResponses responses = operation.getResponses();
|
||||
if (responses == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String key : responses.keySet()) {
|
||||
ApiResponse response = responses.get(key);
|
||||
if (ModelUtils.getSchemaFromResponse(response) == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Schema property = ModelUtils.getSchemaFromResponse(response);
|
||||
if (property instanceof ObjectSchema) {
|
||||
ObjectSchema op = (ObjectSchema) property;
|
||||
if (op.getProperties() != null && op.getProperties().size() > 0) {
|
||||
String modelName = resolveModelName(op.getTitle(), "inline_response_" + key);
|
||||
Schema model = modelFromProperty(op, modelName);
|
||||
String existing = matchGenerated(model);
|
||||
Content content = response.getContent();
|
||||
for (MediaType mediaType : content.values()) {
|
||||
if (existing != null) {
|
||||
Schema schema = this.makeSchema(existing, property);
|
||||
schema.setRequired(op.getRequired());
|
||||
mediaType.setSchema(schema);
|
||||
} else {
|
||||
Schema schema = this.makeSchema(modelName, property);
|
||||
schema.setRequired(op.getRequired());
|
||||
mediaType.setSchema(schema);
|
||||
addGenerated(modelName, model);
|
||||
openAPI.getComponents().addSchemas(modelName, model);
|
||||
}
|
||||
}
|
||||
} else if (ModelUtils.isComposedSchema(model)) {
|
||||
ComposedSchema m = (ComposedSchema) model;
|
||||
if (m.getAllOf() != null && !m.getAllOf().isEmpty()) {
|
||||
Schema child = null;
|
||||
for (Schema component : m.getAllOf()) {
|
||||
if (component.get$ref() == null) {
|
||||
child = component;
|
||||
}
|
||||
}
|
||||
} else if (property instanceof ArraySchema) {
|
||||
ArraySchema ap = (ArraySchema) property;
|
||||
Schema inner = ap.getItems();
|
||||
if (inner instanceof ObjectSchema) {
|
||||
ObjectSchema op = (ObjectSchema) inner;
|
||||
if (op.getProperties() != null && op.getProperties().size() > 0) {
|
||||
flattenProperties(op.getProperties(), pathname);
|
||||
String modelName = resolveModelName(op.getTitle(),
|
||||
"inline_response_" + key);
|
||||
Schema innerModel = modelFromProperty(op, modelName);
|
||||
String existing = matchGenerated(innerModel);
|
||||
if (existing != null) {
|
||||
Schema schema = this.makeSchema(existing, op);
|
||||
schema.setRequired(op.getRequired());
|
||||
ap.setItems(schema);
|
||||
} else {
|
||||
Schema schema = this.makeSchema(modelName, op);
|
||||
schema.setRequired(op.getRequired());
|
||||
ap.setItems(schema);
|
||||
addGenerated(modelName, innerModel);
|
||||
openAPI.getComponents().addSchemas(modelName, innerModel);
|
||||
}
|
||||
if (child != null) {
|
||||
Map<String, Schema> properties = child.getProperties();
|
||||
flattenProperties(properties, modelName);
|
||||
}
|
||||
}
|
||||
} else if (property instanceof MapSchema) {
|
||||
MapSchema mp = (MapSchema) property;
|
||||
Schema innerProperty = ModelUtils.getAdditionalProperties(mp);
|
||||
if (innerProperty instanceof ObjectSchema) {
|
||||
ObjectSchema op = (ObjectSchema) innerProperty;
|
||||
if (op.getProperties() != null && op.getProperties().size() > 0) {
|
||||
flattenProperties(op.getProperties(), pathname);
|
||||
String modelName = resolveModelName(op.getTitle(),
|
||||
"inline_response_" + key);
|
||||
Schema innerModel = modelFromProperty(op, modelName);
|
||||
String existing = matchGenerated(innerModel);
|
||||
if (existing != null) {
|
||||
Schema schema = new Schema().$ref(existing);
|
||||
schema.setRequired(op.getRequired());
|
||||
mp.setAdditionalProperties(schema);
|
||||
} else {
|
||||
Schema schema = new Schema().$ref(modelName);
|
||||
schema.setRequired(op.getRequired());
|
||||
mp.setAdditionalProperties(schema);
|
||||
addGenerated(modelName, innerModel);
|
||||
openAPI.getComponents().addSchemas(modelName, innerModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -316,6 +319,65 @@ public class InlineModelResolver {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten inline models in components
|
||||
*
|
||||
* @param openAPI target spec
|
||||
*/
|
||||
private void flattenComponents(OpenAPI openAPI) {
|
||||
Map<String, Schema> models = openAPI.getComponents().getSchemas();
|
||||
if (models == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> modelNames = new ArrayList<String>(models.keySet());
|
||||
for (String modelName : modelNames) {
|
||||
Schema model = models.get(modelName);
|
||||
if (model instanceof Schema) {
|
||||
Schema m = (Schema) model;
|
||||
Map<String, Schema> properties = m.getProperties();
|
||||
flattenProperties(properties, modelName);
|
||||
fixStringModel(m);
|
||||
} else if (ModelUtils.isArraySchema(model)) {
|
||||
ArraySchema m = (ArraySchema) model;
|
||||
Schema inner = m.getItems();
|
||||
if (inner instanceof ObjectSchema) {
|
||||
ObjectSchema op = (ObjectSchema) inner;
|
||||
if (op.getProperties() != null && op.getProperties().size() > 0) {
|
||||
String innerModelName = resolveModelName(op.getTitle(), modelName + "_inner");
|
||||
Schema innerModel = modelFromProperty(op, innerModelName);
|
||||
String existing = matchGenerated(innerModel);
|
||||
if (existing == null) {
|
||||
openAPI.getComponents().addSchemas(innerModelName, innerModel);
|
||||
addGenerated(innerModelName, innerModel);
|
||||
Schema schema = new Schema().$ref(innerModelName);
|
||||
schema.setRequired(op.getRequired());
|
||||
m.setItems(schema);
|
||||
} else {
|
||||
Schema schema = new Schema().$ref(existing);
|
||||
schema.setRequired(op.getRequired());
|
||||
m.setItems(schema);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ModelUtils.isComposedSchema(model)) {
|
||||
ComposedSchema m = (ComposedSchema) model;
|
||||
if (m.getAllOf() != null && !m.getAllOf().isEmpty()) {
|
||||
Schema child = null;
|
||||
for (Schema component : m.getAllOf()) {
|
||||
if (component.get$ref() == null) {
|
||||
child = component;
|
||||
}
|
||||
}
|
||||
if (child != null) {
|
||||
Map<String, Schema> properties = child.getProperties();
|
||||
flattenProperties(properties, modelName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function fix models that are string (mostly enum). Before this fix, the
|
||||
* example would look something like that in the doc: "\"example from def\""
|
||||
@@ -358,6 +420,7 @@ public class InlineModelResolver {
|
||||
}
|
||||
int count = 0;
|
||||
boolean done = false;
|
||||
key = key.replaceAll("/", "_"); // e.g. /me/videos => _me_videos
|
||||
key = key.replaceAll("[^a-z_\\.A-Z0-9 ]", ""); // FIXME: a parameter
|
||||
// should not be assigned. Also declare the methods parameters as 'final'.
|
||||
while (!done) {
|
||||
|
||||
@@ -95,6 +95,7 @@ public class CodegenConfigurator implements Serializable {
|
||||
private boolean verbose;
|
||||
private boolean skipOverwrite;
|
||||
private boolean removeOperationIdPrefix;
|
||||
private boolean logToStderr;
|
||||
private boolean validateSpec;
|
||||
private boolean enablePostProcessFile;
|
||||
private String templateDir;
|
||||
@@ -220,6 +221,24 @@ public class CodegenConfigurator implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean getLogToStderr() {
|
||||
return logToStderr;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setLogToStderr(boolean logToStderrte) {
|
||||
this.logToStderr = logToStderr;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isGenerateAliasAsModel() {
|
||||
return ModelUtils.isGenerateAliasAsModel();
|
||||
}
|
||||
|
||||
public CodegenConfigurator setGenerateAliasAsModel(boolean generateAliasAsModel) {
|
||||
ModelUtils.setGenerateAliasAsModel(generateAliasAsModel);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getModelNameSuffix() {
|
||||
return modelNameSuffix;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,12 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
protected Set<String> collectionTypes;
|
||||
protected Set<String> mapTypes;
|
||||
|
||||
// true if support nullable type
|
||||
protected boolean supportNullable = Boolean.FALSE;
|
||||
|
||||
// nullable type
|
||||
protected Set<String> nullableType = new HashSet<String>();
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractCSharpCodegen.class);
|
||||
|
||||
public AbstractCSharpCodegen() {
|
||||
@@ -130,19 +136,26 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
"String",
|
||||
"string",
|
||||
"bool?",
|
||||
"bool",
|
||||
"double?",
|
||||
"double",
|
||||
"decimal?",
|
||||
"decimal",
|
||||
"int?",
|
||||
"int",
|
||||
"long?",
|
||||
"long",
|
||||
"float?",
|
||||
"float",
|
||||
"byte[]",
|
||||
"ICollection",
|
||||
"Collection",
|
||||
"List",
|
||||
"Dictionary",
|
||||
"DateTime?",
|
||||
"DateTime",
|
||||
"DateTimeOffset?",
|
||||
"String",
|
||||
"DataTimeOffset",
|
||||
"Boolean",
|
||||
"Double",
|
||||
"Int32",
|
||||
@@ -157,6 +170,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
instantiationTypes.put("list", "List");
|
||||
instantiationTypes.put("map", "Dictionary");
|
||||
|
||||
|
||||
// Nullable types here assume C# 2 support is not part of base
|
||||
typeMapping = new HashMap<String, String>();
|
||||
typeMapping.put("string", "string");
|
||||
@@ -176,6 +190,11 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
typeMapping.put("map", "Dictionary");
|
||||
typeMapping.put("object", "Object");
|
||||
typeMapping.put("UUID", "Guid?");
|
||||
|
||||
// nullable type
|
||||
nullableType = new HashSet<String>(
|
||||
Arrays.asList("decimal", "bool", "int", "float", "long", "double", "DateTime", "Guid")
|
||||
);
|
||||
}
|
||||
|
||||
public void setReturnICollection(boolean returnICollection) {
|
||||
@@ -209,8 +228,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
this.useDateTimeOffsetFlag = flag;
|
||||
if (flag) {
|
||||
typeMapping.put("DateTime", "DateTimeOffset?");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
typeMapping.put("DateTime", "DateTime?");
|
||||
}
|
||||
}
|
||||
@@ -421,8 +439,8 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Object> entry : models.entrySet()) {
|
||||
String swaggerName = entry.getKey();
|
||||
CodegenModel model = ModelUtils.getModelByName(swaggerName, models);
|
||||
String openAPIName = entry.getKey();
|
||||
CodegenModel model = ModelUtils.getModelByName(openAPIName, models);
|
||||
if (model != null) {
|
||||
for (CodegenProperty var : model.allVars) {
|
||||
if (enumRefs.containsKey(var.dataType)) {
|
||||
@@ -483,7 +501,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOGGER.warn("Expected to retrieve model %s by name, but no model was found. Check your -Dmodels inclusions.", swaggerName);
|
||||
LOGGER.warn("Expected to retrieve model %s by name, but no model was found. Check your -Dmodels inclusions.", openAPIName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -573,28 +591,30 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
}
|
||||
}
|
||||
|
||||
for (CodegenParameter parameter: operation.allParams) {
|
||||
CodegenModel model = null;
|
||||
for(Object modelHashMap: allModels) {
|
||||
CodegenModel codegenModel = ((HashMap<String, CodegenModel>) modelHashMap).get("model");
|
||||
if (codegenModel.getClassname().equals(parameter.dataType)) {
|
||||
model = codegenModel;
|
||||
break;
|
||||
if (!isSupportNullable()) {
|
||||
for (CodegenParameter parameter : operation.allParams) {
|
||||
CodegenModel model = null;
|
||||
for (Object modelHashMap : allModels) {
|
||||
CodegenModel codegenModel = ((HashMap<String, CodegenModel>) modelHashMap).get("model");
|
||||
if (codegenModel.getClassname().equals(parameter.dataType)) {
|
||||
model = codegenModel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (model == null) {
|
||||
// Primitive data types all come already marked
|
||||
parameter.isNullable = true;
|
||||
} else {
|
||||
// Effectively mark enum models as enums and non-nullable
|
||||
if (model.isEnum) {
|
||||
parameter.isEnum = true;
|
||||
parameter.allowableValues = model.allowableValues;
|
||||
parameter.isPrimitiveType = true;
|
||||
parameter.isNullable = false;
|
||||
} else {
|
||||
if (model == null) {
|
||||
// Primitive data types all come already marked
|
||||
parameter.isNullable = true;
|
||||
} else {
|
||||
// Effectively mark enum models as enums and non-nullable
|
||||
if (model.isEnum) {
|
||||
parameter.isEnum = true;
|
||||
parameter.allowableValues = model.allowableValues;
|
||||
parameter.isPrimitiveType = true;
|
||||
parameter.isNullable = false;
|
||||
} else {
|
||||
parameter.isNullable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -792,6 +812,14 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
return reservedWords.contains(word);
|
||||
}
|
||||
|
||||
public String getNullableType(Schema p, String type) {
|
||||
if (languageSpecificPrimitives.contains(type)) {
|
||||
return type;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSchemaType(Schema p) {
|
||||
String openAPIType = super.getSchemaType(p);
|
||||
@@ -804,8 +832,9 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
|
||||
if (typeMapping.containsKey(openAPIType)) {
|
||||
type = typeMapping.get(openAPIType);
|
||||
if (languageSpecificPrimitives.contains(type)) {
|
||||
return type;
|
||||
String languageType = getNullableType(p, type);
|
||||
if (languageType != null) {
|
||||
return languageType;
|
||||
}
|
||||
} else {
|
||||
type = openAPIType;
|
||||
@@ -950,6 +979,14 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
this.interfacePrefix = interfacePrefix;
|
||||
}
|
||||
|
||||
public boolean isSupportNullable() {
|
||||
return supportNullable;
|
||||
}
|
||||
|
||||
public void setSupportNullable(final boolean supportNullable) {
|
||||
this.supportNullable = supportNullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toEnumValue(String value, String datatype) {
|
||||
// C# only supports enums as literals for int, int?, long, long?, byte, and byte?. All else must be treated as strings.
|
||||
@@ -1011,7 +1048,9 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
@Override
|
||||
public boolean isDataTypeString(String dataType) {
|
||||
// also treat double/decimal/float as "string" in enum so that the values (e.g. 2.8) get double-quoted
|
||||
return "String".equalsIgnoreCase(dataType) || "double?".equals(dataType) || "decimal?".equals(dataType) || "float?".equals(dataType);
|
||||
return "String".equalsIgnoreCase(dataType) ||
|
||||
"double?".equals(dataType) || "decimal?".equals(dataType) || "float?".equals(dataType) ||
|
||||
"double".equals(dataType) || "decimal".equals(dataType) || "float".equals(dataType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -117,6 +117,8 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
|
||||
|
||||
setReservedWordsLowerCase(
|
||||
Arrays.asList(
|
||||
// special words
|
||||
"object",
|
||||
// used as internal variables, can collide with parameter names
|
||||
"localVarPath", "localVarQueryParams", "localVarCollectionQueryParams",
|
||||
"localVarHeaderParams", "localVarFormParams", "localVarPostBody",
|
||||
@@ -1436,4 +1438,13 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
|
||||
public void setParentOverridden(final boolean parentOverridden) {
|
||||
this.parentOverridden = parentOverridden;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) {
|
||||
super.addAdditionPropertiesToCodeGenModel(codegenModel, schema);
|
||||
|
||||
// See https://github.com/OpenAPITools/openapi-generator/pull/1729#issuecomment-449937728
|
||||
codegenModel.additionalPropertiesType = getSchemaType(ModelUtils.getAdditionalProperties(schema));
|
||||
addImport(codegenModel, codegenModel.additionalPropertiesType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -776,7 +776,6 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import static org.apache.commons.lang3.StringUtils.isEmpty;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.samskivert.mustache.Mustache;
|
||||
|
||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
|
||||
import org.openapitools.codegen.CliOption;
|
||||
@@ -32,6 +33,7 @@ import org.openapitools.codegen.CodegenParameter;
|
||||
import org.openapitools.codegen.CodegenProperty;
|
||||
import org.openapitools.codegen.CodegenType;
|
||||
import org.openapitools.codegen.SupportingFile;
|
||||
import org.openapitools.codegen.utils.ModelUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -84,19 +86,39 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
|
||||
// By default, generated code is considered public
|
||||
protected boolean nonPublicApi = Boolean.FALSE;
|
||||
|
||||
|
||||
public CSharpRefactorClientCodegen() {
|
||||
super();
|
||||
|
||||
// mapped non-nullable type without ?
|
||||
typeMapping = new HashMap<String, String>();
|
||||
typeMapping.put("string", "string");
|
||||
typeMapping.put("binary", "byte[]");
|
||||
typeMapping.put("ByteArray", "byte[]");
|
||||
typeMapping.put("boolean", "bool");
|
||||
typeMapping.put("integer", "int");
|
||||
typeMapping.put("float", "float");
|
||||
typeMapping.put("long", "long");
|
||||
typeMapping.put("double", "double");
|
||||
typeMapping.put("number", "decimal");
|
||||
typeMapping.put("DateTime", "DateTime");
|
||||
typeMapping.put("date", "DateTime");
|
||||
typeMapping.put("file", "System.IO.Stream");
|
||||
typeMapping.put("array", "List");
|
||||
typeMapping.put("list", "List");
|
||||
typeMapping.put("map", "Dictionary");
|
||||
typeMapping.put("object", "Object");
|
||||
typeMapping.put("UUID", "Guid");
|
||||
|
||||
setSupportNullable(Boolean.TRUE);
|
||||
hideGenerationTimestamp = Boolean.TRUE;
|
||||
supportsInheritance = true;
|
||||
modelTemplateFiles.put("model.mustache", ".cs");
|
||||
apiTemplateFiles.put("api.mustache", ".cs");
|
||||
|
||||
modelDocTemplateFiles.put("model_doc.mustache", ".md");
|
||||
apiDocTemplateFiles.put("api_doc.mustache", ".md");
|
||||
|
||||
embeddedTemplateDir = templateDir = "csharp-refactor";
|
||||
|
||||
hideGenerationTimestamp = Boolean.TRUE;
|
||||
|
||||
cliOptions.clear();
|
||||
|
||||
// CLI options
|
||||
@@ -223,7 +245,6 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
|
||||
setModelPropertyNaming((String) additionalProperties.get(CodegenConstants.MODEL_PROPERTY_NAMING));
|
||||
}
|
||||
|
||||
|
||||
if (isEmpty(apiPackage)) {
|
||||
setApiPackage("Api");
|
||||
}
|
||||
@@ -609,6 +630,10 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
|
||||
public void postProcessParameter(CodegenParameter parameter) {
|
||||
postProcessPattern(parameter.pattern, parameter.vendorExtensions);
|
||||
super.postProcessParameter(parameter);
|
||||
|
||||
if (!parameter.required && nullableType.contains(parameter.dataType)) { //optional
|
||||
parameter.dataType = parameter.dataType + "?";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -852,4 +877,17 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
|
||||
// To avoid unexpected behaviors when options are passed programmatically such as { "supportsAsync": "" }
|
||||
return super.processCompiler(compiler).emptyStringIsFalse(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullableType(Schema p, String type) {
|
||||
if (languageSpecificPrimitives.contains(type)) {
|
||||
if (isSupportNullable() && ModelUtils.isNullable(p) && nullableType.contains(type)) {
|
||||
return type + "?";
|
||||
} else {
|
||||
return type;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
protected String modelDocPath = "docs/";
|
||||
protected String apiTestPath = "api/";
|
||||
protected String modelTestPath = "model/";
|
||||
protected boolean useES6 = false; // default is ES5
|
||||
protected boolean useES6 = true; // default is ES5
|
||||
private String modelPropertyNaming = "camelCase";
|
||||
|
||||
public JavascriptClientCodegen() {
|
||||
@@ -207,8 +207,8 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC)
|
||||
.defaultValue(Boolean.TRUE.toString()));
|
||||
cliOptions.add(new CliOption(USE_ES6,
|
||||
"use JavaScript ES6 (ECMAScript 6) (beta). Default is ES5.")
|
||||
.defaultValue(Boolean.FALSE.toString()));
|
||||
"use JavaScript ES6 (ECMAScript 6) (beta). Default is ES6.")
|
||||
.defaultValue(Boolean.TRUE.toString()));
|
||||
cliOptions.add(new CliOption(CodegenConstants.MODEL_PROPERTY_NAMING, CodegenConstants.MODEL_PROPERTY_NAMING_DESC).defaultValue("camelCase"));
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,10 @@ import org.openapitools.codegen.CodegenConstants;
|
||||
import org.openapitools.codegen.CodegenOperation;
|
||||
import org.openapitools.codegen.CodegenType;
|
||||
import org.openapitools.codegen.SupportingFile;
|
||||
import org.openapitools.codegen.CodegenSecurity;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
@@ -46,6 +48,8 @@ public class PhpSlimServerCodegen extends AbstractPhpCodegen {
|
||||
|
||||
protected String groupId = "org.openapitools";
|
||||
protected String artifactId = "openapi-server";
|
||||
protected String authDirName = "Auth";
|
||||
protected String authPackage = "";
|
||||
|
||||
public PhpSlimServerCodegen() {
|
||||
super();
|
||||
@@ -59,6 +63,7 @@ public class PhpSlimServerCodegen extends AbstractPhpCodegen {
|
||||
setInvokerPackage("OpenAPIServer");
|
||||
apiPackage = invokerPackage + "\\" + apiDirName;
|
||||
modelPackage = invokerPackage + "\\" + modelDirName;
|
||||
authPackage = invokerPackage + "\\" + authDirName;
|
||||
outputFolder = "generated-code" + File.separator + "slim";
|
||||
|
||||
modelTestTemplateFiles.put("model_test.mustache", ".php");
|
||||
@@ -118,6 +123,15 @@ public class PhpSlimServerCodegen extends AbstractPhpCodegen {
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
|
||||
// Update the invokerPackage for the default authPackage
|
||||
authPackage = invokerPackage + "\\" + authDirName;
|
||||
}
|
||||
|
||||
// make auth src path available in mustache template
|
||||
additionalProperties.put("authPackage", authPackage);
|
||||
additionalProperties.put("authSrcPath", "./" + toSrcPath(authPackage, srcBasePath));
|
||||
|
||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||
supportingFiles.add(new SupportingFile("composer.mustache", "", "composer.json"));
|
||||
supportingFiles.add(new SupportingFile("index.mustache", "", "index.php"));
|
||||
@@ -158,6 +172,15 @@ public class PhpSlimServerCodegen extends AbstractPhpCodegen {
|
||||
return objs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CodegenSecurity> fromSecurity(Map<String, SecurityScheme> securitySchemeMap) {
|
||||
List<CodegenSecurity> codegenSecurities = super.fromSecurity(securitySchemeMap);
|
||||
if (Boolean.FALSE.equals(codegenSecurities.isEmpty())) {
|
||||
supportingFiles.add(new SupportingFile("abstract_authenticator.mustache", toSrcPath(authPackage, srcBasePath), toAbstractName("Authenticator") + ".php"));
|
||||
}
|
||||
return codegenSecurities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiName(String name) {
|
||||
if (name.length() == 0) {
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.openapitools.codegen.CodegenType;
|
||||
import org.openapitools.codegen.DefaultCodegen;
|
||||
import org.openapitools.codegen.SupportingFile;
|
||||
import org.openapitools.codegen.utils.ModelUtils;
|
||||
import org.openapitools.codegen.utils.ProcessUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -425,6 +426,16 @@ public class PowerShellClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return objs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||
List<Object> models = (List<Object>) objs.get("models");
|
||||
// add x-index to properties
|
||||
ProcessUtils.addIndexToProperties(models);
|
||||
return objs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -619,7 +619,15 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
public String toDefaultValue(Schema p) {
|
||||
if (ModelUtils.isBooleanSchema(p)) {
|
||||
if (p.getDefault() != null) {
|
||||
if (p.getDefault().toString().equalsIgnoreCase("false"))
|
||||
if (Boolean.valueOf(p.getDefault().toString()) == false)
|
||||
return "False";
|
||||
else
|
||||
return "True";
|
||||
}
|
||||
// include fallback to example, default defined as server only
|
||||
// example is not defined as server only
|
||||
if (p.getExample() != null) {
|
||||
if (Boolean.valueOf(p.getExample().toString()) == false)
|
||||
return "False";
|
||||
else
|
||||
return "True";
|
||||
@@ -632,10 +640,24 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
if (p.getDefault() != null) {
|
||||
return p.getDefault().toString();
|
||||
}
|
||||
// default numbers are not yet returned by v2 spec openAPI results
|
||||
// https://github.com/swagger-api/swagger-parser/issues/971
|
||||
// include fallback to example, default defined as server only
|
||||
// example is not defined as server only
|
||||
if (p.getExample() != null) {
|
||||
return p.getExample().toString();
|
||||
}
|
||||
} else if (ModelUtils.isIntegerSchema(p)) {
|
||||
if (p.getDefault() != null) {
|
||||
return p.getDefault().toString();
|
||||
}
|
||||
// default integers are not yet returned by v2 spec openAPI results
|
||||
// https://github.com/swagger-api/swagger-parser/issues/971
|
||||
// include fallback to example, default defined as server only
|
||||
// example is not defined as server only
|
||||
if (p.getExample() != null) {
|
||||
return p.getExample().toString();
|
||||
}
|
||||
} else if (ModelUtils.isStringSchema(p)) {
|
||||
if (p.getDefault() != null) {
|
||||
if (Pattern.compile("\r\n|\r|\n").matcher((String) p.getDefault()).find())
|
||||
@@ -643,6 +665,23 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
else
|
||||
return "'" + p.getDefault() + "'";
|
||||
}
|
||||
// include fallback to example, default defined as server only
|
||||
// example is not defined as server only
|
||||
if (p.getExample() != null) {
|
||||
if (Pattern.compile("\r\n|\r|\n").matcher((String) p.getExample()).find())
|
||||
return "'''" + p.getExample() + "'''";
|
||||
else
|
||||
return "'" + p.getExample() + "'";
|
||||
}
|
||||
} else if (ModelUtils.isArraySchema(p)) {
|
||||
if (p.getDefault() != null) {
|
||||
return p.getDefault().toString();
|
||||
}
|
||||
// include fallback to example, default defined as server only
|
||||
// example is not defined as server only
|
||||
if (p.getExample() != null) {
|
||||
return p.getExample().toString();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -61,6 +61,16 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class ModelUtils {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ModelUtils.class);
|
||||
private static boolean generateAliasAsModel = false;
|
||||
|
||||
public static void setGenerateAliasAsModel(boolean value) {
|
||||
generateAliasAsModel = value;
|
||||
}
|
||||
|
||||
public static boolean isGenerateAliasAsModel() {
|
||||
return generateAliasAsModel;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Searches for the model by name in the map of models and returns it
|
||||
@@ -769,15 +779,23 @@ public class ModelUtils {
|
||||
// top-level enum class
|
||||
return schema;
|
||||
} else if (isArraySchema(ref)) {
|
||||
return unaliasSchema(allSchemas, allSchemas.get(ModelUtils.getSimpleRef(schema.get$ref())));
|
||||
if (generateAliasAsModel) {
|
||||
return schema; // generate a model extending array
|
||||
} else {
|
||||
return unaliasSchema(allSchemas, allSchemas.get(ModelUtils.getSimpleRef(schema.get$ref())));
|
||||
}
|
||||
} else if (isComposedSchema(ref)) {
|
||||
return schema;
|
||||
} else if (isMapSchema(ref)) {
|
||||
if (ref.getProperties() != null && !ref.getProperties().isEmpty()) // has at least one property
|
||||
return schema; // treat it as model
|
||||
else {
|
||||
// treat it as a typical map
|
||||
return unaliasSchema(allSchemas, allSchemas.get(ModelUtils.getSimpleRef(schema.get$ref())));
|
||||
if (generateAliasAsModel) {
|
||||
return schema; // generate a model extending map
|
||||
} else {
|
||||
// treat it as a typical map
|
||||
return unaliasSchema(allSchemas, allSchemas.get(ModelUtils.getSimpleRef(schema.get$ref())));
|
||||
}
|
||||
}
|
||||
} else if (isObjectSchema(ref)) { // model
|
||||
if (ref.getProperties() != null && !ref.getProperties().isEmpty()) { // has at least one property
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.openapitools.codegen.utils;
|
||||
|
||||
import org.openapitools.codegen.CodegenModel;
|
||||
import org.openapitools.codegen.CodegenProperty;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ProcessUtils {
|
||||
|
||||
/**
|
||||
* Add x-index extension to the model's properties
|
||||
*
|
||||
* @param models List of models
|
||||
*/
|
||||
public static void addIndexToProperties(List<Object> models) {
|
||||
for (Object _mo : models) {
|
||||
Map<String, Object> mo = (Map<String, Object>) _mo;
|
||||
CodegenModel cm = (CodegenModel) mo.get("model");
|
||||
|
||||
int i = 0;
|
||||
for (CodegenProperty var : cm.vars) {
|
||||
var.vendorExtensions.put("x-index", i);
|
||||
i++;
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
for (CodegenProperty var : cm.allVars) {
|
||||
var.vendorExtensions.put("x-index", j);
|
||||
j++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -310,7 +310,9 @@
|
||||
{{/returnContainer}}
|
||||
//return type
|
||||
{{/returnTypeIsPrimitive}}
|
||||
apiClient_free(apiClient);
|
||||
if (apiClient->dataReceived) {
|
||||
free(apiClient->dataReceived);
|
||||
}
|
||||
{{#hasQueryParams}}list_free(localVarQueryParameters);{{/hasQueryParams}}
|
||||
{{#hasHeaderParams}}list_free(localVarHeaderParameters);{{/hasHeaderParams}}
|
||||
{{#hasFormParams}}list_free(localVarFormParameters);{{/hasFormParams}}
|
||||
@@ -380,7 +382,10 @@ end:
|
||||
{{/returnType}}
|
||||
{{^returnType}}
|
||||
//No return type
|
||||
end: apiClient_free(apiClient);
|
||||
end:
|
||||
if (apiClient->dataReceived) {
|
||||
free(apiClient->dataReceived);
|
||||
}
|
||||
{{#hasQueryParams}}list_free(localVarQueryParameters);{{/hasQueryParams}}
|
||||
{{#hasHeaderParams}}list_free(localVarHeaderParameters);{{/hasHeaderParams}}
|
||||
{{#hasFormParams}}list_free(localVarFormParameters);{{/hasFormParams}}
|
||||
|
||||
@@ -12,20 +12,48 @@ apiClient_t *apiClient_create() {
|
||||
apiClient->basePath = "{{{basePath}}}";
|
||||
apiClient->dataReceived = NULL;
|
||||
apiClient->response_code = 0;
|
||||
#ifdef BASIC_AUTH
|
||||
{{#hasAuthMethods}}
|
||||
{{#authMethods}}
|
||||
{{#isBasic}}
|
||||
apiClient->username = NULL;
|
||||
apiClient->password = NULL;
|
||||
#endif // BASIC_AUTH
|
||||
#ifdef OAUTH2
|
||||
{{/isBasic}}
|
||||
{{#isOAuth}}
|
||||
apiClient->accessToken = NULL;
|
||||
#endif // OAUTH2
|
||||
{{/isOAuth}}
|
||||
{{#isApiKey}}
|
||||
apiClient->apiKeys = NULL;
|
||||
{{/isApiKey}}
|
||||
{{/authMethods}}
|
||||
{{/hasAuthMethods}}
|
||||
|
||||
return apiClient;
|
||||
}
|
||||
|
||||
void apiClient_free(apiClient_t *apiClient) {
|
||||
if(apiClient->dataReceived) {
|
||||
free(apiClient->dataReceived);
|
||||
if(apiClient->basePath) {
|
||||
free(apiClient->basePath);
|
||||
}
|
||||
{{#hasAuthMethods}}
|
||||
{{#authMethods}}
|
||||
{{#isBasic}}
|
||||
if(apiClient->username) {
|
||||
free(apiClient->username);
|
||||
}
|
||||
if(apiClient->password) {
|
||||
free(apiClient->password);
|
||||
}
|
||||
{{/isBasic}}
|
||||
{{#isOAuth}}
|
||||
if(apiClient->accessToken) {
|
||||
free(apiClient->accessToken);
|
||||
}
|
||||
{{/isOAuth}}
|
||||
{{#isApiKey}}
|
||||
list_free(apiClient->apiKeys);
|
||||
{{/isApiKey}}
|
||||
{{/authMethods}}
|
||||
{{/hasAuthMethods}}
|
||||
free(apiClient);
|
||||
curl_global_cleanup();
|
||||
}
|
||||
@@ -254,11 +282,9 @@ void apiClient_invoke(apiClient_t *apiClient,
|
||||
if(strcmp(keyValuePair->key,
|
||||
"file") == 0)
|
||||
{
|
||||
printf("Size of fileVar - %p\n",fileVar);
|
||||
memcpy(&fileVar,
|
||||
keyValuePair->value,
|
||||
sizeof(fileVar));
|
||||
printf("Size of fileVar1 - %p\n",fileVar);
|
||||
curl_mime_data(part,
|
||||
fileVar->fileData,
|
||||
fileVar->fileSize);
|
||||
@@ -287,8 +313,12 @@ void apiClient_invoke(apiClient_t *apiClient,
|
||||
free(headerValueToWrite);
|
||||
}
|
||||
}
|
||||
{{#hasAuthMethods}}
|
||||
{{#authMethods}}
|
||||
{{#isApiKey}}
|
||||
// this would only be generated for apiKey authentication
|
||||
#ifdef API_KEY
|
||||
if (apiClient->apiKeys != NULL)
|
||||
{
|
||||
list_ForEach(listEntry, apiClient->apiKeys) {
|
||||
keyValuePair_t *apiKey = listEntry->data;
|
||||
if((apiKey->key != NULL) &&
|
||||
@@ -300,7 +330,10 @@ void apiClient_invoke(apiClient_t *apiClient,
|
||||
free(headerValueToWrite);
|
||||
}
|
||||
}
|
||||
#endif // API_KEY
|
||||
}
|
||||
{{/isApiKey}}
|
||||
{{/authMethods}}
|
||||
{{/hasAuthMethods}}
|
||||
|
||||
char *targetUrl =
|
||||
assembleTargetUrl(apiClient->basePath,
|
||||
@@ -316,19 +349,11 @@ void apiClient_invoke(apiClient_t *apiClient,
|
||||
&apiClient->dataReceived);
|
||||
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
|
||||
curl_easy_setopt(handle, CURLOPT_VERBOSE, 0); // to get curl debug msg 0: to disable, 1L:to enable
|
||||
// this would only be generated for OAuth2 authentication
|
||||
#ifdef OAUTH2
|
||||
if(apiClient->accessToken != NULL) {
|
||||
// curl_easy_setopt(handle, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);
|
||||
curl_easy_setopt(handle,
|
||||
CURLOPT_XOAUTH2_BEARER,
|
||||
apiClient->accessToken);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
{{#hasAuthMethods}}
|
||||
{{#authMethods}}
|
||||
{{#isBasic}}
|
||||
// this would only be generated for basic authentication:
|
||||
#ifdef BASIC_AUTH
|
||||
char *authenticationToken;
|
||||
|
||||
if((apiClient->username != NULL) &&
|
||||
@@ -351,8 +376,18 @@ void apiClient_invoke(apiClient_t *apiClient,
|
||||
CURLOPT_USERPWD,
|
||||
authenticationToken);
|
||||
}
|
||||
|
||||
#endif // BASIC_AUTH
|
||||
{{/isBasic}}
|
||||
{{#isOAuth}}
|
||||
// this would only be generated for OAuth2 authentication
|
||||
if(apiClient->accessToken != NULL) {
|
||||
// curl_easy_setopt(handle, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);
|
||||
curl_easy_setopt(handle,
|
||||
CURLOPT_XOAUTH2_BEARER,
|
||||
apiClient->accessToken);
|
||||
}
|
||||
{{/isOAuth}}
|
||||
{{/authMethods}}
|
||||
{{/hasAuthMethods}}
|
||||
|
||||
if(bodyParameters != NULL) {
|
||||
postData(handle, bodyParameters);
|
||||
@@ -371,16 +406,27 @@ void apiClient_invoke(apiClient_t *apiClient,
|
||||
if(res == CURLE_OK) {
|
||||
curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &apiClient->response_code);
|
||||
} else {
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
char *url,*ip,*scheme;
|
||||
long port;
|
||||
curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &url);
|
||||
curl_easy_getinfo(handle, CURLINFO_PRIMARY_IP, &ip);
|
||||
curl_easy_getinfo(handle, CURLINFO_PRIMARY_PORT, &port);
|
||||
curl_easy_getinfo(handle, CURLINFO_SCHEME, &scheme);
|
||||
fprintf(stderr, "curl_easy_perform() failed\n\nURL: %s\nIP: %s\nPORT: %li\nSCHEME: %s\nStrERROR: %s\n",url,ip,port,scheme,
|
||||
curl_easy_strerror(res));
|
||||
}
|
||||
#ifdef BASIC_AUTH
|
||||
{{#hasAuthMethods}}
|
||||
{{#authMethods}}
|
||||
{{#isBasic}}
|
||||
if((apiClient->username != NULL) &&
|
||||
(apiClient->password != NULL) )
|
||||
{
|
||||
free(authenticationToken);
|
||||
}
|
||||
#endif // BASIC_AUTH
|
||||
{{/isBasic}}
|
||||
{{/authMethods}}
|
||||
{{/hasAuthMethods}}
|
||||
|
||||
curl_easy_cleanup(handle);
|
||||
if(formParameters != NULL) {
|
||||
free(formString);
|
||||
|
||||
@@ -12,19 +12,20 @@ typedef struct apiClient_t {
|
||||
char *basePath;
|
||||
void *dataReceived;
|
||||
long response_code;
|
||||
// this would only be generated for basic authentication
|
||||
#ifdef BASIC_AUTH
|
||||
{{#hasAuthMethods}}
|
||||
{{#authMethods}}
|
||||
{{#isBasic}}
|
||||
char *username;
|
||||
char *password;
|
||||
#endif // BASIC_AUTH
|
||||
// this would only be generated for OAUTH2 authentication
|
||||
#ifdef OAUTH2
|
||||
{{/isBasic}}
|
||||
{{#isOAuth}}
|
||||
char *accessToken;
|
||||
#endif // OAUTH2
|
||||
#ifdef API_KEY
|
||||
//this would only be generated for apiKey authentication
|
||||
{{/isOAuth}}
|
||||
{{#isApiKey}}
|
||||
list_t *apiKeys;
|
||||
#endif // API_KEY
|
||||
{{/isApiKey}}
|
||||
{{/authMethods}}
|
||||
{{/hasAuthMethods}}
|
||||
} apiClient_t;
|
||||
|
||||
typedef struct FileStruct
|
||||
|
||||
@@ -121,7 +121,7 @@ if(hasProperty('target') && target == 'android') {
|
||||
ext {
|
||||
swagger_annotations_version = "1.5.21"
|
||||
jackson_version = "2.8.11"
|
||||
jackson_databind_version = "2.8.11.2"
|
||||
jackson_databind_version = "2.8.11.3"
|
||||
{{#threetenbp}}
|
||||
threepane_version = "2.6.4"
|
||||
{{/threetenbp}}
|
||||
|
||||
@@ -16,7 +16,7 @@ lazy val root = (project in file(".")).
|
||||
"io.github.openfeign.form" % "feign-form" % "2.1.0" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-core" % "2.8.11" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.8.11" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.11.2" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.11.3" % "compile",
|
||||
"com.fasterxml.jackson.datatype" % "jackson-datatype-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}}" % "2.8.7" % "compile",
|
||||
"com.github.joschi.jackson" % "jackson-datatype-threetenbp" % "2.6.4" % "compile",
|
||||
"org.apache.oltu.oauth2" % "org.apache.oltu.oauth2.client" % "1.0.1" % "compile",
|
||||
|
||||
@@ -303,7 +303,7 @@
|
||||
<feign-version>{{#useFeign10}}10.0.1{{/useFeign10}}{{^useFeign10}}9.4.0{{/useFeign10}}</feign-version>
|
||||
<feign-form-version>2.1.0</feign-form-version>
|
||||
<jackson-version>2.8.11</jackson-version>
|
||||
<jackson-databind-version>2.8.11.2</jackson-databind-version>
|
||||
<jackson-databind-version>2.8.11.3</jackson-databind-version>
|
||||
{{#threetenbp}}
|
||||
<jackson-threetenbp-version>2.6.4</jackson-threetenbp-version>
|
||||
{{/threetenbp}}
|
||||
|
||||
@@ -121,7 +121,7 @@ if(hasProperty('target') && target == 'android') {
|
||||
ext {
|
||||
swagger_annotations_version = "1.5.21"
|
||||
jackson_version = "2.8.11"
|
||||
jackson_databind_version = "2.8.11.2"
|
||||
jackson_databind_version = "2.8.11.3"
|
||||
google_api_client_version = "1.23.0"
|
||||
jersey_common_version = "2.25.1"
|
||||
jodatime_version = "2.9.9"
|
||||
|
||||
@@ -14,7 +14,7 @@ lazy val root = (project in file(".")).
|
||||
"org.glassfish.jersey.core" % "jersey-common" % "2.25.1",
|
||||
"com.fasterxml.jackson.core" % "jackson-core" % "2.8.11" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.8.11" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.11.2" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.11.3" % "compile",
|
||||
{{#withXml}}
|
||||
"com.fasterxml.jackson.dataformat" % "jackson-dataformat-xml" % "2.8.9" % "compile",
|
||||
{{/withXml}}
|
||||
|
||||
@@ -296,7 +296,7 @@
|
||||
<google-api-client-version>1.23.0</google-api-client-version>
|
||||
<jersey-common-version>2.25.1</jersey-common-version>
|
||||
<jackson-version>2.8.11</jackson-version>
|
||||
<jackson-databind-version>2.8.11.2</jackson-databind-version>
|
||||
<jackson-databind-version>2.8.11.3</jackson-databind-version>
|
||||
{{#joda}}
|
||||
<jodatime-version>2.9.9</jodatime-version>
|
||||
{{/joda}}
|
||||
|
||||
@@ -120,7 +120,7 @@ if(hasProperty('target') && target == 'android') {
|
||||
ext {
|
||||
swagger_annotations_version = "1.5.21"
|
||||
jackson_version = "2.8.11"
|
||||
jackson_databind_version = "2.8.11.2"
|
||||
jackson_databind_version = "2.8.11.3"
|
||||
{{#supportJava6}}
|
||||
jersey_version = "2.6"
|
||||
commons_io_version=2.5
|
||||
|
||||
@@ -15,7 +15,7 @@ lazy val root = (project in file(".")).
|
||||
"org.glassfish.jersey.media" % "jersey-media-json-jackson" % {{#supportJava6}}"2.6"{{/supportJava6}}{{^supportJava6}}"2.25.1"{{/supportJava6}},
|
||||
"com.fasterxml.jackson.core" % "jackson-core" % "2.8.11" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.8.11" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.11.2" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.11.3" % "compile",
|
||||
{{#joda}}
|
||||
"com.fasterxml.jackson.datatype" % "jackson-datatype-joda" % "2.8.9" % "compile",
|
||||
{{/joda}}
|
||||
|
||||
@@ -333,7 +333,7 @@
|
||||
<commons_lang3_version>3.6</commons_lang3_version>
|
||||
{{/supportJava6}}
|
||||
<jackson-version>2.8.11</jackson-version>
|
||||
<jackson-databind-version>2.8.11.2</jackson-databind-version>
|
||||
<jackson-databind-version>2.8.11.3</jackson-databind-version>
|
||||
{{#threetenbp}}
|
||||
<threetenbp-version>2.6.4</threetenbp-version>
|
||||
{{/threetenbp}}
|
||||
|
||||
@@ -18,9 +18,10 @@ import org.threeten.bp.LocalDate;
|
||||
import org.threeten.bp.OffsetDateTime;
|
||||
import org.threeten.bp.format.DateTimeFormatter;
|
||||
{{/threetenbp}}
|
||||
|
||||
{{#hasOAuthMethods}}
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import org.apache.oltu.oauth2.common.message.types.GrantType;
|
||||
{{/hasOAuthMethods}}
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.File;
|
||||
@@ -92,7 +93,10 @@ public class ApiClient {
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
{{#authMethods}}{{#isOAuth}}
|
||||
|
||||
{{#hasOAuthMethods}}
|
||||
{{#oauthMethods}}
|
||||
{{#-first}}
|
||||
/*
|
||||
* Constructor for ApiClient to support access token retry on 401/403 configured with client ID
|
||||
*/
|
||||
@@ -123,7 +127,10 @@ public class ApiClient {
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
{{/isOAuth}}{{/authMethods}}
|
||||
|
||||
{{/-first}}
|
||||
{{/oauthMethods}}
|
||||
{{/hasOAuthMethods}}
|
||||
private void init() {
|
||||
httpClient = new OkHttpClient();
|
||||
|
||||
|
||||
@@ -119,12 +119,14 @@ if(hasProperty('target') && target == 'android') {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'io.swagger:swagger-annotations:1.5.17'
|
||||
compile 'io.swagger:swagger-annotations:1.5.21'
|
||||
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 'com.google.code.gson:gson:2.8.5'
|
||||
compile 'io.gsonfire:gson-fire:1.8.0'
|
||||
{{#hasOAuthMethods}}
|
||||
compile group: 'org.apache.oltu.oauth2', name: 'org.apache.oltu.oauth2.client', version: '1.0.1'
|
||||
{{/hasOAuthMethods}}
|
||||
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.8.1'
|
||||
{{#joda}}
|
||||
compile 'joda-time:joda-time:2.9.9'
|
||||
|
||||
@@ -9,11 +9,14 @@ lazy val root = (project in file(".")).
|
||||
publishArtifact in (Compile, packageDoc) := false,
|
||||
resolvers += Resolver.mavenLocal,
|
||||
libraryDependencies ++= Seq(
|
||||
"io.swagger" % "swagger-annotations" % "1.5.17",
|
||||
"io.swagger" % "swagger-annotations" % "1.5.21",
|
||||
"com.squareup.okhttp" % "okhttp" % "2.7.5",
|
||||
"com.squareup.okhttp" % "logging-interceptor" % "2.7.5",
|
||||
"com.google.code.gson" % "gson" % "2.8.1",
|
||||
"com.google.code.gson" % "gson" % "2.8.5",
|
||||
"org.apache.commons" % "commons-lang3" % "3.8.1",
|
||||
{{#hasOAuthMethods}}
|
||||
"org.apache.oltu.oauth2" % "org.apache.oltu.oauth2.client" % "1.0.1",
|
||||
{{/hasOAuthMethods}}
|
||||
{{#joda}}
|
||||
"joda-time" % "joda-time" % "2.9.9" % "compile",
|
||||
{{/joda}}
|
||||
|
||||
@@ -220,11 +220,13 @@
|
||||
<artifactId>gson-fire</artifactId>
|
||||
<version>${gson-fire-version}</version>
|
||||
</dependency>
|
||||
{{#hasOAuthMethods}}
|
||||
<dependency>
|
||||
<groupId>org.apache.oltu.oauth2</groupId>
|
||||
<artifactId>org.apache.oltu.oauth2.client</artifactId>
|
||||
<version>1.0.1</version>
|
||||
</dependency>
|
||||
{{/hasOAuthMethods}}
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
@@ -288,9 +290,9 @@
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<gson-fire-version>1.8.0</gson-fire-version>
|
||||
<swagger-core-version>1.5.18</swagger-core-version>
|
||||
<swagger-core-version>1.5.21</swagger-core-version>
|
||||
<okhttp-version>2.7.5</okhttp-version>
|
||||
<gson-version>2.8.1</gson-version>
|
||||
<gson-version>2.8.5</gson-version>
|
||||
<commons-lang3-version>3.8.1</commons-lang3-version>
|
||||
{{#joda}}
|
||||
<jodatime-version>2.9.9</jodatime-version>
|
||||
|
||||
@@ -120,7 +120,7 @@ if(hasProperty('target') && target == 'android') {
|
||||
ext {
|
||||
swagger_annotations_version = "1.5.21"
|
||||
jackson_version = "2.8.11"
|
||||
jackson_databind_version = "2.8.11.2"
|
||||
jackson_databind_version = "2.8.11.3"
|
||||
threetenbp_version = "2.6.4"
|
||||
resteasy_version = "3.1.3.Final"
|
||||
{{^java8}}
|
||||
|
||||
@@ -15,7 +15,7 @@ lazy val root = (project in file(".")).
|
||||
"org.jboss.resteasy" % "resteasy-jackson2-provider" % "3.1.3.Final" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-core" % "2.8.11" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.8.11" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.11.2" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.11.3" % "compile",
|
||||
"com.github.joschi.jackson" % "jackson-datatype-threetenbp" % "2.6.4" % "compile",
|
||||
{{#java8}}
|
||||
"com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % "2.8.6" % "compile",
|
||||
|
||||
@@ -267,7 +267,7 @@
|
||||
<swagger-annotations-version>1.5.21</swagger-annotations-version>
|
||||
<resteasy-version>3.1.3.Final</resteasy-version>
|
||||
<jackson-version>2.8.11</jackson-version>
|
||||
<jackson-databind-version>2.8.11</jackson-databind-version>
|
||||
<jackson-databind-version>2.8.11.3</jackson-databind-version>
|
||||
<threetenbp-version>2.6.4</threetenbp-version>
|
||||
{{^java8}}
|
||||
<jodatime-version>2.9.9</jodatime-version>
|
||||
|
||||
@@ -121,7 +121,7 @@ if(hasProperty('target') && target == 'android') {
|
||||
ext {
|
||||
swagger_annotations_version = "1.5.21"
|
||||
jackson_version = "2.8.11"
|
||||
jackson_databind_version = "2.8.11.2"
|
||||
jackson_databind_version = "2.8.11.3"
|
||||
spring_web_version = "4.3.9.RELEASE"
|
||||
jodatime_version = "2.9.9"
|
||||
junit_version = "4.12"
|
||||
|
||||
@@ -298,7 +298,7 @@
|
||||
<swagger-annotations-version>1.5.21</swagger-annotations-version>
|
||||
<spring-web-version>4.3.9.RELEASE</spring-web-version>
|
||||
<jackson-version>2.8.11</jackson-version>
|
||||
<jackson-databind-version>2.8.11.2</jackson-databind-version>
|
||||
<jackson-databind-version>2.8.11.3</jackson-databind-version>
|
||||
{{#joda}}
|
||||
<jodatime-version>2.9.9</jodatime-version>
|
||||
{{/joda}}
|
||||
|
||||
@@ -132,7 +132,7 @@ ext {
|
||||
{{/play25}}
|
||||
{{#play26}}
|
||||
jackson_version = "2.8.11"
|
||||
jackson_databind_version = "2.8.11"
|
||||
jackson_databind_version = "2.8.11.3"
|
||||
play_version = "2.6.7"
|
||||
{{/play26}}
|
||||
{{/usePlayWS}}
|
||||
@@ -187,6 +187,7 @@ dependencies {
|
||||
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.core:jackson-databind:$jackson_databind_version"
|
||||
compile "com.fasterxml.jackson.datatype:jackson-datatype-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}}:$jackson_version"
|
||||
{{/usePlayWS}}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ lazy val root = (project in file(".")).
|
||||
"javax.validation" % "validation-api" % "1.1.0.Final" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-core" % "2.8.11" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.8.11" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.11.2" % "compile",
|
||||
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.11.3" % "compile",
|
||||
{{/play26}}
|
||||
"com.squareup.retrofit2" % "converter-jackson" % "2.3.0" % "compile",
|
||||
{{/usePlayWS}}
|
||||
|
||||
@@ -287,7 +287,7 @@
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson-version}</version>
|
||||
<version>${jackson-databind-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
@@ -354,6 +354,7 @@
|
||||
<gson-fire-version>1.8.0</gson-fire-version>
|
||||
<swagger-annotations-version>1.5.21</swagger-annotations-version>
|
||||
{{#usePlayWS}}
|
||||
<jackson-databind-version>2.8.11.3</jackson-databind-version>
|
||||
{{#play24}}
|
||||
<jackson-version>2.6.6</jackson-version>
|
||||
<play-version>2.4.11</play-version>
|
||||
|
||||
@@ -2,6 +2,7 @@ package {{invokerPackage}};
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
@@ -88,16 +89,21 @@ public class ApiClient {
|
||||
|
||||
public ApiClient() {
|
||||
this.dateFormat = createDefaultDateFormat();
|
||||
this.webClient = buildWebClient(new ObjectMapper(), dateFormat);
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.setDateFormat(dateFormat);
|
||||
mapper.registerModule(new JavaTimeModule());
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
|
||||
this.webClient = buildWebClient(mapper);
|
||||
this.init();
|
||||
}
|
||||
|
||||
public ApiClient(ObjectMapper mapper, DateFormat format) {
|
||||
this(buildWebClient(mapper.copy(), format), format);
|
||||
this(buildWebClient(mapper.copy()), format);
|
||||
}
|
||||
|
||||
public ApiClient(WebClient webClient, ObjectMapper mapper, DateFormat format) {
|
||||
this(Optional.ofNullable(webClient).orElseGet(() ->buildWebClient(mapper.copy(), format)), format);
|
||||
this(Optional.ofNullable(webClient).orElseGet(() ->buildWebClient(mapper.copy())), format);
|
||||
}
|
||||
|
||||
private ApiClient(WebClient webClient, DateFormat format) {
|
||||
@@ -126,9 +132,7 @@ public class ApiClient {
|
||||
* Build the RestTemplate used to make HTTP requests.
|
||||
* @return RestTemplate
|
||||
*/
|
||||
public static WebClient buildWebClient(ObjectMapper mapper, DateFormat dateFormat) {
|
||||
mapper.setDateFormat(dateFormat);
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
public static WebClient buildWebClient(ObjectMapper mapper) {
|
||||
ExchangeStrategies strategies = ExchangeStrategies
|
||||
.builder()
|
||||
.codecs(clientDefaultCodecsConfigurer -> {
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
<swagger-annotations-version>1.5.20</swagger-annotations-version>
|
||||
<spring-web-version>5.0.7.RELEASE</spring-web-version>
|
||||
<jackson-version>2.8.11</jackson-version>
|
||||
<jackson-databind-version>2.8.11.2</jackson-databind-version>
|
||||
<jackson-databind-version>2.8.11.3</jackson-databind-version>
|
||||
<junit-version>4.12</junit-version>
|
||||
<reactor-version>3.1.8.RELEASE</reactor-version>
|
||||
<reactor-netty-version>0.7.8.RELEASE</reactor-netty-version>
|
||||
|
||||
@@ -18,6 +18,11 @@ import com.google.gson.stream.JsonWriter;
|
||||
{{/gson}}
|
||||
public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} {
|
||||
{{#allowableValues}}{{#enumVars}}
|
||||
{{#enumDescription}}
|
||||
/**
|
||||
* {{enumDescription}}
|
||||
*/
|
||||
{{/enumDescription}}
|
||||
{{{name}}}({{{value}}}){{^-last}},
|
||||
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}
|
||||
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} {
|
||||
{{#allowableValues}}
|
||||
{{#enumVars}}
|
||||
{{#enumDescription}}
|
||||
/**
|
||||
* {{enumDescription}}
|
||||
*/
|
||||
{{/enumDescription}}
|
||||
{{{name}}}({{{value}}}){{^-last}},
|
||||
{{/-last}}{{#-last}};{{/-last}}
|
||||
{{/enumVars}}
|
||||
|
||||
@@ -95,6 +95,11 @@
|
||||
* Allow user to override superagent agent
|
||||
*/
|
||||
this.requestAgent = null;
|
||||
|
||||
/*
|
||||
* Allow user to add superagent plugins
|
||||
*/
|
||||
this.plugins = null;
|
||||
};
|
||||
|
||||
{{#emitJSDoc}} /**
|
||||
@@ -381,6 +386,14 @@
|
||||
var url = this.buildUrl(path, pathParams);
|
||||
var request = superagent(httpMethod, url);
|
||||
|
||||
if (this.plugins !== null) {
|
||||
for (var index in this.plugins) {
|
||||
if (this.plugins.hasOwnProperty(index)) {
|
||||
request.use(this.plugins[index])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apply authentications
|
||||
this.applyAuthToRequest(request, authNames);
|
||||
|
||||
|
||||
@@ -84,6 +84,11 @@ class ApiClient {
|
||||
*/
|
||||
this.requestAgent = null;
|
||||
|
||||
/*
|
||||
* Allow user to add superagent plugins
|
||||
*/
|
||||
this.plugins = null;
|
||||
|
||||
}
|
||||
|
||||
{{#emitJSDoc}}/**
|
||||
@@ -352,6 +357,14 @@ class ApiClient {
|
||||
var url = this.buildUrl(path, pathParams);
|
||||
var request = superagent(httpMethod, url);
|
||||
|
||||
if (this.plugins !== null) {
|
||||
for (var index in this.plugins) {
|
||||
if (this.plugins.hasOwnProperty(index)) {
|
||||
request.use(this.plugins[index])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apply authentications
|
||||
this.applyAuthToRequest(request, authNames);
|
||||
|
||||
@@ -425,7 +438,14 @@ class ApiClient {
|
||||
{{#usePromises}}return new Promise((resolve, reject) => {
|
||||
request.end((error, response) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
var err = {};
|
||||
err.status = response.status;
|
||||
err.statusText = response.statusText;
|
||||
err.body = response.body;
|
||||
err.response = response;
|
||||
err.error = error;
|
||||
|
||||
reject(err);
|
||||
} else {
|
||||
try {
|
||||
var data = this.deserialize(response, returnType);
|
||||
|
||||
@@ -36,7 +36,7 @@ nlohmann::json {{classname}}::toJson() const
|
||||
{{/required}}{{#required}}val["{{baseName}}"] = m_{{name}};
|
||||
{{/required}}{{/isListContainer}}{{/isPrimitiveType}}{{#isListContainer}}{
|
||||
nlohmann::json jsonArray;
|
||||
for( auto& item : m_{{name}} )
|
||||
for( const auto& item : m_{{name}} )
|
||||
{
|
||||
jsonArray.push_back({{prefix}}ModelBase::toJson(item));
|
||||
}
|
||||
@@ -49,7 +49,7 @@ nlohmann::json {{classname}}::toJson() const
|
||||
}
|
||||
{{/isListContainer}}{{#isMapContainer}}{
|
||||
nlohmann::json jsonObj;
|
||||
for( auto const& item : m_{{name}} )
|
||||
for( const auto& item : m_{{name}} )
|
||||
{ {{^items.isContainer}}
|
||||
jsonObj[item.first] = {{prefix}}ModelBase::toJson(item.second);{{/items.isContainer}} {{#items.isListContainer}}
|
||||
jsonObj[item.first] = {{prefix}}ArrayHelper::toJson<{{{items.items.datatype}}}>(item.second);
|
||||
@@ -84,7 +84,7 @@ void {{classname}}::fromJson(const nlohmann::json& val)
|
||||
{{^required}}if(val.find("{{baseName}}") != val.end())
|
||||
{
|
||||
{{/required}}
|
||||
for( auto& item : val["{{baseName}}"] )
|
||||
for( const auto& item : val["{{baseName}}"] )
|
||||
{
|
||||
{{#isPrimitiveType}}m_{{name}}.push_back(item);
|
||||
{{/isPrimitiveType}}{{^isPrimitiveType}}{{#items.isString}}m_{{name}}.push_back(item);
|
||||
@@ -114,7 +114,7 @@ void {{classname}}::fromJson(const nlohmann::json& val)
|
||||
if(val["{{baseName}}"].is_object()) { {{^items.isContainer}}
|
||||
m_{{name}} = {{prefix}}MapHelper::fromJson<{{{items.datatype}}}>(val["{{baseName}}"]);
|
||||
{{/items.isContainer}} {{#items.isContainer}}
|
||||
for( auto& item : val["{{baseName}}"].items() )
|
||||
for( const auto& item : val["{{baseName}}"].items() )
|
||||
{ {{#items.isMapContainer}}
|
||||
{{{items.datatype}}} newItem = {{prefix}}MapHelper::fromJson<{{{items.items.datatype}}}>(item.value());
|
||||
{{/items.isMapContainer}}{{#items.isListContainer}}
|
||||
|
||||
@@ -172,6 +172,7 @@ void
|
||||
|
||||
if (worker->error_type == QNetworkReply::NoError) {
|
||||
emit {{nickname}}Signal({{#returnType}}output{{/returnType}});
|
||||
emit {{nickname}}SignalFull(worker{{#returnType}}, output{{/returnType}});
|
||||
} else {
|
||||
emit {{nickname}}SignalE({{#returnType}}output, {{/returnType}}error_type, error_str);
|
||||
emit {{nickname}}SignalEFull(worker, error_type, error_str);
|
||||
|
||||
@@ -33,6 +33,8 @@ private:
|
||||
signals:
|
||||
{{#operations}}{{#operation}}void {{nickname}}Signal({{#returnType}}{{{returnType}}} summary{{/returnType}});
|
||||
{{/operation}}{{/operations}}
|
||||
{{#operations}}{{#operation}}void {{nickname}}SignalFull({{prefix}}HttpRequestWorker* worker{{#returnType}}, {{{returnType}}} summary{{/returnType}});
|
||||
{{/operation}}{{/operations}}
|
||||
{{#operations}}{{#operation}}void {{nickname}}SignalE({{#returnType}}{{{returnType}}} summary, {{/returnType}}QNetworkReply::NetworkError error_type, QString& error_str);
|
||||
{{/operation}}{{/operations}}
|
||||
{{#operations}}{{#operation}}void {{nickname}}SignalEFull({{prefix}}HttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str);
|
||||
|
||||
@@ -27,7 +27,6 @@ public:
|
||||
{{classname}}();
|
||||
{{classname}}(QString json);
|
||||
~{{classname}}() override;
|
||||
void init();
|
||||
|
||||
QString asJson () const override;
|
||||
QJsonObject asJsonObject() const override;
|
||||
@@ -43,6 +42,7 @@ public:
|
||||
virtual bool isValid() const override;
|
||||
|
||||
private:
|
||||
void init();
|
||||
{{#vars}}
|
||||
{{{dataType}}} {{name}};
|
||||
bool m_{{name}}_isSet;
|
||||
|
||||
@@ -11,6 +11,14 @@ namespace {{this}} {
|
||||
|
||||
class {{prefix}}Object {
|
||||
public:
|
||||
{{prefix}}Object() {
|
||||
|
||||
}
|
||||
|
||||
{{prefix}}Object(QString jsonString) {
|
||||
fromJson(jsonString);
|
||||
}
|
||||
|
||||
virtual ~{{prefix}}Object(){
|
||||
|
||||
}
|
||||
@@ -41,7 +49,7 @@ class {{prefix}}Object {
|
||||
return true;
|
||||
}
|
||||
private :
|
||||
QJsonObject jObj;
|
||||
QJsonObject jObj;
|
||||
};
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
|
||||
@@ -77,7 +77,7 @@ void {{classname}}Request::{{nickname}}Request({{#hasPathParams}}{{#pathParams}}
|
||||
{{^isMapContainer}}
|
||||
{{#isPrimitiveType}}
|
||||
{{{dataType}}} {{paramName}};
|
||||
::{{cppNamespace}}::fromStringValue((QString(socket->readAll()), {{paramName}});
|
||||
::{{cppNamespace}}::fromStringValue(QString(socket->readAll()), {{paramName}});
|
||||
{{/isPrimitiveType}}
|
||||
{{/isMapContainer}}
|
||||
{{#isMapContainer}}
|
||||
|
||||
@@ -27,7 +27,6 @@ public:
|
||||
{{classname}}();
|
||||
{{classname}}(QString json);
|
||||
~{{classname}}() override;
|
||||
void init();
|
||||
|
||||
QString asJson () const override;
|
||||
QJsonObject asJsonObject() const override;
|
||||
@@ -43,6 +42,7 @@ public:
|
||||
virtual bool isValid() const override;
|
||||
|
||||
private:
|
||||
void init();
|
||||
{{#vars}}
|
||||
{{{dataType}}} {{name}};
|
||||
bool m_{{name}}_isSet;
|
||||
|
||||
@@ -11,6 +11,14 @@ namespace {{this}} {
|
||||
|
||||
class {{prefix}}Object {
|
||||
public:
|
||||
{{prefix}}Object() {
|
||||
|
||||
}
|
||||
|
||||
{{prefix}}Object(QString jsonString) {
|
||||
fromJson(jsonString);
|
||||
}
|
||||
|
||||
virtual ~{{prefix}}Object(){
|
||||
|
||||
}
|
||||
@@ -41,7 +49,7 @@ class {{prefix}}Object {
|
||||
return true;
|
||||
}
|
||||
private :
|
||||
QJsonObject jObj;
|
||||
QJsonObject jObj;
|
||||
};
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace {{clientPackage}}
|
||||
private static string _dateTimeFormat = ISO8601_DATETIME_FORMAT;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the the date time format used when serializing in the ApiClient
|
||||
/// Gets or sets the date time format used when serializing in the ApiClient
|
||||
/// By default, it's set to ISO 8601 - "o", for others see:
|
||||
/// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
|
||||
/// and https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx
|
||||
|
||||
@@ -242,7 +242,7 @@ namespace {{packageName}}.Client
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the the date time format used when serializing in the ApiClient
|
||||
/// Gets or sets the date time format used when serializing in the ApiClient
|
||||
/// By default, it's set to ISO 8601 - "o", for others see:
|
||||
/// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
|
||||
/// and https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace {{packageName}}.{{apiPackage}}
|
||||
/// </summary>
|
||||
{{>visibility}} interface {{interfacePrefix}}{{classname}} : {{interfacePrefix}}{{classname}}Sync{{#supportsAsync}}, {{interfacePrefix}}{{classname}}Async{{/supportsAsync}}
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -94,7 +94,7 @@ namespace {{packageName}}.{{apiPackage}}
|
||||
{{>visibility}} partial class {{classname}} : {{interfacePrefix}}{{classname}}
|
||||
{
|
||||
private {{packageName}}.Client.ExceptionFactory _exceptionFactory = (name, response) => null;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
|
||||
/// </summary>
|
||||
@@ -151,7 +151,7 @@ namespace {{packageName}}.{{apiPackage}}
|
||||
if(asyncClient == null) throw new ArgumentNullException("asyncClient");
|
||||
{{/supportsAsync}}
|
||||
if(configuration == null) throw new ArgumentNullException("configuration");
|
||||
|
||||
|
||||
this.Client = client;
|
||||
{{#supportsAsync}}
|
||||
this.AsynchronousClient = asyncClient;
|
||||
@@ -225,13 +225,15 @@ namespace {{packageName}}.{{apiPackage}}
|
||||
public {{packageName}}.Client.ApiResponse<{{#returnType}} {{{returnType}}} {{/returnType}}{{^returnType}}Object{{/returnType}}> {{operationId}}WithHttpInfo ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
|
||||
{
|
||||
{{#allParams}}
|
||||
{{^isNullable}}
|
||||
{{#required}}
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == null)
|
||||
throw new {{packageName}}.Client.ApiException(400, "Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}");
|
||||
{{/required}}
|
||||
{{/allParams}}
|
||||
|
||||
{{/required}}
|
||||
{{/isNullable}}
|
||||
{{/allParams}}
|
||||
{{packageName}}.Client.RequestOptions requestOptions = new {{packageName}}.Client.RequestOptions();
|
||||
|
||||
String[] @contentTypes = new String[] {
|
||||
@@ -362,11 +364,14 @@ namespace {{packageName}}.{{apiPackage}}
|
||||
public async System.Threading.Tasks.Task<{{packageName}}.Client.ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}>> {{operationId}}AsyncWithHttpInfo ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
|
||||
{
|
||||
{{#allParams}}
|
||||
{{^isNullable}}
|
||||
{{#required}}
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == null)
|
||||
throw new {{packageName}}.Client.ApiException(400, "Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}");
|
||||
|
||||
{{/required}}
|
||||
{{/isNullable}}
|
||||
{{/allParams}}
|
||||
|
||||
{{packageName}}.Client.RequestOptions requestOptions = new {{packageName}}.Client.RequestOptions();
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
{{#description}}
|
||||
/// <value>{{description}}</value>
|
||||
{{/description}}
|
||||
[DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})]
|
||||
[DataMember(Name="{{baseName}}", EmitDefaultValue={{#isNullable}}true{{/isNullable}}{{^isNullable}}{{emitDefaultValue}}{{/isNullable}})]
|
||||
public {{#complexType}}{{{complexType}}}{{/complexType}}{{^complexType}}{{{datatypeWithEnum}}}{{/complexType}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}} {{name}} { get; set; }
|
||||
{{/isEnum}}
|
||||
{{/vars}}
|
||||
@@ -58,6 +58,7 @@
|
||||
{{#vars}}
|
||||
{{^isInherited}}
|
||||
{{^isReadOnly}}
|
||||
{{^isNullable}}
|
||||
{{#required}}
|
||||
{{^isEnum}}
|
||||
// to ensure "{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}" is required (not null)
|
||||
@@ -69,11 +70,16 @@
|
||||
{
|
||||
this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
|
||||
}
|
||||
|
||||
{{/isEnum}}
|
||||
{{#isEnum}}
|
||||
this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
|
||||
{{/isEnum}}
|
||||
{{/required}}
|
||||
{{/isNullable}}
|
||||
{{#isNullable}}
|
||||
this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
|
||||
{{/isNullable}}
|
||||
{{/isReadOnly}}
|
||||
{{/isInherited}}
|
||||
{{/vars}}
|
||||
@@ -108,7 +114,7 @@
|
||||
/// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
|
||||
/// </summary>{{#description}}
|
||||
/// <value>{{description}}</value>{{/description}}
|
||||
[DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})]{{#isDate}}
|
||||
[DataMember(Name="{{baseName}}", EmitDefaultValue={{#isNullable}}true{{/isNullable}}{{^isNullable}}{{emitDefaultValue}}{{/isNullable}})]{{#isDate}}
|
||||
[JsonConverter(typeof(OpenAPIDateConverter))]{{/isDate}}
|
||||
public {{{dataType}}} {{name}} { get; {{#isReadOnly}}private {{/isReadOnly}}set; }
|
||||
|
||||
|
||||
@@ -322,7 +322,7 @@ namespace {{packageName}}.Client
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the the date time format used when serializing in the ApiClient
|
||||
/// Gets or sets the date time format used when serializing in the ApiClient
|
||||
/// By default, it's set to ISO 8601 - "o", for others see:
|
||||
/// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
|
||||
/// and https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx
|
||||
|
||||
@@ -89,22 +89,22 @@ class {{classname}} {
|
||||
authNames);
|
||||
|
||||
if(response.statusCode >= 400) {
|
||||
throw new ApiException(response.statusCode, response.body);
|
||||
throw new ApiException(response.statusCode, _decodeBodyBytes(response));
|
||||
} else if(response.body != null) {
|
||||
{{#isListContainer}}
|
||||
{{#returnType}}
|
||||
return (apiClient.deserialize(response.body, '{{{returnType}}}') as List).map((item) => item as {{returnBaseType}}).toList();
|
||||
return (apiClient.deserialize(_decodeBodyBytes(response), '{{{returnType}}}') as List).map((item) => item as {{returnBaseType}}).toList();
|
||||
{{/returnType}}
|
||||
{{/isListContainer}}
|
||||
{{^isListContainer}}
|
||||
{{#isMapContainer}}
|
||||
{{#returnType}}
|
||||
return new {{{returnType}}}.from(apiClient.deserialize(response.body, '{{{returnType}}}'));
|
||||
return new {{{returnType}}}.from(apiClient.deserialize(_decodeBodyBytes(response), '{{{returnType}}}'));
|
||||
{{/returnType}};
|
||||
{{/isMapContainer}}
|
||||
{{^isMapContainer}}
|
||||
{{#returnType}}
|
||||
return apiClient.deserialize(response.body, '{{{returnType}}}') as {{{returnType}}};
|
||||
return apiClient.deserialize(_decodeBodyBytes(response), '{{{returnType}}}') as {{{returnType}}};
|
||||
{{/returnType}}
|
||||
{{/isMapContainer}}
|
||||
{{/isListContainer}}
|
||||
|
||||
@@ -50,3 +50,15 @@ String parameterToString(dynamic value) {
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the decoded body by utf-8 if application/json with the given headers.
|
||||
/// Else, returns the decoded body by default algorithm of dart:http.
|
||||
/// Because avoid to text garbling when header only contains "application/json" without "; charset=utf-8".
|
||||
String _decodeBodyBytes(Response response) {
|
||||
var contentType = response.headers['content-type'];
|
||||
if (contentType != null && contentType.contains("application/json")) {
|
||||
return utf8.decode(response.bodyBytes);
|
||||
} else {
|
||||
return response.body;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,37 +16,41 @@ class {{classname}} {
|
||||
{{classname}}.fromJson(Map<String, dynamic> json) {
|
||||
if (json == null) return;
|
||||
{{#vars}}
|
||||
if (json['{{baseName}}'] == null) {
|
||||
{{name}} = null;
|
||||
} else {
|
||||
{{#isDateTime}}
|
||||
{{name}} = json['{{baseName}}'] == null ? null : DateTime.parse(json['{{baseName}}']);
|
||||
{{name}} = DateTime.parse(json['{{baseName}}']);
|
||||
{{/isDateTime}}
|
||||
{{#isDate}}
|
||||
{{name}} = json['{{baseName}}'] == null ? null : DateTime.parse(json['{{baseName}}']);
|
||||
{{name}} = DateTime.parse(json['{{baseName}}']);
|
||||
{{/isDate}}
|
||||
{{^isDateTime}}
|
||||
{{^isDate}}
|
||||
{{#complexType}}
|
||||
{{#isListContainer}}
|
||||
{{name}} = {{complexType}}.listFromJson(json['{{baseName}}']);
|
||||
{{name}} = {{complexType}}.listFromJson(json['{{baseName}}']);
|
||||
{{/isListContainer}}
|
||||
{{^isListContainer}}
|
||||
{{#isMapContainer}}
|
||||
{{name}} = {{complexType}}.mapFromJson(json['{{baseName}}']);
|
||||
{{name}} = {{complexType}}.mapFromJson(json['{{baseName}}']);
|
||||
{{/isMapContainer}}
|
||||
{{^isMapContainer}}
|
||||
{{name}} = new {{complexType}}.fromJson(json['{{baseName}}']);
|
||||
{{name}} = new {{complexType}}.fromJson(json['{{baseName}}']);
|
||||
{{/isMapContainer}}
|
||||
{{/isListContainer}}
|
||||
{{/complexType}}
|
||||
{{^complexType}}
|
||||
{{#isListContainer}}
|
||||
{{name}} = (json['{{baseName}}'] as List).map((item) => item as {{items.datatype}}).toList();
|
||||
{{name}} = (json['{{baseName}}'] as List).map((item) => item as {{items.datatype}}).toList();
|
||||
{{/isListContainer}}
|
||||
{{^isListContainer}}
|
||||
{{name}} = json['{{baseName}}'];
|
||||
{{name}} = json['{{baseName}}'];
|
||||
{{/isListContainer}}
|
||||
{{/complexType}}
|
||||
{{/isDate}}
|
||||
{{/isDateTime}}
|
||||
}
|
||||
{{/vars}}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,22 +89,22 @@ class {{classname}} {
|
||||
authNames);
|
||||
|
||||
if(response.statusCode >= 400) {
|
||||
throw new ApiException(response.statusCode, response.body);
|
||||
throw new ApiException(response.statusCode, _decodeBodyBytes(response));
|
||||
} else if(response.body != null) {
|
||||
{{#isListContainer}}
|
||||
{{#returnType}}
|
||||
return (apiClient.deserialize(response.body, '{{{returnType}}}') as List).map((item) => item as {{returnBaseType}}).toList();
|
||||
return (apiClient.deserialize(_decodeBodyBytes(response), '{{{returnType}}}') as List).map((item) => item as {{returnBaseType}}).toList();
|
||||
{{/returnType}}
|
||||
{{/isListContainer}}
|
||||
{{^isListContainer}}
|
||||
{{#isMapContainer}}
|
||||
{{#returnType}}
|
||||
return new {{{returnType}}}.from(apiClient.deserialize(response.body, '{{{returnType}}}'));
|
||||
return new {{{returnType}}}.from(apiClient.deserialize(_decodeBodyBytes(response), '{{{returnType}}}'));
|
||||
{{/returnType}};
|
||||
{{/isMapContainer}}
|
||||
{{^isMapContainer}}
|
||||
{{#returnType}}
|
||||
return apiClient.deserialize(response.body, '{{{returnType}}}') as {{{returnType}}};
|
||||
return apiClient.deserialize(_decodeBodyBytes(response), '{{{returnType}}}') as {{{returnType}}};
|
||||
{{/returnType}}
|
||||
{{/isMapContainer}}
|
||||
{{/isListContainer}}
|
||||
|
||||
@@ -50,3 +50,15 @@ String parameterToString(dynamic value) {
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the decoded body by utf-8 if application/json with the given headers.
|
||||
/// Else, returns the decoded body by default algorithm of dart:http.
|
||||
/// Because avoid to text garbling when header only contains "application/json" without "; charset=utf-8".
|
||||
String _decodeBodyBytes(Response response) {
|
||||
var contentType = response.headers['content-type'];
|
||||
if (contentType != null && contentType.contains("application/json")) {
|
||||
return utf8.decode(response.bodyBytes);
|
||||
} else {
|
||||
return response.body;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,37 +16,41 @@ class {{classname}} {
|
||||
{{classname}}.fromJson(Map<String, dynamic> json) {
|
||||
if (json == null) return;
|
||||
{{#vars}}
|
||||
if (json['{{baseName}}'] == null) {
|
||||
{{name}} = null;
|
||||
} else {
|
||||
{{#isDateTime}}
|
||||
{{name}} = json['{{baseName}}'] == null ? null : DateTime.parse(json['{{baseName}}']);
|
||||
{{name}} = DateTime.parse(json['{{baseName}}']);
|
||||
{{/isDateTime}}
|
||||
{{#isDate}}
|
||||
{{name}} = json['{{baseName}}'] == null ? null : DateTime.parse(json['{{baseName}}']);
|
||||
{{name}} = DateTime.parse(json['{{baseName}}']);
|
||||
{{/isDate}}
|
||||
{{^isDateTime}}
|
||||
{{^isDate}}
|
||||
{{#complexType}}
|
||||
{{#isListContainer}}
|
||||
{{name}} = {{complexType}}.listFromJson(json['{{baseName}}']);
|
||||
{{name}} = {{complexType}}.listFromJson(json['{{baseName}}']);
|
||||
{{/isListContainer}}
|
||||
{{^isListContainer}}
|
||||
{{#isMapContainer}}
|
||||
{{name}} = {{complexType}}.mapFromJson(json['{{baseName}}']);
|
||||
{{name}} = {{complexType}}.mapFromJson(json['{{baseName}}']);
|
||||
{{/isMapContainer}}
|
||||
{{^isMapContainer}}
|
||||
{{name}} = new {{complexType}}.fromJson(json['{{baseName}}']);
|
||||
{{name}} = new {{complexType}}.fromJson(json['{{baseName}}']);
|
||||
{{/isMapContainer}}
|
||||
{{/isListContainer}}
|
||||
{{/complexType}}
|
||||
{{^complexType}}
|
||||
{{#isListContainer}}
|
||||
{{name}} = ((json['{{baseName}}'] ?? []) as List).map((item) => item as {{items.datatype}}).toList();
|
||||
{{name}} = (json['{{baseName}}'] as List).map((item) => item as {{items.datatype}}).toList();
|
||||
{{/isListContainer}}
|
||||
{{^isListContainer}}
|
||||
{{name}} = json['{{baseName}}'];
|
||||
{{name}} = json['{{baseName}}'];
|
||||
{{/isListContainer}}
|
||||
{{/complexType}}
|
||||
{{/isDate}}
|
||||
{{/isDateTime}}
|
||||
}
|
||||
{{/vars}}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user