Compare commits

..

95 Commits

Author SHA1 Message Date
William Cheng
56bba880e7 3.2.1 release (#807)
* 3.2.1 release

* roll back incorrect change to link

* update doc

* update 3.1.2 release

* Fix version table
2018-08-14 17:47:59 +08:00
Jim Schubert
7acba8a4d8 [generator] Cleanup debugOpenAPI usage/display text (#804) 2018-08-14 11:45:50 +08:00
Geoff Brown
08ca54d3d5 Fixed date formatting in typescript node client (#786)
Fixes #785
2018-08-13 19:27:31 +02:00
William Cheng
7b04732f09 better explain usage (#794) 2018-08-13 09:30:18 -04:00
William Cheng
b64864f47d Fix float/double default value in C# generator (#791)
* fix float/double default value

* better code format

* better CI for openapi3 batch files (C# client)

* update nancyfx samples

* pipe output to /dev/null to reduce log size

* fix windows batch file

* add C# API client generated by OAS3 spec
2018-08-13 13:28:22 +08:00
William Cheng
c237fe9f1c Enhancements to documentation generators (samples, default values, etc) (#790)
* enhancements to doc generators (samples, default values, etc)

* add 3.3.x to PR template
2018-08-13 13:27:45 +08:00
Jérémie Bresson
5e1c4cde50 Remove duplicate variable declaration (#792) 2018-08-13 13:26:34 +08:00
attrobit
1559c4fadd Issue 758 root resource (#771)
* Unit-Test for JavaJAXRSSpecServerCodegen.

* Path generation for primary resource fixed.

* Unit test for toApiName.

* Review-Feedback: blank line removed.
2018-08-12 22:37:19 +08:00
Rytis Karpuška
0cd6d8c139 Do not declare destructor as default when destructor is explicitly declared. (#732) 2018-08-12 13:44:07 +02:00
William Cheng
ddb0920fed Fix C# client enum issue (#774)
* fix csharp enum issue

* fix numeric enum value

* add docstring to exlain isDataTypeString

* fix docstring by adding return

* fix ToJson in hash model

* remove BaseValidate for map model

* restore csproj file
2018-08-11 11:34:20 +08:00
Akihito Nakano
21777f2759 [JavaScript] Update vulnerable dependencies (#784)
* Update vulnerable dependencies

* Update samples: javascript-es6

* Update samples: javascript-promise

* Update samples: javascript-promise-es6

* Update samples: javascript

* Update samples: petstore-security-test/javascript

* Rename operationId if it starts with a number

* Update samples

bin/javascript-petstore.sh
bin/javascript-es6-petstore.sh
bin/javascript-promise-petstore.sh
bin/javascript-promise-es6-petstore.sh
2018-08-10 21:50:33 +08:00
Yusuke Iinuma
afdef8f890 [Ruby] Fix method split (#780)
* Fix methods split for readable

* Recreate sample
2018-08-10 17:25:22 +08:00
Dec12 | Fujigon
d019bbd2c7 [Java][jaxrs-jersey] add sample with jaxrs-jersey + openapi v3 (#778)
* create sample with "jaxrs-jersey" language & openapi v3

* circle ci setting

* fix typo. also add "jaxrs-jersey" to all samples profile

* artifactId conflicts. rename.

* generate samples with "./bin/openapi3/jaxrs-jersey-petstore.sh"
2018-08-10 17:24:24 +08:00
William Cheng
748d1d70cb update groupId in pom (#779) 2018-08-10 15:48:19 +08:00
Daniel Miller
987fd77042 [cpp-restsdk] Support multi-line descriptions (#753)
* Update IndentedLambda to take optional prefix

* Add `multiline_comment_4` to CppRestSdkClient

* Update cpp-restsdk example
2018-08-09 19:01:15 -04:00
antihax
a0984a9be8 [Core] Resolve Inline Models (#736)
* Add InlineModelResolver.java

* fix inline schema for OAS2 body parameter

* skip warning, fix MapSchema cast error
2018-08-09 23:27:51 +08:00
Jim Schubert
9920c435ca [gradle] Support nullable system property values (#764)
The gradle plugin sets all System properties before generation, then
reverts them back to their original state.

System.getProperty/setProperty return null if the property was not
previously set. The Kotlin map was defined with non-nullable key/value
constraints, so setting something not commonly set (modelDocs: "false")
would result in an runtime exception.

This changes the map to support nullable values, and rather than setting
a null System property at the end, it clears those which previously had
no value.
2018-08-09 15:56:15 +08:00
David Webster
4060fcbb8b Correct URL for openapi-generator.cli.sh in README.md (#770) 2018-08-09 10:42:11 +08:00
Rubén Martínez
d0ccac5663 Fixed the generation of model properties whose data type is a composed (allOf) schema (#704)
* #582 Fixed the generation of model properties whose data type is a composed (allOf) schema. Before this fix, the data type name of the generated property was that of the first model participating in the allOf clause. After this fix the property data type is again as expected: the one of the composed schema and not one of its parents.

* Added unit test in order to have regression testing in the fix for the #582 issue (references to composed schemas should not get unaliased for them to get a proper data type name in the generation of model properties).

* Run ./bin/utils/ensure-up-to-date to re-generate samples run in the CI.

* Removed tabs from ModelUtilsTest.java
2018-08-08 13:06:42 -04:00
William Cheng
06263d7606 [JAX-RS][Spec] Add samples to CircleCI (#759)
* test jaxrs spec server petstore in circleci

* remove duplicated entries in pom

* trigger build failure

* Revert "trigger build failure"

This reverts commit 35ac96ed4a.
2018-08-08 11:50:33 +08:00
William Cheng
3245c0a139 minor update to python generator usage (#762) 2018-08-08 11:21:34 +08:00
stkrwork
0809d8f527 [C++][Restbed/Pistache] Added fix for byte array (#752)
* Added fix for byte array

* Fix spacing

* Adapted default value for ByteArray

* Adapted default value for ByteArray in Pistache Server
2018-08-07 17:07:05 +02:00
sunn
baf16cf834 [cpp pistache] use model namespace only on Model import (#733)
Don't use model namespaces when not imported
2018-08-07 15:19:56 +02:00
Dec12 | Fujigon
629608c573 [jaxrs-spec*] samples should be tested. repair import and dependency. (#755)
* sample server projects "jaxrs-spec", "jaxrs-spec-interface", and "jaxrs-spec-interface-response" should be tested

* update jax-rs api to 2.1, in which @PATCH annotation is available
add jackson annotation dependency

* add joda-time to dependency

* modify mustache template to add @JsonCreate, @JsonValue import

* fix return type of enum value() method

* add InputStream import

* Attachment class is in apache cxf. spec should not depend on it

* re-generate sample jaxrs-spec, jaxrs-spec-interface, and jaxrs-spec-interface-response
2018-08-07 16:45:09 +08:00
sunn
e143214685 [cpp pistache] fix leading number in model names and apply modelNamePrefix in all cases (#730)
* Fix numbers in nameInCamelCase. Add possibility to prefix Names to avoid conflicts
* Allow unique prefixing for template functions as well
2018-08-06 22:22:22 +02:00
William Cheng
2340d83a33 add 3.3.0 to readme 2018-08-07 01:39:54 +08:00
William Cheng
90a8b81728 Prepare 3.2.1-SNAPSHOT release (#748)
* prepare 3.2.1 SNAPSHOT release

* update doc to use 3.2.0 stable version
2018-08-07 01:31:37 +08:00
William Cheng
30fb22fffa update readme with links to 3.2.0 JAR 2018-08-06 23:47:36 +08:00
William Cheng
f329872ce7 3.2.0 release (#744) 2018-08-06 22:06:39 +08:00
Alexey Alekhin
05db32fea2 [Elm] Template improvements (#661)
* Add elm template parameter to the samples testing script

* Update elm-date-extra package; fixes #458

* Update generated elm samples

* Use Elm doc comments; remove some unneccessary newlines

* Update generated Elm samples

* Remove unnecessary parenthesis around non-optional container type
2018-08-06 18:17:59 +08:00
William Cheng
c116c8fb9b [PHP] Decommission "packagePath", add new option "packageName" (#681)
* remove packagePath from php file location, use -o instead

* fix php symfony top folder

* restore pacakgePath

* update php laraavel samples

* remove packagePath from PHP generator

* add new silex files

* update window batch - php silex

* fix openapi3 silex script
2018-08-06 18:10:34 +08:00
William Cheng
1ab4fe43b5 fix petstore security spec to remove validation errors (#739) 2018-08-06 17:02:02 +08:00
Jon Schoning
f6c21057e1 [haskell-http-client] regen samples (#709)
* [haskell-http-client] regen samples

* ensure the haskell-http-client samples are always up-to-date
2018-08-05 15:11:52 -05:00
William Cheng
c9085b4f2b Update Q&A based on feedback from users (#695)
* update qna based on feedback from users

* Improvements

* minor fix to typo
2018-08-05 17:49:36 +08:00
William Cheng
f6146b212f [PHP] better operationId handling, add CI for PHP slim server (#723)
* better operationId handling, add CI for PHP slim

* use spaces instead of tabs

* replace tab with space

* install php
2018-08-03 10:47:54 +08:00
Akihito Nakano
2b429ee43b [PHP] [Laravel] Fix syntax errors in models (#721)
* Fix syntax errors in Models

* Update samples

./bin/php-laravel-petstore-server.sh
2018-08-03 10:44:12 +08:00
David van Laatum
a258cf3fc6 #714 prevent throwing another exception if the request fails eg connection reset (#715)
* prevent throwing another exception if the request fails eg connection reset

* prevent throwing another exception if the request fails eg connection reset
2018-08-03 00:02:09 +08:00
William Cheng
07a5715b9f Add template creator: C++ qt5 server, php laravel (#720) 2018-08-02 22:39:37 +08:00
William Cheng
f32398a708 add dockerfile for ror, fix template issue (#718) 2018-08-02 22:07:09 +08:00
William Cheng
f0425d77ef [Ruby] Better handling of operationID starting with a number (#719)
* better handling of operationId starting with numbers in Ruby

* update Rubocop to use Layout
2018-08-02 22:00:50 +08:00
William Cheng
e0020b41da underscore classVarName to fix route issue in ROR (#706) 2018-08-02 21:42:09 +08:00
William Cheng
375c26ccb3 add option to select db adapter in ror (#711) 2018-08-02 13:52:34 +08:00
William Cheng
40024ac72a [Go] Prefix enum number with _ (#703)
* prefix enum number with _ in go

* reformat code, use else if
2018-08-02 10:13:01 +08:00
William Cheng
ab08dd1d26 Better handling of operationID starting with numbers (#691)
* add numeric operationid to test spec

* better handling of operationId in more generators

* fix go toOperationId

* update samples

* update java samples

* update java samples (vertx, webclient)

* update java google api client sample

* fix typo, update OAS3 test spec, update php petstore (oas3)

* defer camelize in operationid

* remove duplicated sanitizeName
2018-08-01 22:31:58 +08:00
William Cheng
21141f682f Fix Javadoc string error in Java (rest-assured) client (#702)
* fix docstring

* trigger build failure

* Revert "trigger build failure"

This reverts commit 12cd26f0ca.

* update java samples
2018-08-01 22:13:41 +08:00
Jeremie Bresson
d8ea28e147 Update "phpunit.xml.dist" 2018-08-01 14:43:34 +02:00
Victor Orlovsky
82156b6639 Added constant "httpMethod", "summary" (#697) 2018-08-01 12:02:11 +08:00
Jérémie Bresson
3085bf1df5 [typescript] allow $ in var name (#694) 2018-07-31 19:36:16 +02:00
Yuriy Belenko
58e0946b1e [Slim] Add Basic authentication middleware (#606)
* [Slim] Add Basic Authentication Middleware

User needs to add own implementation to verifyCredentials method in AuthBasic.php.

* [Slim] Update README template

I'm not sure about `middlewareSrcPath` variable. I'll fix it in following PRs
if path is broken.
Hope that notice in README catches attention and most of users will read it.

* Revert "[Slim] Update README template"

This reverts commit 204ee02fd8.

* Revert "[Slim] Add Basic Authentication Middleware"

This reverts commit 6a8e03079a.

* [Slim] Add "tuupola/slim-basic-auth" package

Package "tuupola/slim-basic-auth" 3.1.0 requires PHP 7, that's why I
set it's version to ^3.0.0 in Composer. Minimum version will be
3.0.0-rc.1 which supports PHP 5.5. I've tested build with PHP 7, it
would be nice to check build with PHP 5.5 someday.

* [Slim] Update README template

Not sure about forward slash in path to SlimRouter class. I will fix it
in upcoming PRs if necessary.

* [Slim] Refresh samples
2018-08-01 00:55:30 +08:00
Christoph, René Pardon
f793ac25c7 feat (PHP LARAVEL) 8417: initial PHP-laravel codegen integration (#574)
* feat (PHP LARAVEL) 8417: initial PHP-laravel codegen integration

* feat (PHP LARAVEL) 8417: code review adjustments

* feat (PHP LARAVEL) 8417: fix typos; add missing files; adjust readme for those unfamilar with laravel to get started quickly

* feat (PHP LARAVEL) 8417: add sample petstore server

* feat (PHP LARAVEL) 8417: adjust route service provdider and model generation
2018-08-01 00:34:33 +08:00
René Winkelmeyer
d1fc923b66 Re-implementation of Apex client code gen (#698) 2018-07-31 23:02:25 +08:00
Jérémie Bresson
f1897c4462 Update swagger-parser to "2.0.2-OpenAPITools.org-1" (#696) 2018-07-31 14:02:35 +02:00
William Cheng
d8ec6b2003 [Apex] migrating to OpenAPI Generator project (#692)
* [apex] migrating to OpenAPITools

* migrate apex to openapi-generator
2018-07-31 15:28:54 +08:00
Jérémie Bresson
824654964b Use Released version in maven samples (#693)
* Fixing maven examples:  set version to last released version and other improvements
* Include example poms in the "release_version_update_docs.sh" script
2018-07-31 06:32:24 +02:00
William Cheng
0c52fcd5ff udpate rust server samples 2018-07-31 11:33:23 +08:00
sunn
926b971497 [qt5 server] Improvement in response handling (#675)
* Remove warnings and add custom request sending

* Remove duplicate code from subclass and add missing setupRoutes

* Removed redundant override

* Add serialization of responses

* Fix CI failure

* Add inline function to duplicate code.

* Make const reference wherever possible

* Add support for Array of Primitive types.

* Add Array of Primitive support for Error response

* Update for multiple path params
2018-07-31 00:16:46 +08:00
Jérémie Bresson
1e95d36809 Add "Validate spec on generation by default" section (#683) 2018-07-30 17:53:26 +02:00
Benjamin Gill
a3e5185e39 Ignore additional properties (#671)
* Ignore additionalProperties

rust-server doen't yet support them, and they cause quite a bit of havoc at the moment (ending up as the `HashMap` type).

* Use .equals() rather than `==`
2018-07-30 23:06:05 +08:00
William Cheng
1cbfca4887 Update instruction to disable validateSpec (#684) 2018-07-30 13:29:05 +02:00
Benjamin Gill
b0909ade6f [rust-server] add support for '|' in path segments (#667)
* Added encoding for vertical bar character in object IDs for client requests

* Updated sample
2018-07-30 18:38:52 +08:00
William Cheng
036fa6918c fix operation id starting with number for python client (#682) 2018-07-30 15:42:06 +08:00
sunn
b587052de4 cpp-tizen extends AbstractCppCodegen (#676)
* cpp-tizen extends AbstractCppCodegen

* Update javadoc comment
2018-07-30 15:33:00 +08:00
Benjamin Gill
cb9a734ebb [rust-server] add support for multiple samples (#658)
* Add support for multiple rust-server samples

Though we only have the one as yet. This will make it easier to move rust-server back on to the main test spec, whilst preserving the ability to have rust-specific test specs.

* Rust samples need unique names

* Move samples to a dedicated directory

So that there is nothing else in the folder where they live so that the workspace definition in the root Cargo.toml can be simple.
2018-07-30 15:31:55 +08:00
William Cheng
01dbb8b693 fix base path when it's not defined in the spec (#678) 2018-07-30 15:09:56 +08:00
Rubén Martínez
68d80ab67d [Java][Client][RestTemplate] Fixed invalid URL-encoding of query parameters (#646)
Fix for the #644
2018-07-30 08:38:10 +02:00
Jérémie Bresson
14ab3d763e Consider cases where complexType is null (#680) 2018-07-29 13:10:58 +02:00
Benjamin Gill
3c3ac0a071 Add extra modules to main dockerfile (#650)
So that the mvn build is successful
2018-07-28 16:10:49 +08:00
Rytis Karpuška
0b88889cdf [cpp] Sanitize identifier names (#631)
* [cpp] Sanitize identifier names

* Remove duplicated methods in cpp code generator subclasses.

* Fix unintended codegen differences in cpp tizen caused by it not extending AbstractCppCodegen class.
2018-07-28 15:23:35 +08:00
William Cheng
b33f1f945b add stop wait to spring pom (#670) 2018-07-27 23:41:31 +08:00
Jérémie Bresson
c7953ac137 Split release_version_update script in 2 scripts (#657) 2018-07-27 18:32:13 +08:00
sunn
534b6b5978 [cpp qt5 server] Improve qt5 server naming (#655)
* Adapted according to reviews

* Add changed files

* Update beta tag to the naming
2018-07-27 01:49:26 +08:00
Benjamin Gill
b6fc29050d Implement stack for Swagger Context (#612) 2018-07-27 01:48:43 +08:00
William Cheng
7e494e52ab Various improvements (#653)
* improve validation error message

* minor improvement to qt5 c++ server

* fix invalid spec (causing shippable failure)

* Revert "minor improvement to qt5 c++ server"

This reverts commit 56f356cc51.
2018-07-26 23:10:15 +08:00
Benjamin Gill
7624a1ff85 Various enhancements to html2 docsgen (#643)
This commit includes the following changes:

- Fix docs not generating parameter descriptions, add rust sample.
- Add example to doc output.
- Add basic scope reporting.
- Stringify the JSON "Example" objects for response schemas.
- Prettify JSON examples in response schemas.
- Parse and present multiline response descriptions.
- Add API error details to docsgen.
- Add read only markers to read only properties.
- Fix up style document indentation.
- Add support for `x-shared-errors`, an extension to define common error types that can be shared across a microservice framework.
2018-07-26 21:57:57 +08:00
Benjamin Gill
1d72edddf6 Avoid HTML escaping of rust-server output (#645) 2018-07-26 21:46:59 +08:00
Akihito Nakano
c9b934147a [PHP] Escape media type (#615)
* Move escapeMediaType() to AbstractPhpCodegen

* Escape media type

* Update samples

- bin/php-lumen-petstore-server.sh

* Refactoring: remove unused 'import'
2018-07-26 21:26:01 +08:00
sunn
65bad61abb [Qt5 Server] Add Support for Qt5 server using QHttpEngine (#322)
* Initial wiring to get the QHttpEngine Server running for Qt5 server

* Add wiring for build environment

* Add current generated files

* Update README.md

* Solved Build for Docker and Host
Wired up main
TODO : Route API call to handlers

* Wire up routes

* Wiring up routes update

* Convert Path to QHttpEngine format

* Rename some files

* Extract query Parameters and path parameters

* Removed pri file, Qt can read CMakeLists.txt

* Initial support of deserialization

* Adding initial support for response serialization

* Setup simple signal handler to quite the server with Ctrl+C in a container and on the host

* Remove unneeded function

* Add executable permission to script and move from Debian to Alpine for Dockerfile

* Add stringValue of missing types

* Unify toJson'xxx' APIs the same way like setValue

* Rework to remove all pointer usages, pass by const references, simplify model, add emit signals to default handlers
2018-07-26 18:30:13 +08:00
Jim Schubert
77df3d6770 Validate spec on generation by default (#251)
* Validate spec on generation by default

Adds a validation parameter to CodegenConfigurator, and passes through
options from CLI, Maven Plugin and Gradle Plugin to that property.

Default is to validate the spec during generation. If spec has errors,
we will output errors as well as warnings to the user.

Option can be disabled by passing false to validateSpec (Maven/Gradle)
or --validate-spec (CLI).

* Prepare version 3.1.1-SNAPSHOT

* fix version

* Use last prod version for the sample

* Update README.md

Fix

* [cli] Option parser does not support true/false for boolean options
2018-07-26 17:36:08 +08:00
Jérémie Bresson
a8e8acead7 [java] add useNullForUnknownEnumValue option (#633) 2018-07-26 11:00:45 +02:00
Rytis Karpuška
44d419c1a1 Fix inconsistent parameter names when ensuring uniqueness. (#640) 2018-07-25 21:46:56 +02:00
Jérémie Bresson
60c81eae0a Prepare version 3.2.0 (#651) 2018-07-25 20:27:16 +02:00
Jeremie Bresson
00246f3ea0 Merge remote-tracking branch 'origin/master' into 3.2.x
* Solve Conflicts
* Activate "ensure_up_to_date" script
* Remove references to the "3.2.x" branch

# Conflicts:
#	CI/pom.xml.bash
#	CI/pom.xml.circleci
#	CI/pom.xml.circleci.java7
#	CI/pom.xml.ios
#	modules/openapi-generator-cli/pom.xml
#	modules/openapi-generator-gradle-plugin/gradle.properties
#	modules/openapi-generator-gradle-plugin/pom.xml
#	modules/openapi-generator-maven-plugin/pom.xml
#	modules/openapi-generator-online/Dockerfile
#	modules/openapi-generator-online/pom.xml
#	modules/openapi-generator/pom.xml
#	pom.xml
2018-07-25 18:19:37 +02:00
Jeremie Bresson
70cdd27e75 Merge remote-tracking branch 'origin/master' into 3.2.x 2018-07-25 16:51:19 +02:00
William Cheng
27a356dacf default isAddExternalLibs to true (#626) 2018-07-24 12:08:29 +08:00
William Cheng
667e3130fe Merge remote-tracking branch 'origin/master' into 3.2.x 2018-07-23 23:04:28 +08:00
Tomasz Prus
8867d2b34c Support for python 3.7 by renaming async to async_req (#519)
* feat: support for python 3.7

* fix: regenerate other sample clients
2018-07-20 22:14:18 +08:00
William Cheng
71ef6a0a2b update petstore samples 2018-07-19 19:28:31 +08:00
William Cheng
888da52181 Merge remote-tracking branch 'origin/master' into 3.2.x 2018-07-19 18:46:18 +08:00
Jeremie Bresson
45ed374b62 Merge remote-tracking branch 'origin/master' into 3.2.x 2018-07-18 12:19:41 +02:00
Jérémie Bresson
baaa335664 Add documentation for CodegenDiscriminator (#587) 2018-07-18 09:07:35 +02:00
Daonomic
0a52f56ba4 Support for discriminator.mapping (#536) 2018-07-18 06:14:42 +02:00
William Cheng
478d6ced4e Merge remote-tracking branch 'origin/master' into 3.2.x 2018-07-14 01:35:54 +08:00
Jeremie Bresson
0cc60d39d2 Merge remote-tracking branch 'origin/master' into 3.2.x 2018-07-13 07:25:49 +02:00
Jeremie Bresson
8f6bb8d9ec Merge remote-tracking branch 'origin/master' into 3.2.x 2018-07-07 09:13:54 +02:00
Jeremie Bresson
23c04e2e66 Prepare version 3.2.0-SNAPSHOT 2018-07-07 06:14:58 +02:00
2210 changed files with 59409 additions and 13262 deletions

View File

@@ -2,7 +2,7 @@
- [ ] Read the [contribution guidelines](https://github.com/openapitools/openapi-generator/blob/master/CONTRIBUTING.md).
- [ ] Ran the shell script under `./bin/` to update Petstore sample so that CIs can verify the change. (For instance, only need to run `./bin/{LANG}-petstore.sh` and `./bin/security/{LANG}-petstore.sh` if updating the {LANG} (e.g. php, ruby, python, etc) code generator or {LANG} client's mustache templates). Windows batch files can be found in `.\bin\windows\`.
- [ ] Filed the PR against the [correct branch](https://github.com/OpenAPITools/openapi-generator/wiki/Git-Branches): `master`, `3.2.x`, `4.0.x`. Default: `master`.
- [ ] Filed the PR against the [correct branch](https://github.com/OpenAPITools/openapi-generator/wiki/Git-Branches): `master`, `3.3.x`, `4.0.x`. Default: `master`.
- [ ] Copied the [technical committee](https://github.com/openapitools/openapi-generator/#62---openapi-generator-technical-committee) to review the pull request if your PR is targeting a particular programming language.
### Description of the PR

2
.gitignore vendored
View File

@@ -99,6 +99,8 @@ samples/client/petstore/silex/SwaggerServer/venodr/
samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/cache/
samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/logs/
#PHP-laravel
samples/server/petstore/php-laravel/node_modules
# Perl
samples/client/petstore/perl/deep_module_test/

View File

@@ -123,7 +123,7 @@ after_success:
./gradlew -Psigning.keyId="$SIGNING_KEY" -Psigning.password="$SIGNING_PASSPHRASE" -Psigning.secretKeyRingFile="${TRAVIS_BUILD_DIR}/sec.gpg" -PossrhUsername="${SONATYPE_USERNAME}" -PossrhPassword="${SONATYPE_PASSWORD}" uploadArchives --no-daemon;
echo "Finished ./gradlew uploadArchives";
popd;
elif ([ "$TRAVIS_BRANCH" == "3.1.x" ] || [ "$TRAVIS_BRANCH" == "4.0.x" ]) ; then
elif ([ "$TRAVIS_BRANCH" == "4.0.x" ]) ; then
mvn clean deploy --settings CI/settings.xml;
echo "Finished mvn clean deploy for $TRAVIS_BRANCH";
pushd .;

View File

@@ -9,7 +9,7 @@
<artifactId>openapi-generator-project</artifactId>
<packaging>pom</packaging>
<name>openapi-generator-project</name>
<version>3.1.2</version>
<version>3.2.1</version>
<url>https://github.com/openapi-tools/openapi-generator</url>
<scm>
<connection>scm:git:git@github.com:openapi-tools/openapi-generator.git</connection>
@@ -920,7 +920,7 @@
</repository>
</repositories>
<properties>
<swagger-parser-version>2.0.1</swagger-parser-version>
<swagger-parser-version>2.0.2-OpenAPITools.org-1</swagger-parser-version>
<swagger-core-version>2.0.1</swagger-core-version>
<scala-version>2.11.1</scala-version>
<felix-version>3.3.0</felix-version>

View File

@@ -10,7 +10,7 @@
<artifactId>openapi-generator-project</artifactId>
<packaging>pom</packaging>
<name>openapi-generator-project</name>
<version>3.1.2</version>
<version>3.2.1</version>
<url>https://github.com/openapitools/openapi-generator</url>
<scm>
<connection>scm:git:git@github.com:openapitools/openapi-generator.git</connection>
@@ -607,6 +607,55 @@
<module>samples/server/petstore/jaxrs/jersey1</module>
</modules>
</profile>
<profile>
<!-- openapi v3's one -->
<id>jaxrs-jersey</id>
<activation>
<property>
<name>env</name>
<value>java</value>
</property>
</activation>
<modules>
<module>samples/server/petstore/jaxrs-jersey</module>
</modules>
</profile>
<profile>
<id>jaxrs-spec</id>
<activation>
<property>
<name>env</name>
<value>java</value>
</property>
</activation>
<modules>
<module>samples/server/petstore/jaxrs-spec</module>
</modules>
</profile>
<profile>
<id>jaxrs-spec-interface</id>
<activation>
<property>
<name>env</name>
<value>java</value>
</property>
</activation>
<modules>
<module>samples/server/petstore/jaxrs-spec-interface</module>
</modules>
</profile>
<profile>
<id>jaxrs-spec-interface-response</id>
<activation>
<property>
<name>env</name>
<value>java</value>
</property>
</activation>
<modules>
<module>samples/server/petstore/jaxrs-spec-interface-response</module>
</modules>
</profile>
<profile>
<id>typescript-fetch-client-tests-default</id>
<activation>
@@ -862,6 +911,10 @@
<module>samples/client/petstore/kotlin-threetenbp/</module>
<module>samples/client/petstore/kotlin-string/</module>
<!-- servers -->
<module>samples/server/petstore/jaxrs-jersey</module>
<module>samples/server/petstore/jaxrs-spec</module>
<module>samples/server/petstore/jaxrs-spec-interface</module>
<module>samples/server/petstore/jaxrs-spec-interface-response</module>
<module>samples/server/petstore/java-vertx/rx</module>
<module>samples/server/petstore/java-vertx/async</module>
<module>samples/server/petstore/java-inflector</module>
@@ -901,7 +954,6 @@
<module>samples/server/petstore/jaxrs-cxf-cdi</module>
<module>samples/server/petstore/jaxrs-cxf-non-spring-app</module>
<module>samples/server/petstore/java-msf4j</module>
<module>samples/server/petstore/jaxrs-spec-interface</module>
<module>samples/server/petstore/scala-lagom-server</module>
<module>samples/server/petstore/scalatra</module>
<module>samples/server/petstore/finch</module>
@@ -976,7 +1028,7 @@
</repository>
</repositories>
<properties>
<swagger-parser-version>2.0.1</swagger-parser-version>
<swagger-parser-version>2.0.2-OpenAPITools.org-1</swagger-parser-version>
<swagger-core-version>2.0.1</swagger-core-version>
<scala-version>2.11.1</scala-version>
<felix-version>3.3.0</felix-version>

View File

@@ -10,7 +10,7 @@
<artifactId>openapi-generator-project</artifactId>
<packaging>pom</packaging>
<name>openapi-generator-project</name>
<version>3.1.2</version>
<version>3.2.1</version>
<url>https://github.com/openapitools/openapi-generator</url>
<scm>
<connection>scm:git:git@github.com:openapitools/openapi-generator.git</connection>
@@ -607,6 +607,55 @@
<module>samples/server/petstore/jaxrs/jersey1</module>
</modules>
</profile>
<profile>
<!-- openapi v3's one -->
<id>jaxrs-jersey</id>
<activation>
<property>
<name>env</name>
<value>java</value>
</property>
</activation>
<modules>
<module>samples/server/petstore/jaxrs-jersey</module>
</modules>
</profile>
<profile>
<id>jaxrs-spec</id>
<activation>
<property>
<name>env</name>
<value>java</value>
</property>
</activation>
<modules>
<module>samples/server/petstore/jaxrs-spec</module>
</modules>
</profile>
<profile>
<id>jaxrs-spec-interface</id>
<activation>
<property>
<name>env</name>
<value>java</value>
</property>
</activation>
<modules>
<module>samples/server/petstore/jaxrs-spec-interface</module>
</modules>
</profile>
<profile>
<id>jaxrs-spec-interface-response</id>
<activation>
<property>
<name>env</name>
<value>java</value>
</property>
</activation>
<modules>
<module>samples/server/petstore/jaxrs-spec-interface-response</module>
</modules>
</profile>
<profile>
<id>typescript-fetch-client-tests-default</id>
<activation>
@@ -853,6 +902,10 @@
<module>samples/client/petstore/java/google-api-client</module>
<module>samples/client/petstore/kotlin/</module>
<!-- servers -->
<module>samples/server/petstore/jaxrs-jersey</module>
<module>samples/server/petstore/jaxrs-spec</module>
<module>samples/server/petstore/jaxrs-spec-interface</module>
<module>samples/server/petstore/jaxrs-spec-interface-response</module>
<module>samples/server/petstore/java-vertx/rx</module>
<module>samples/server/petstore/java-vertx/async</module>
<module>samples/server/petstore/java-inflector</module>
@@ -876,7 +929,6 @@
<module>samples/server/petstore/jaxrs-cxf-cdi</module>
<module>samples/server/petstore/jaxrs-cxf-non-spring-app</module>
<module>samples/server/petstore/java-msf4j</module>
<module>samples/server/petstore/jaxrs-spec-interface</module>
</modules>
</profile>
</profiles>
@@ -948,7 +1000,7 @@
</repository>
</repositories>
<properties>
<swagger-parser-version>2.0.1</swagger-parser-version>
<swagger-parser-version>2.0.2-OpenAPITools.org-1</swagger-parser-version>
<swagger-core-version>2.0.1</swagger-core-version>
<scala-version>2.11.1</scala-version>
<felix-version>3.3.0</felix-version>

View File

@@ -9,7 +9,7 @@
<artifactId>openapi-generator-project</artifactId>
<packaging>pom</packaging>
<name>openapi-generator-project</name>
<version>3.1.2</version>
<version>3.2.1</version>
<url>https://github.com/openapitools/openapi-generator</url>
<scm>
<connection>scm:git:git@github.com:openapitools/openapi-generator.git</connection>
@@ -928,7 +928,7 @@
</repository>
</repositories>
<properties>
<swagger-parser-version>2.0.1</swagger-parser-version>
<swagger-parser-version>2.0.2-OpenAPITools.org-1</swagger-parser-version>
<swagger-core-version>2.0.1</swagger-core-version>
<scala-version>2.11.1</scala-version>
<felix-version>3.3.0</felix-version>

View File

@@ -14,8 +14,9 @@ COPY ./LICENSE ${GEN_DIR}
COPY ./google_checkstyle.xml ${GEN_DIR}
# Modules are copied individually here to allow for caching of docker layers between major.minor versions
# NOTE: openapi-generator-online is not included here
COPY ./modules/openapi-generator-gradle-plugin ${GEN_DIR}/modules/openapi-generator-gradle-plugin
COPY ./modules/openapi-generator-maven-plugin ${GEN_DIR}/modules/openapi-generator-maven-plugin
COPY ./modules/openapi-generator-online ${GEN_DIR}/modules/openapi-generator-online
COPY ./modules/openapi-generator-cli ${GEN_DIR}/modules/openapi-generator-cli
COPY ./modules/openapi-generator ${GEN_DIR}/modules/openapi-generator
COPY ./pom.xml ${GEN_DIR}

View File

@@ -2,16 +2,11 @@
<div align="center">
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`3.1.2`): [![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/master.svg?label=Integration%20Test)](https://travis-ci.org/OpenAPITools/openapi-generator)
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`3.2.2`): [![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/master.svg?label=Integration%20Test)](https://travis-ci.org/OpenAPITools/openapi-generator)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Run Status](https://api.shippable.com/projects/5af6bf74e790f4070084a115/badge?branch=master)](https://app.shippable.com/github/OpenAPITools/openapi-generator)
[![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=master&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator-wh2wu)
[`3.2.x`](https://github.com/OpenAPITools/openapi-generator/tree/3.2.x) branch: [![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/3.2.x.svg?label=Integration%20Test)](https://travis-ci.org/OpenAPITools/openapi-generator)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator/tree/3.2.x.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Run Status](https://api.shippable.com/projects/5af6bf74e790f4070084a115/badge?branch=3.2.x)](https://app.shippable.com/github/OpenAPITools/openapi-generator)
[![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=3.2.x&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator-wh2wu)
[`4.0.x`](https://github.com/OpenAPITools/openapi-generator/tree/4.0.x) branch: [![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/4.0.x.svg?label=Integration%20Test)](https://travis-ci.org/OpenAPITools/openapi-generator)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator/tree/4.0.x.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Run Status](https://api.shippable.com/projects/5af6bf74e790f4070084a115/badge?branch=4.0.x)](https://app.shippable.com/github/OpenAPITools/openapi-generator)
@@ -88,10 +83,13 @@ The OpenAPI Specification has undergone 3 revisions since initial creation in 20
OpenAPI Generator Version | Release Date | OpenAPI Spec compatibility | Notes
---------------------------- | ------------ | -------------------------- | -----
4.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/4.0.0-SNAPSHOT/)| TBD | 1.0, 1.1, 1.2, 2.0, 3.0 | Major release with breaking changes (no fallback)
3.2.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/3.2.0-SNAPSHOT/)| TBD | 1.0, 1.1, 1.2, 2.0, 3.0 | Minor release with breaking changes (with fallbacks)
3.3.0 (upcoming minor release)| TBD | 1.0, 1.1, 1.2, 2.0, 3.0 | Minor release (breaking changes with fallbacks)
3.2.2 (current master, upcoming patch release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/3.2.2-SNAPSHOT/)| TBD | 1.0, 1.1, 1.2, 2.0, 3.0 | Bugfix release
[3.2.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.2.1) | 14.08.2018 | 1.0, 1.1, 1.2, 2.0, 3.0 | Bugfix release
[3.2.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.2.0) | 06.08.2018 | 1.0, 1.1, 1.2, 2.0, 3.0 | Bugfix release
[3.1.2](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.1.2) | 25.07.2018 | 1.0, 1.1, 1.2, 2.0, 3.0 | Bugfix release
[3.1.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.1.1) | 18.07.2018 | 1.0, 1.1, 1.2, 2.0, 3.0 | Bugfix release
[3.1.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.1.0) | 06.07.2018 | 1.0, 1.1, 1.2, 2.0, 3.0 | Minor release with breaking changes (with fallbacks)
[3.1.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.1.0) | 06.07.2018 | 1.0, 1.1, 1.2, 2.0, 3.0 | Minor release (breaking changes with fallbacks)
[3.0.3](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.0.3) | 27.06.2018 | 1.0, 1.1, 1.2, 2.0, 3.0 | Bugfix release
[3.0.2](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.0.2) | 18.06.2018 | 1.0, 1.1, 1.2, 2.0, 3.0 | Bugfix release
[3.0.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.0.1) | 11.06.2018 | 1.0, 1.1, 1.2, 2.0, 3.0 | Bugfix release
@@ -147,16 +145,16 @@ See the different versions of the [openapi-generator-cli](https://mvnrepository.
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 8 runtime at a minimum):
JAR location: `http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.1.2/openapi-generator-cli-3.1.2.jar`
JAR location: `http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.2.1/openapi-generator-cli-3.2.1.jar`
For **Mac/Linux** users:
```sh
wget http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.1.2/openapi-generator-cli-3.1.2.jar -O openapi-generator-cli.jar
wget http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.2.1/openapi-generator-cli-3.2.1.jar -O openapi-generator-cli.jar
```
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
```
Invoke-WebRequest -OutFile openapi-generator-cli.jar http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.1.2/openapi-generator-cli-3.1.2.jar
Invoke-WebRequest -OutFile openapi-generator-cli.jar http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.2.1/openapi-generator-cli-3.2.1.jar
```
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
@@ -177,7 +175,7 @@ An example of setting this up (NOTE: Always evaluate scripts curled from externa
```
mkdir -p ~/bin/openapitools
curl https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/bin/utils/openapi-generator.cli.sh > ~/bin/openapitools/openapi-generator-cli
curl https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/bin/utils/openapi-generator-cli.sh > ~/bin/openapitools/openapi-generator-cli
chmod u+x ~/bin/openapitools/openapi-generator-cli
export PATH=$PATH:~/bin/openapitools/
```
@@ -322,6 +320,20 @@ Once built, `run-in-docker.sh` will act as an executable for openapi-generator-c
-g go -o /gen/out/go-petstore -DpackageName=petstore # generates go client, outputs locally to ./out/go-petstore
```
##### Troubleshooting
If an error like this occurs, just execute the **mvn clean install -U** command:
> org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test (default-test) on project openapi-generator: A type incompatibility occurred while executing org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test: java.lang.ExceptionInInitializerError cannot be cast to java.io.IOException
```sh
./run-in-docker.sh mvn clean install -U
```
> Failed to execute goal org.fortasoft:gradle-maven-plugin:1.0.8:invoke (default) on project openapi-generator-gradle-plugin-mvn-wrapper: org.gradle.tooling.BuildException: Could not execute build using Gradle distribution 'https://services.gradle.org/distributions/gradle-4.7-bin.zip'
Right now: no solution for this one :|
#### Run Docker in Vagrant
Prerequisite: install [Vagrant](https://www.vagrantup.com/downloads.html) and [VirtualBox](https://www.virtualbox.org/wiki/Downloads).
```sh
@@ -550,6 +562,7 @@ Here is a list of template creators:
* Ada: @stcarrez
* C# ASP.NET5: @jimschubert
* C# NancyFX: @mstefaniuk
* C++ (Qt5 QHttpEngine): @etherealjoy
* C++ Pistache: @sebymiano
* C++ Restbed: @stkrwork
* Erlang Server: @galaxie
@@ -565,6 +578,7 @@ Here is a list of template creators:
* JAX-RS CXF (CDI): @nickcmaynard
* JAX-RS RestEasy (JBoss EAP): @jfiala
* Kotlin: @jimschubert
* PHP Laravel: @renepardon
* PHP Lumen: @abcsun
* PHP Slim: @jfastnacht
* PHP Symfony: @ksm2

View File

@@ -35,6 +35,8 @@ build_script:
# install openapi-generator locally
- mvn clean install --quiet
test_script:
# restore test-related files
- copy /b/v/y CI\samples.ci\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj samples\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
# test c# API client
- nunit-console samples\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\bin\Debug\Org.OpenAPITools.Test.dll --result=myresults.xml;format=AppVeyor
# test c# API client (with PropertyChanged)
@@ -42,6 +44,10 @@ test_script:
# generate all petstore clients
- .\bin\windows\run-all-petstore.cmd
# generate all petstore clients (openapi3)
- .\bin\openapi3\windows\run-all-petstore.cmd
cache:
- C:\maven\
- C:\Users\appveyor\.m2

View File

@@ -0,0 +1,32 @@
#!/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
# 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/cpp-qt5-qhttpengine-server -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g cpp-qt5-qhttpengine-server -o samples/server/petstore/cpp-qt5-qhttpengine-server $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -29,8 +29,9 @@ fi
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g csharp -o samples/client/petstore/csharp/OpenAPIClient --additional-properties packageGuid={321C8C3F-0156-40C1-AE42-D59761FB9B6C} $@"
java $JAVA_OPTS -jar $executable $ags
# restore csproj file
echo "restore csproject file: CI/samples/client/petstore/csharp/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj"
cp ./CI/samples/client/petstore/csharp/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj ./samples/client/petstore/csharp/OpenAPIClient/src/Org.OpenAPITools.Test/
cp ./CI/samples.ci/client/petstore/csharp/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj ./samples/client/petstore/csharp/OpenAPIClient/src/Org.OpenAPITools.Test/
java $JAVA_OPTS -jar $executable $ags

View File

@@ -27,6 +27,6 @@ fi
# 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 -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g dynamic-html -o samples/dynamic-html $@"
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g dynamic-html -o samples/documentation/dynamic-html $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -27,6 +27,6 @@ fi
# 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 -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g elm -o samples/client/petstore/elm $@"
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g elm -t modules/openapi-generator/src/main/resources/elm -o samples/client/petstore/elm $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -27,6 +27,6 @@ fi
# 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 -i modules/openapi-generator/src/test/resources/2_0/markdown.yaml -g html -o samples/html.md $@"
ags="generate -i modules/openapi-generator/src/test/resources/2_0/markdown.yaml -g html -o samples/documentation/html.md $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -27,6 +27,6 @@ fi
# 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 -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g html -o samples/html $@"
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g html -o samples/documentation/html $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -27,6 +27,6 @@ fi
# 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 -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g html2 -o samples/html2 --additional-properties hideGenerationTimestamp=true $@"
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g html2 -o samples/documentation/html2 --additional-properties hideGenerationTimestamp=true $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -27,7 +27,7 @@ fi
# 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 --artifact-id petstore-java-client-jersey1 -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -o samples/client/petstore/java/jersey1 -DhideGenerationTimestamp=true --library=jersey1 $@"
ags="generate --artifact-id petstore-java-client-jersey1 -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -o samples/client/petstore/java/jersey1 -DhideGenerationTimestamp=true --library=jersey1 --additional-properties useNullForUnknownEnumValue=true $@"
echo "Removing files and folders under samples/client/petstore/java/jersey1/src/main"
rm -rf samples/client/petstore/java/jersey1/src/main

View File

@@ -1,4 +1,7 @@
{
"library": "jersey2",
"artifactId": "petstore-jersey2"
"artifactId": "petstore-jersey2",
"additionalProperties" : {
"useNullForUnknownEnumValue" : true
}
}

View File

@@ -0,0 +1,32 @@
#!/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 clean package
fi
# 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/cpp-qt5-qhttpengine-server -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g cpp-qt5-qhttpengine-server -o samples/client/petstore/cpp-qt5-qhttpengine-server $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -27,6 +27,6 @@ fi
# 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 $@ -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -g csharp -o samples/client/petstore/csharp/OpenAPIClient --additional-properties packageGuid={321C8C3F-0156-40C1-AE42-D59761FB9B6C}"
ags="generate $@ -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -g csharp -o samples/openapi3/client/petstore/csharp/OpenAPIClient --additional-properties packageGuid={321C8C3F-0156-40C1-AE42-D59761FB9B6C}"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -0,0 +1,32 @@
#!/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 clean package
fi
# 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 --artifact-id "openapiv3-jaxrs-jersey-petstore-server" -t modules/openapi-generator/src/main/resources/JavaJaxRS/ -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g jaxrs-jersey -o samples/server/petstore/jaxrs-jersey $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -0,0 +1,42 @@
#!/bin/bash
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
# Make sure that the working directory is the root dir
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "${SCRIPT_DIR}/../"
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
# Make sure that we are regenerating the sample by removing any existing target directory
TARGET_DIR="$SCRIPT_DIR/../../samples/server/petstore/php-laravel"
if [ -d "$TARGET_DIR" ]; then
rm -rf $TARGET_DIR
fi
executable="$SCRIPT_DIR/../../modules/openapi-generator-cli/target/openapi-generator-cli.jar"
if [ ! -f "$executable" ]
then
mvn clean package
fi
# 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 $SCRIPT_DIR/../../modules/openapi-generator/src/main/resources/php-laravel -i $SCRIPT_DIR/../../modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g php-laravel -o $TARGET_DIR $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -33,6 +33,6 @@ fi
# 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/php -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -g php -o samples/openapi3/client/petstore/php $@"
ags="generate -t modules/openapi-generator/src/main/resources/php -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -g php -o samples/openapi3/client/petstore/php/OpenAPIClient-php $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -27,6 +27,6 @@ fi
# 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/php-silex -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g php-silex -o samples/server/petstore/php-silex $@"
ags="generate -t modules/openapi-generator/src/main/resources/php-silex -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g php-silex -o samples/server/petstore/php-silex/OpenAPIServer $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -23,7 +23,7 @@ if [ ! -d "${APP_DIR}" ]; then
fi
# Make sure that we are regenerating the sample by removing any existing target directory
TARGET_DIR="$SCRIPT_DIR/../../samples/server/petstore/php-symfony"
TARGET_DIR="$SCRIPT_DIR/../../samples/server/petstore/php-symfony/SymfonyBundle-php"
if [ -d "$TARGET_DIR" ]; then
rm -rf $TARGET_DIR
fi

33
bin/openapi3/run-all-petstore Executable file
View File

@@ -0,0 +1,33 @@
#!/bin/bash
# this bash script will loop through all the .sh files under bin
# execute the script and check the result (exit code) to see if
# there's any error
echo "IMPORTANT: this script should be run by the CI (e.g. Shippable) only. There's no need to run this script to update Petstore samples for all generators."
echo "Please press CTRL+C to stop or the script will continue in 10 seconds."
sleep 10
successes=0
failures=0
for SCRIPT in $(ls -l ./bin/openapi3/*.sh | grep -v all)
do
if [ -f ${SCRIPT} -a -x ${SCRIPT} ]; then
echo "Running $SCRIPT (output to /dev/null)"
${SCRIPT} 2>&1 > /dev/null
rc=$?
if [[ ${rc} != 0 ]]; then
>&2 echo "ERROR!! FAILED TO RUN ${SCRIPT}"
((failures+=1))
else
((successes+=1))
fi
fi
done
if (( failures > 0 )); then
>&2 echo "[ERROR] ${failures} out of $((failures+successes)) scripts failed."
exit 1
else
echo "[SUCCESS] ${successes} generators finished."
fi

View File

@@ -0,0 +1,14 @@
set executable=.\modules\openapi-generator-cli\target\openapi-generator-cli.jar
If Not Exist %executable% (
mvn clean package
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\openapi-generator\src\test/resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g csharp -o samples\openapi3\client\petstore\csharp\SwaggerClient --additional-properties packageGuid={321C8C3F-0156-40C1-AE42-D59761FB9B6C}
java %JAVA_OPTS% -jar %executable% %ags%
REM restore csproj file
echo "restore csproject file: CI\samples.ci\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj"
copy /b/v/y CI\samples.ci\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj samples\openapi3\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\

View File

@@ -0,0 +1,15 @@
REM this batch file will loop through all the .bat files under bin\openapi3\windows\
REM execute the script and check the error level to see if there's any error
echo IMPORTANT: this script should be run by the CI (e.g. appveyor) only. There's no need to run this script to update Petstore samples for all generators.
echo Please press CTRL+C to stop or the script will continue in 10 seconds.
timeout 10
for /f "delims=" %%i in ('dir /b ".\bin\openapi3\windows\*.bat"') do (
CALL .\bin\openapi3\windows\%%i
IF ERRORLEVEL 1 IF NOT ERRORLEVEL 2 exit /b 1
)

View File

@@ -0,0 +1,32 @@
#!/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
# 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/php-laravel -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g php-laravel -o samples/server/petstore/php-laravel $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -33,6 +33,6 @@ fi
# 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/php -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g php -o samples/client/petstore/php $@"
ags="generate -t modules/openapi-generator/src/main/resources/php -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g php -o samples/client/petstore/php/OpenAPIClient-php $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -27,6 +27,6 @@ fi
# 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/php-silex -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g php-silex -o samples/server/petstore/php-silex $@"
ags="generate -t modules/openapi-generator/src/main/resources/php-silex -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g php-silex -o samples/server/petstore/php-silex/OpenAPIServer $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -23,7 +23,7 @@ if [ ! -d "${APP_DIR}" ]; then
fi
# Make sure that we are regenerating the sample by removing any existing target directory
TARGET_DIR="$SCRIPT_DIR/../samples/server/petstore/php-symfony"
TARGET_DIR="$SCRIPT_DIR/../samples/server/petstore/php-symfony/SymfonyBundle-php"
if [ -d "$TARGET_DIR" ]; then
rm -rf $TARGET_DIR
fi

View File

@@ -13,8 +13,8 @@ failures=0
for SCRIPT in $(ls -l ./bin/*.sh | grep -v all)
do
if [ -f ${SCRIPT} -a -x ${SCRIPT} ]; then
echo "Running $SCRIPT"
${SCRIPT}
echo "Running $SCRIPT (output to /dev/null)"
${SCRIPT} 2>&1 > /dev/null
rc=$?
if [[ ${rc} != 0 ]]; then
>&2 echo "ERROR!! FAILED TO RUN ${SCRIPT}"
@@ -30,4 +30,4 @@ if (( failures > 0 )); then
exit 1
else
echo "[SUCCESS] ${successes} generators finished."
fi
fi

View File

@@ -25,8 +25,10 @@ then
mvn -B clean package
fi
# 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/rust-server -i modules/openapi-generator/src/test/resources/2_0/rust-server/petstore-with-fake-endpoints-models-for-testing.yaml -g rust-server -o samples/server/petstore/rust-server -DpackageName=petstore_api --additional-properties hideGenerationTimestamp=true $@"
for spec_path in modules/openapi-generator/src/test/resources/2_0/rust-server/* ; do
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
spec=$(basename "$spec_path" | sed 's/.yaml//')
ags="generate -t modules/openapi-generator/src/main/resources/rust-server -i $spec_path -g rust-server -o samples/server/petstore/rust-server/output/$spec -DpackageName=$spec --additional-properties hideGenerationTimestamp=true $@"
java $JAVA_OPTS -jar $executable $ags
java $JAVA_OPTS -jar $executable $ags
done

View File

@@ -30,7 +30,8 @@ sleep 5
./bin/typescript-node-petstore-all.sh > /dev/null 2>&1
./bin/typescript-inversify-petstore.sh > /dev/null 2>&1
./bin/rust-server-petstore.sh > /dev/null 2>&1
./bin/openapi3/haskell-http-client-petstore.sh > /dev/null 2>&1
./bin/csharp-petstore.sh > /dev/null 2>&1
# Check:
if [ -n "$(git status --porcelain)" ]; then

View File

@@ -40,16 +40,13 @@ declare -a files=("CI/pom.xml.bash"
"CI/pom.xml.circleci.java7"
"CI/pom.xml.ios"
"modules/openapi-generator-cli/pom.xml"
"modules/openapi-generator-gradle-plugin/README.adoc"
"modules/openapi-generator-gradle-plugin/gradle.properties"
"modules/openapi-generator-gradle-plugin/pom.xml"
"modules/openapi-generator-gradle-plugin/samples/local-spec/build.gradle"
"modules/openapi-generator-maven-plugin/pom.xml"
"modules/openapi-generator-online/pom.xml"
"modules/openapi-generator/pom.xml"
"modules/openapi-generator-online/Dockerfile"
"pom.xml"
"README.md")
"pom.xml")
for filename in "${files[@]}"; do
# e.g. sed -i '' "s/3.0.1-SNAPSHOT/3.0.1/g" CI/pom.xml.bash

View File

@@ -0,0 +1,57 @@
#!/bin/bash
#
# usage: ./bin/utils/release_version_update.sh 3.0.1-SNAPSHOT 3.0.1
#
# 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.
#
if [[ "$1" != "" ]]; then
FROM="$1"
else
echo "Missing argument. Usage e.g.: ./bin/utils/release_version_update.sh 3.0.1-SNAPSHOT 3.0.1"
exit 1;
fi
if [[ "$2" != "" ]]; then
TO="$2"
else
echo "Missing argument. Usage e.g.: ./bin/utils/release_version_update.sh 3.0.1-SNAPSHOT 3.0.1"
exit 1;
fi
echo "IMPORTANT: this script works on Mac only"
echo "Release preparation: replacing $FROM with $TO in different files"
declare -a files=("modules/openapi-generator-maven-plugin/README.md"
"modules/openapi-generator-maven-plugin/examples/java-client.xml"
"modules/openapi-generator-maven-plugin/examples/non-java-invalid-spec.xml"
"modules/openapi-generator-maven-plugin/examples/non-java.xml"
"modules/openapi-generator-gradle-plugin/README.adoc"
"modules/openapi-generator-gradle-plugin/samples/local-spec/gradle.properties"
"modules/openapi-generator-gradle-plugin/samples/local-spec/build.gradle"
"modules/openapi-generator-gradle-plugin/samples/local-spec/README.md"
"README.md")
for filename in "${files[@]}"; do
# e.g. sed -i '' "s/3.0.1-SNAPSHOT/3.0.1/g" CI/pom.xml.bash
#echo "Running command: sed -i '' "s/$FROM/$TO/g" $filename"
if sed -i '' "s/$FROM/$TO/g" $filename; then
echo "Updated $filename successfully!"
else
echo "ERROR: Failed to update $filename with the following command"
echo "sed -i '' \"s/$FROM/$TO/g\" $filename"
fi
done

View File

@@ -0,0 +1,10 @@
set executable=.\modules\openapi-generator-cli\target\openapi-generator-cli.jar
If Not Exist %executable% (
mvn clean package
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g cpp-qt5-qhttpengine-server -o samples\server\petstore\cpp-qt5-qhttpengine-server
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g csharp -o samples/client/petstore/csharp/SwaggerClientNet40 --additional-properties packageGuid={321C8C3F-0156-40C1-AE42-D59761FB9B6C} -c ./bin/csharp-petstore-net-40.json
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g csharp -o samples\client\petstore\csharp\SwaggerClientNet40 --additional-properties packageGuid={321C8C3F-0156-40C1-AE42-D59761FB9B6C} -c .\bin\csharp-petstore-net-40.json
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g csharp -o samples\client\petstore\csharp\SwaggerClientNetStandard --additional-properties targetFramework=v5.0,packageGuid={3AB1F259-1769-484B-9411-84505FCCBD55}
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g csharp -o samples\client\petstore\csharp\SwaggerClientNetStandard --additional-properties targetFramework=v5.0,packageGuid={3AB1F259-1769-484B-9411-84505FCCBD55}
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -9,7 +9,7 @@ set ags=generate -i modules\openapi-generator\src\test/resources\2_0\petstore-wi
java %JAVA_OPTS% -jar %executable% %ags%
# restore csproj file
echo "restore csproject file: CI\samples\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj"
copy .\CI\samples\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj .\samples\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\
REM restore csproj file
echo "restore csproject file: CI\samples.ci\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj"
copy /b/v/y CI\samples.ci\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj samples\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\

View File

@@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -DloggerPath=conf/log4j.properties
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g html -o samples\client\petstore\html
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g html -o samples\documentation\html
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -DloggerPath=conf/log4j.properties
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g html2 -o samples\html2
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g html2 -o samples\documentation\html2
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g php -o samples\client\petstore\php
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g php -o samples\client\petstore\php\OpenAPIClient-php
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g php-silex -o samples\server\petstore\php-silex
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g php-silex -o samples\server\petstore\php-silex\OpenAPIServer
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g php-symfony -o samples\server\petstore\php-symfony
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g php-symfony -o samples\server\petstore\php-symfony\SymfonyBundle-php
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -11,6 +11,42 @@ Another approach to find breaking changes is to look at issue and pull requests
* link:https://github.com/OpenAPITools/openapi-generator/labels/Breaking%20change%20%28with%20fallback%29[Breaking change (with fallback)]
* link:https://github.com/OpenAPITools/openapi-generator/labels/Breaking%20change%20%28without%20fallback%29[Breaking change (without fallback)]
=== From 3.1.x to 3.2.0
Version `3.2.0` is a minor version of OpenAPI-Generator, in comparison to `3.1.x` it contains some breaking changes, but with the possibility to fallback to the old behavior.
The default value of some options might change.
Projects relying on generated code might need to be adapted.
==== Validate spec on generation by default
The default is to validate the spec during generation. If the spec has errors,
they will appear as errors or warnings to the user. This prevent generation of the project.
If you want to switch back to the `3.1.x` behavior you can use:
* Set the `validateSpec` option to `false` if you are using the Maven or Gradle plugin
* Use the command line option `--skip-validate-spec` if you are using the CLI
==== Model (all languages)
In `CodegenModel` and in `CodegenOperation` we use now our own class `org.openapitools.codegen.CodegenDiscriminator` instead of `io.swagger.v3.oas.models.media.Discriminator`.
For the templates, this is not an API change, because the same values are available.
If you have your own `Codegen` class (to support your own generator for example) then you might get some compile error due to the change.
==== Java
Schema with enum values are mapped to java enum in the generated code.
In previous version, when an unknown value was deserialized, the value was set to `null`.
With `3.2.0` a new option is introduced: `useNullForUnknownEnumValue`.
* When set to `false` (default value), an Exception (`IllegalArgumentException`) is thrown when the value not available in the enum.
* When set to `true`, unknown values are mapped to `null` as it was the case in previous versions.
=== From 3.0.x to 3.1.0
Version `3.1.0` is the first minor version of OpenAPI-Generator, in comparison to `3.0.3` it contains some breaking changes, but with the possibility to fallback to the old behavior.

View File

@@ -2,41 +2,40 @@
#### What is the governance structure of the OpenAPI Generator project?
OpenAPI generator (openapi-generator) is managed by the [core team members](../README.md#openapi-generator-core-team).
OpenAPI generator (openapi-generator) is managed by the members of the [core team](../README.md#openapi-generator-core-team).
#### What is the difference between Swagger Codegen and OpenAPI Generator?
Swagger Codegen is driven by SmartBear while OpenAPI Generator is driven by the community. More than 40 top contributors and template creators of Swagger Codegen have joined OpenAPI Generator as the founding team members.
Swagger is a trademark owned by SmartBear and the use of the term "Swagger" in this project is for demo (reference) purposes only.
#### Why was it decided to fork Swagger Codegen and to maintain a community-driven version?
There are several reasons:
1. The founding members came to the conclusion that Swagger Codegen 3.0.0 beta contains too many breaking changes while they strongly believe 3.0.0 release should only focus on one thing: OpenAPI specification 3.0 support.
1. Swagger Codegen 3.0.0 beta was evaluated as unstable. Changes made directly to 3.0.0 branch without reviews or tests, were breaking the builds from time to time (e.g. a simple `mvn clean package` failed).
1. Reviews of code changes in the 3.0.0 branch highlighted a lot of code block removal without any reason. This might produce regressions for edge cases discovered previously.
1. Most of the test cases in the generators have been commented out as part of the migration to support OpenAPI 3.0. Test cases are the most valuable assets of the project and should be maintained to ensure a good quality.
1. According to SmartBear, [Swagger Codegen 2.x and 3.x should be supported in parallel for a while](https://github.com/swagger-api/swagger-codegen/issues/7754#issuecomment-375039048) without the possibility to work with git branches to merge the fixes from one branch to the next. Having to implement everything twice is not a good idea and the best use of the Swagger Codegen community resources.
1. Having a community-driven version can bring the project to the next level.
1. The founding members came to the conclusion that Swagger Codegen 3.0.0 beta contains too many breaking changes. They also strongly believe the 3.0.0 release should only focus on one thing: OpenAPI 3.0 support.
1. The founding members had concerns about the development practices, which seemed to be contributing to an unstable and insufficiently tested codebase.
1. There was a disagreement on the evolutionary strategy for Swagger Codegen. The founding members felt it was important to move forward with OpenAPI 3.0 support, while maintaining backward compatibility with OpenAPI 2.0 in the same codebase.
1. The founding members found that the enhancements and bug fixes submitted for Swagger Codegen 2.x need to be submitted again for Swagger Codegen 3.0.0 branch (otherwise, these changes would not appear in the 3.0.0 branch. Having to do the pull request twice is not the best use of community resources).
1. The community-driven version has a more rapid [release cycle](https://github.com/OpenAPITools/openapi-generator/releases/) (weekly patch release, monthly minor release) so users do not need to wait for several months to get a stable release.
1. Having a community-driven version _can_ bring the project to the next level with reliable releases and a clear [roadmap](https://github.com/OpenAPITools/openapi-generator/blob/master/docs/roadmap.adoc).
UPDATE: After the public launch of OpenAPI Generator, some of the core team members were contacted by Ron (SmartBear) and we explained to him the reasons of the fork as explained above. We also asked him to contact team@openapitools.org if he wants to discuss further but so far we don't see any email from him to team@openapitools.org.
#### Was anything done to attempt to address the issues before deciding to fork Swagger Codegen and maintain a community-driven version?
#### Has anything been done in attempt to address the issues before deciding to fork Swagger Codegen and maintain a community-driven version?
There were several conversations with SmartBear (Ron, Hugo) via emails, gitter, Skype call and GitHub issues.
There were several conversations with the project owners of Swagger Codegen via emails, Gitter, Skype call and GitHub issues to discuss the state of Swagger Codegen 3.0.0.
But there was no consensus on the next steps and on the direction for Swagger Codegen 3.0.0.
#### Is there any change to the project license?
#### Are there any changes to the project license?
No, OpenAPI Generator is still using [Apache license (version 2)](https://www.apache.org/licenses/LICENSE-2.0).
No, OpenAPI Generator is still using the [Apache license (version 2)](https://www.apache.org/licenses/LICENSE-2.0).
#### What is the difference between Swagger Codegen and OpenAPI Generator?
#### I am currently using Swagger Codegen 2.x. How can I upgrade the generator to OpenAPI Generator?
Swagger Codegen is driven by SmartBear while OpenAPI Generator is driven by the community. More than 40 top contributors and template creators of Swagger Codegen have joined OpenAPI Generator as the founding team members.
OpenAPI Generator is based on Swagger Codegen `2.4.0-SNAPSHOT` version so the migration should be relatively straightforward. Refer to the [migration guide](migration-from-swagger-codegen.md) for more information.
Swagger is a trademark owned by SmartBear and the use of the term "Swagger" found in this project is for demo purpose (reference) only.
#### Who maintains this Q&A page?
#### Im currently using Swagger Codegen 2.x. How can I upgrade the generator to OpenAPI Generator?
OpenAPI Generator is based on Swagger Codegen 2.4.0-SNAPSHOT version so the migration should be easy, straightforward and almost seamless. Please refer to the [migration guide](migration-from-swagger-codegen.md) for more information.
#### May I know who maintains this Q&A page?
This Q&A page is maintained by the [core team members](../README.md#openapi-generator-core-team). It's not maintained by a single person nor do these Q&As represent the view of an individual.
This Q&A page is maintained by the [core team members](../README.md#openapi-generator-core-team). It is not maintained by a single person nor do these Q&As represent the views of any individual or person.

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<version>3.1.2</version>
<version>3.2.1</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -72,4 +72,4 @@ public class ConfigHelp implements Runnable {
System.exit(1);
}
}
}
}

View File

@@ -194,6 +194,11 @@ public class Generate implements Runnable {
description = CodegenConstants.REMOVE_OPERATION_ID_PREFIX_DESC)
private Boolean removeOperationIdPrefix;
@Option(name = {"--skip-validate-spec"},
title = "skip spec validation",
description = "Skips the default behavior of validating an input specification.")
private Boolean skipValidateSpec;
@Override
public void run() {
@@ -207,6 +212,10 @@ public class Generate implements Runnable {
}
// now override with any specified parameters
if (skipValidateSpec != null) {
configurator.setValidateSpec(false);
}
if (verbose != null) {
configurator.setVerbose(verbose);
}

View File

@@ -34,7 +34,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath "org.openapitools:openapi-generator-gradle-plugin:3.1.2"
classpath "org.openapitools:openapi-generator-gradle-plugin:3.2.1"
}
}
@@ -59,6 +59,11 @@ The gradle plugin is not currently published to https://plugins.gradle.org/m2/.
|false
|The verbosity of generation
|validateSpec
|Boolean
|true
|Whether or not we should validate the input spec before generation. Invalid specs result in an error.
|generatorName
|String
|None

View File

@@ -1,4 +1,4 @@
openApiGeneratorVersion=3.1.2
openApiGeneratorVersion=3.2.1
# BEGIN placeholders
# these are just placeholders to allow contributors to build directly

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<version>3.1.2</version>
<version>3.2.1</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -11,10 +11,11 @@ gradle openApiGenerate
gradle openApiMeta
gradle openApiValidate
gradle buildGoSdk
gradle generateGoWithInvalidSpec
```
The samples can be tested against other versions of the plugin using the `openApiGeneratorVersion` property. For example:
```bash
gradle -PopenApiGeneratorVersion=3.1.2 openApiValidate
gradle -PopenApiGeneratorVersion=3.2.1 openApiValidate
```

View File

@@ -41,6 +41,9 @@ openApiGenerate {
configOptions = [
dateLibrary: "java8"
]
systemProperties = [
modelDocs: "false"
]
}
task buildGoSdk(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTask){
@@ -54,3 +57,16 @@ task buildGoSdk(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTas
dateLibrary: "threetenp"
]
}
task generateGoWithInvalidSpec(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTask){
validateSpec = true
generatorName = "go"
inputSpec = "$rootDir/petstore-v3.0-invalid.yaml".toString()
additionalProperties = [
packageName: "petstore"
]
outputDir = "$buildDir/go".toString()
configOptions = [
dateLibrary: "threetenp"
]
}

View File

@@ -1 +1 @@
openApiGeneratorVersion=3.1.2
openApiGeneratorVersion=3.2.1

View File

@@ -80,6 +80,7 @@ class OpenApiGeneratorPlugin : Plugin<Project> {
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)

View File

@@ -32,6 +32,11 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
*/
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)
*/
@@ -262,6 +267,11 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
val configOptions = project.objects.property<Map<String, String>>()
init {
applyDefaults()
}
@Suppress("MemberVisibilityCanBePrivate")
fun applyDefaults(){
releaseNote.set("Minor update")
modelNamePrefix.set("")
modelNameSuffix.set("")
@@ -271,5 +281,6 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
generateApiDocumentation.set(true)
withXml.set(false)
configOptions.set(mapOf())
validateSpec.set(true)
}
}

View File

@@ -28,7 +28,6 @@ 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.CodegenConfiguratorUtils.*
/**
@@ -48,6 +47,12 @@ open class GenerateTask : DefaultTask() {
@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)
*/
@@ -318,7 +323,7 @@ open class GenerateTask : DefaultTask() {
@get:Internal
val configOptions = project.objects.property<Map<String, String>>()
private val originalEnvironmentVariables = mutableMapOf<String, String>()
private val originalEnvironmentVariables = mutableMapOf<String, String?>()
private fun <T : Any?> Property<T>.ifNotEmpty(block: Property<T>.(T) -> Unit) {
if (isPresent) {
@@ -347,8 +352,9 @@ open class GenerateTask : DefaultTask() {
try {
if (systemProperties.isPresent) {
systemProperties.get().forEach { (key, value) ->
originalEnvironmentVariables[key] = System.getProperty(key)
System.setProperty(key, value)
// System.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] = System.setProperty(key, value)
configurator.addSystemProperty(key, value)
}
}
@@ -382,6 +388,10 @@ open class GenerateTask : DefaultTask() {
configurator.isVerbose = value
}
validateSpec.ifNotEmpty { value ->
configurator.isValidateSpec = value
}
skipOverwrite.ifNotEmpty { value ->
configurator.isSkipOverwrite = value ?: false
}
@@ -528,12 +538,15 @@ open class GenerateTask : DefaultTask() {
out.println("Successfully generated code to ${configurator.outputDir}")
} catch (e: RuntimeException) {
logger.error(e.message)
throw GradleException("Code generation failed.")
throw GradleException("Code generation failed.", e)
}
} finally {
originalEnvironmentVariables.forEach { entry ->
System.setProperty(entry.key, entry.value)
// Reset all modified system properties back to their original state
originalEnvironmentVariables.forEach {
when {
it.value == null -> System.clearProperty(it.key)
else -> System.setProperty(it.key, it.value)
}
}
originalEnvironmentVariables.clear()
}

View File

@@ -31,7 +31,7 @@ class GenerateTaskDslTest : TestBase() {
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-invalid.yaml")
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml")
)
withProject(defaultBuildGradle, projectFiles)

View File

@@ -11,7 +11,7 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase)
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.1.2</version>
<version>3.2.1</version>
<executions>
<execution>
<goals>
@@ -37,7 +37,10 @@ mvn clean compile
### General Configuration parameters
:bulb: These **general** configurations should be in the same level
- `inputSpec` - OpenAPI Spec file path
- `validateSpec` - Whether or not to validate the input spec prior to generation. Invalid specifications will result in an error.
- `language` - target generation language (deprecated, replaced by `generatorName` as values here don't represent only 'language' any longer)
- `generatorName` - target generator name
- `output` - target output path (default is `${project.build.directory}/generated-sources/swagger`)
@@ -48,7 +51,7 @@ mvn clean compile
- `invokerPackage` - the package to use for the generated invoker objects
- `modelNamePrefix` and `modelNameSuffix` - Sets the pre- or suffix for model classes and enums
- `withXml` - enable XML annotations inside the generated models and API (only works with Java `language` and libraries that provide support for JSON and XML)
- `configOptions` - a map of language-specific parameters (see below)
- `configOptions` - a map of language-specific parameters. To show a full list of generator-specified parameters (options), please use `configHelp` (explained below)
- `configHelp` - dumps the configuration help for the specified library (generates no sources)
- `ignoreFileOverride` - specifies the full path to a `.openapi-generator-ignore` used for pattern based overrides of generated outputs
- `generateApis` - generate the apis (`true` by default)
@@ -102,4 +105,8 @@ Specifying a custom generator is a bit different. It doesn't support the classpa
### Sample configuration
- Please see [an example configuration](examples) for using the plugin
Please see [an example configuration](examples) for using the plugin. To run these examples, explicitly pass the file to maven. Example:
```bash
mvn -f non-java.xml compile
```

View File

@@ -12,7 +12,7 @@
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.0.1-SNAPSHOT</version>
<version>3.2.1</version>
<executions>
<execution>
<goals>
@@ -20,7 +20,7 @@
</goals>
<configuration>
<!-- specify the swagger yaml -->
<inputSpec>swagger.yaml</inputSpec>
<inputSpec>${project.basedir}/swagger.yaml</inputSpec>
<!-- target to generate java client code -->
<generatorName>java</generatorName>
@@ -39,13 +39,22 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- dependencies are needed for the client being generated -->
<dependency>
<groupId>org.openapitools</groupId>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations-version}</version>
</dependency>
@@ -55,13 +64,8 @@
<!-- HTTP client: jersey-client -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
@@ -69,6 +73,11 @@
<artifactId>jersey-media-multipart</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey-version}</version>
</dependency>
<!-- JSON processing: jackson -->
<dependency>
@@ -96,7 +105,7 @@
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson-version}</version>
</dependency>
<!-- Joda time: if you use it -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
@@ -107,19 +116,19 @@
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${jodatime-version}</version>
</dependency>
</dependency>
<!-- Base64 encoding that works in both JVM and Android -->
<dependency>
<groupId>com.brsanthu</groupId>
<artifactId>migbase64</artifactId>
<version>2.2</version>
</dependency>
</dependency>
</dependencies>
<properties>
<swagger-annotations-version>1.5.8</swagger-annotations-version>
<jersey-version>2.22.2</jersey-version>
<jersey-version>2.27</jersey-version>
<jackson-version>2.8.9</jackson-version>
<jodatime-version>2.7</jodatime-version>
<maven-plugin-version>1.0.0</maven-plugin-version>

View File

@@ -0,0 +1,34 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.openapitools</groupId>
<artifactId>sample-project</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>sample-project</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<!-- activate the plugin -->
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<validateSpec>false</validateSpec>
<inputSpec>${project.basedir}/petstore-v3.0-invalid.yaml</inputSpec>
<generatorName>aspnetcore</generatorName>
<configOptions>
<additional-properties>optionalProjectFile=true</additional-properties>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -12,14 +12,14 @@
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.0.1-SNAPSHOT</version>
<version>3.2.1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>swagger.yaml</inputSpec>
<inputSpec>${project.basedir}/swagger.yaml</inputSpec>
<generatorName>aspnetcore</generatorName>
<configOptions>
<additional-properties>optionalProjectFile=true</additional-properties>

View File

@@ -0,0 +1,103 @@
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

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<version>3.1.2</version>
<version>3.2.1</version>
<relativePath>../..</relativePath>
</parent>
<artifactId>openapi-generator-maven-plugin</artifactId>

View File

@@ -60,6 +60,9 @@ public class CodeGenMojo extends AbstractMojo {
private static final Logger LOGGER = LoggerFactory.getLogger(CodeGenMojo.class);
@Parameter(name="validateSpec", required = false, defaultValue = "true")
private Boolean validateSpec;
@Parameter(name = "verbose", required = false, defaultValue = "false")
private boolean verbose;
@@ -348,6 +351,11 @@ public class CodeGenMojo extends AbstractMojo {
configurator.setVerbose(verbose);
// now override with any specified parameters
if (validateSpec != null) {
configurator.setValidateSpec(validateSpec);
}
if (skipOverwrite != null) {
configurator.setSkipOverwrite(skipOverwrite);
}

View File

@@ -2,7 +2,7 @@ FROM openjdk:8-jre-alpine
WORKDIR /generator
COPY target/openapi-generator-online-3.1.2.jar /generator/openapi-generator-online.jar
COPY target/openapi-generator-online-3.2.1.jar /generator/openapi-generator-online.jar
ENV GENERATOR_HOST=http://localhost

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<version>3.1.2</version>
<version>3.2.1</version>
<relativePath>../..</relativePath>
</parent>
<artifactId>openapi-generator-online</artifactId>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<version>3.1.2</version>
<version>3.2.1</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -204,9 +204,9 @@
<version>${swagger-core-version}</version>
</dependency>
<dependency>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser</artifactId>
<version>${swagger-parser-version}</version>
<groupId>org.openapitools.swagger.parser</groupId>
<artifactId>swagger-parser</artifactId>
<version>${swagger-parser-version}</version>
</dependency>
<dependency>
<groupId>com.samskivert</groupId>

View File

@@ -257,4 +257,8 @@ public class CodegenConstants {
public static final String DOCEXTENSION = "docExtension";
public static final String DOCEXTENSION_DESC = "The extension of the generated documentation files, defaults to markdown, .md";
public static final String DATABASE_ADAPTER = "databaseAdapter";
public static final String DATABASE_ADAPTER_DESC = "The adapter for database (e.g. mysql, sqlite). Default: sqlite";
}

View File

@@ -0,0 +1,88 @@
package org.openapitools.codegen;
import java.util.*;
public class CodegenDiscriminator {
private String propertyName;
private Map<String, String> mapping;
private Set<MappedModel> mappedModels = new LinkedHashSet<>();
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public Map<String, String> getMapping() {
return mapping;
}
public void setMapping(Map<String, String> mapping) {
this.mapping = mapping;
}
public Set<MappedModel> getMappedModels() {
return mappedModels;
}
public void setMappedModels(Set<MappedModel> mappedModels) {
this.mappedModels = mappedModels;
}
public static class MappedModel {
private String mappingName;
private String modelName;
public MappedModel(String mappingName, String modelName) {
this.mappingName = mappingName;
this.modelName = modelName;
}
public String getMappingName() {
return mappingName;
}
public void setMappingName(String mappingName) {
this.mappingName = mappingName;
}
public String getModelName() {
return modelName;
}
public void setModelName(String modelName) {
this.modelName = modelName;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MappedModel that = (MappedModel) o;
return Objects.equals(mappingName, that.mappingName) &&
Objects.equals(modelName, that.modelName);
}
@Override
public int hashCode() {
return Objects.hash(mappingName, modelName);
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CodegenDiscriminator that = (CodegenDiscriminator) o;
return Objects.equals(propertyName, that.propertyName) &&
Objects.equals(mapping, that.mapping) &&
Objects.equals(mappedModels, that.mappedModels);
}
@Override
public int hashCode() {
return Objects.hash(propertyName, mapping, mappedModels);
}
}

View File

@@ -18,15 +18,14 @@
package org.openapitools.codegen;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.media.Discriminator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.Objects;
public class CodegenModel {
public String parent, parentSchema;
@@ -40,7 +39,7 @@ public class CodegenModel {
public String name, classname, title, description, classVarName, modelJson, dataType, xmlPrefix, xmlNamespace, xmlName;
public String classFilename; // store the class file name, mainly used for import
public String unescapedDescription;
public Discriminator discriminator;
public CodegenDiscriminator discriminator;
public String defaultValue;
public String arrayModelType;
public boolean isAlias; // Is this effectively an alias of another simple type
@@ -349,7 +348,7 @@ public class CodegenModel {
this.unescapedDescription = unescapedDescription;
}
public Discriminator getDiscriminator() {
public CodegenDiscriminator getDiscriminator() {
return discriminator;
}
@@ -357,7 +356,7 @@ public class CodegenModel {
return discriminator == null ? null : discriminator.getPropertyName();
}
public void setDiscriminator(Discriminator discriminator) {
public void setDiscriminator(CodegenDiscriminator discriminator) {
this.discriminator = discriminator;
}

View File

@@ -18,17 +18,15 @@
package org.openapitools.codegen;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.media.Discriminator;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.tags.Tag;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Arrays;
public class CodegenOperation {
public final List<CodegenProperty> responseHeaders = new ArrayList<CodegenProperty>();
@@ -40,7 +38,7 @@ public class CodegenOperation {
isRestful, isDeprecated;
public String path, operationId, returnType, httpMethod, returnBaseType,
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse;
public Discriminator discriminator;
public CodegenDiscriminator discriminator;
public List<Map<String, String>> consumes, produces, prioritizedContentTypes;
public CodegenParameter bodyParam;
public List<CodegenParameter> allParams = new ArrayList<CodegenParameter>();

View File

@@ -26,7 +26,12 @@ import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.examples.Example;
import io.swagger.v3.oas.models.headers.Header;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.Content;
import io.swagger.v3.oas.models.media.MediaType;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
import io.swagger.v3.oas.models.parameters.CookieParameter;
import io.swagger.v3.oas.models.parameters.HeaderParameter;
import io.swagger.v3.oas.models.parameters.Parameter;
@@ -43,6 +48,7 @@ import io.swagger.v3.parser.util.SchemaTypeUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CodegenDiscriminator.MappedModel;
import org.openapitools.codegen.examples.ExampleGenerator;
import org.openapitools.codegen.serializer.SerializerUtils;
import org.openapitools.codegen.utils.ModelUtils;
@@ -66,6 +72,7 @@ import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
@@ -1506,6 +1513,10 @@ public class DefaultCodegen implements CodegenConfig {
// unalias schema
schema = ModelUtils.unaliasSchema(allDefinitions, schema);
if (schema == null) {
LOGGER.warn("Schema {} not found", name);
return null;
}
CodegenModel m = CodegenModelFactory.newInstance(CodegenModelType.MODEL);
@@ -1526,7 +1537,7 @@ public class DefaultCodegen implements CodegenConfig {
m.getVendorExtensions().putAll(schema.getExtensions());
}
m.isAlias = typeAliases.containsKey(name);
m.discriminator = schema.getDiscriminator();
m.discriminator = createDiscriminator(name, schema, allDefinitions);
if (schema.getXml() != null) {
m.xmlPrefix = schema.getXml().getPrefix();
@@ -1553,7 +1564,7 @@ public class DefaultCodegen implements CodegenConfig {
int modelImplCnt = 0; // only one inline object allowed in a ComposedModel
for (Schema innerModel : composed.getAllOf()) {
if (m.discriminator == null) {
m.discriminator = schema.getDiscriminator();
m.discriminator = createDiscriminator(name, schema, allDefinitions);
}
if (innerModel.getXml() != null) {
m.xmlPrefix = innerModel.getXml().getPrefix();
@@ -1668,6 +1679,34 @@ public class DefaultCodegen implements CodegenConfig {
return m;
}
private CodegenDiscriminator createDiscriminator(String schemaName, Schema schema, Map<String, Schema> allDefinitions) {
if(schema.getDiscriminator() == null) {
return null;
}
CodegenDiscriminator discriminator = new CodegenDiscriminator();
discriminator.setPropertyName(schema.getDiscriminator().getPropertyName());
discriminator.setMapping(schema.getDiscriminator().getMapping());
if(schema.getDiscriminator().getMapping() != null && !schema.getDiscriminator().getMapping().isEmpty()) {
for (Entry<String, String> e : schema.getDiscriminator().getMapping().entrySet()) {
String name = ModelUtils.getSimpleRef(e.getValue());
discriminator.getMappedModels().add(new MappedModel(e.getKey(), name));
}
} else {
allDefinitions.forEach((childName, child) -> {
if (child instanceof ComposedSchema && ((ComposedSchema) child).getAllOf() != null) {
Set<String> parentSchemas = ((ComposedSchema) child).getAllOf().stream()
.filter(s -> s.get$ref() != null)
.map(s -> ModelUtils.getSimpleRef(s.get$ref()))
.collect(Collectors.toSet());
if (parentSchemas.contains(schemaName)) {
discriminator.getMappedModels().add(new MappedModel(childName, childName));
}
}
});
}
return discriminator;
}
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) {
addParentContainer(codegenModel, codegenModel.name, schema);
}
@@ -2351,6 +2390,13 @@ public class DefaultCodegen implements CodegenConfig {
CodegenParameter p = fromParameter(param, imports);
// ensure unique params
if (ensureUniqueParams) {
if (!isParameterNameUnique(p, allParams)) {
p.paramName = generateNextName(p.paramName);
}
}
allParams.add(p);
if (param instanceof QueryParameter || "query".equalsIgnoreCase(param.getIn())) {
@@ -2379,17 +2425,6 @@ public class DefaultCodegen implements CodegenConfig {
}
}
// ensure unique parameter name
for (CodegenParameter cp : allParams) {
if (ensureUniqueParams) {
if (isParameterNameUnique(cp, allParams)) {
continue;
} else {
cp.paramName = generateNextName(cp.paramName);
}
}
}
// create optional, required parameters
for (CodegenParameter cp : allParams) {
if (cp.required) { //required parameters
@@ -4388,7 +4423,11 @@ public class DefaultCodegen implements CodegenConfig {
}
if (StringUtils.isEmpty(bodyParameterName)) {
codegenParameter.baseName = mostInnerItem.complexType;
if(StringUtils.isEmpty(mostInnerItem.complexType)) {
codegenParameter.baseName = "request_body";
} else {
codegenParameter.baseName = mostInnerItem.complexType;
}
} else {
codegenParameter.baseName = bodyParameterName;
}
@@ -4538,6 +4577,14 @@ public class DefaultCodegen implements CodegenConfig {
}
}
/**
* checks if the data should be classified as "string" in enum
* e.g. double in C# needs to be double-quoted (e.g. "2.8") by treating it as a string
* In the future, we may rename this function to "isEnumString"
*
* @param dataType data type
* @return true if it's a enum string
*/
public boolean isDataTypeString(String dataType) {
return "String".equals(dataType);
}

View File

@@ -95,7 +95,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
/**
* Programmatically disable the output of .openapi-generator/VERSION, .openapi-generator-ignore,
* or other metadata files used by Swagger Codegen.
* or other metadata files used by OpenAPI Generator.
*
* @param generateMetadata true: enable outputs, false: disable outputs
*/
@@ -169,14 +169,15 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
if (!generateApiTests && !generateModelTests) {
config.additionalProperties().put(CodegenConstants.EXCLUDE_TESTS, true);
}
// for backward compatibility
if (System.getProperty("debugSwagger") != null) {
LOGGER.info("Please use system property 'debugOpenAPI' instead of 'debugSwagger'.");
Json.prettyPrint(openAPI);
}
if (System.getProperty("debugOpenAPI") != null) {
Json.prettyPrint(openAPI);
} else if (System.getProperty("debugSwagger") != null) {
// This exists for backward compatibility
// We fall to this block only if debugOpenAPI is null. No need to dump this twice.
LOGGER.info("Please use system property 'debugOpenAPI' instead of 'debugSwagger'.");
Json.prettyPrint(openAPI);
}
config.processOpts();
@@ -193,8 +194,14 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
URL url = URLPathUtils.getServerURL(openAPI);
contextPath = config.escapeText(url.getPath());
basePath = config.escapeText(URLPathUtils.getHost(openAPI));
basePathWithoutHost = contextPath; // for backward compatibility
basePath = config.escapeText(URLPathUtils.getHost(openAPI));
if ("/".equals(basePath.substring(basePath.length() - 1))) {
// remove trailing "/"
// https://host.example.com/ => https://host.example.com
basePath = basePath.substring(0, basePath.length() - 1);
}
}
private void configureOpenAPIInfo() {
@@ -781,8 +788,8 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
configureOpenAPIInfo();
// resolve inline models
//InlineModelResolver inlineModelResolver = new InlineModelResolver();
//inlineModelResolver.flatten(openAPI);
InlineModelResolver inlineModelResolver = new InlineModelResolver();
inlineModelResolver.flatten(openAPI);
List<File> files = new ArrayList<File>();
// models

View File

@@ -0,0 +1,533 @@
package org.openapitools.codegen;
import io.swagger.v3.oas.models.OpenAPI;
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.oas.models.Paths;
import io.swagger.v3.core.util.Json;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.swagger.v3.oas.models.media.Content;
import io.swagger.v3.oas.models.media.MediaType;
import java.util.ArrayList;
import io.swagger.v3.oas.models.media.XML;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class InlineModelResolver {
private OpenAPI openapi;
private boolean skipMatches;
static Logger LOGGER = LoggerFactory.getLogger(InlineModelResolver.class);
Map<String, Schema> addedModels = new HashMap<String, Schema>();
Map<String, String> generatedSignature = new HashMap<String, String>();
public void flatten(OpenAPI openapi) {
this.openapi = openapi;
if (openapi.getComponents() == null) {
return; // There's nothing here
}
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);
// TODO assume JSON, need to support other payload later
content.addMediaType("application/json", mt);
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);
}
}
}
}
}
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);
}
}
}
}
}
}
}
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 = (Schema) mp.getAdditionalProperties();
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);
}
}
}
}
}
}
}
}
}
}
// 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);
}
}
}
} 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\""
*
* @param m Schema implementation
*/
private void fixStringModel(Schema m) {
if (m.getType() != null && m.getType().equals("string") && m.getExample() != null) {
String example = m.getExample().toString();
if (example.substring(0, 1).equals("\"") && example.substring(example.length() - 1).equals("\"")) {
m.setExample(example.substring(1, example.length() - 1));
}
}
}
private String resolveModelName(String title, String key) {
if (title == null) {
return uniqueName(key);
} else {
return uniqueName(title);
}
}
public String matchGenerated(Schema model) {
if (this.skipMatches) {
return null;
}
String json = Json.pretty(model);
if (generatedSignature.containsKey(json)) {
return generatedSignature.get(json);
}
return null;
}
public void addGenerated(String name, Schema model) {
generatedSignature.put(Json.pretty(model), name);
}
public String uniqueName(String key) {
if (key == null) {
key = "NULL_UNIQUE_NAME";
LOGGER.warn("null key found. Default to NULL_UNIQUE_NAME");
}
int count = 0;
boolean done = false;
key = key.replaceAll("[^a-z_\\.A-Z0-9 ]", ""); // FIXME: a parameter
// should not be
// assigned. Also declare
// the methods parameters
// as 'final'.
while (!done) {
String name = key;
if (count > 0) {
name = key + "_" + count;
}
if (openapi.getComponents().getSchemas() == null) {
return name;
} else if (!openapi.getComponents().getSchemas().containsKey(name)) {
return name;
}
count += 1;
}
return key;
}
public void flattenProperties(Map<String, Schema> properties, String path) {
if (properties == null) {
return;
}
Map<String, Schema> propsToUpdate = new HashMap<String, Schema>();
Map<String, Schema> modelsToAdd = new HashMap<String, Schema>();
for (String key : properties.keySet()) {
Schema property = properties.get(key);
if (property instanceof ObjectSchema && ((ObjectSchema) property).getProperties() != null
&& ((ObjectSchema) property).getProperties().size() > 0) {
ObjectSchema op = (ObjectSchema) property;
String modelName = resolveModelName(op.getTitle(), path + "_" + key);
Schema model = modelFromProperty(op, modelName);
String existing = matchGenerated(model);
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
propsToUpdate.put(key, schema);
} else {
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
propsToUpdate.put(key, schema);
modelsToAdd.put(modelName, model);
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(), path);
String modelName = resolveModelName(op.getTitle(), path + "_" + key);
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
ap.setItems(schema);
} else {
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
ap.setItems(schema);
addGenerated(modelName, innerModel);
openapi.getComponents().addSchemas(modelName, innerModel);
}
}
}
}
if (ModelUtils.isMapSchema(property)) {
Schema inner = (Schema) property.getAdditionalProperties();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(op.getProperties(), path);
String modelName = resolveModelName(op.getTitle(), path + "_" + key);
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
property.setAdditionalProperties(schema);
} else {
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
property.setAdditionalProperties(schema);
addGenerated(modelName, innerModel);
openapi.getComponents().addSchemas(modelName, innerModel);
}
}
}
}
}
if (propsToUpdate.size() > 0) {
for (String key : propsToUpdate.keySet()) {
properties.put(key, propsToUpdate.get(key));
}
}
for (String key : modelsToAdd.keySet()) {
openapi.getComponents().addSchemas(key, modelsToAdd.get(key));
this.addedModels.put(key, modelsToAdd.get(key));
}
}
@SuppressWarnings("static-method")
public Schema modelFromProperty(ArraySchema object, @SuppressWarnings("unused") String path) {
String description = object.getDescription();
String example = null;
Object obj = object.getExample();
if (obj != null) {
example = obj.toString();
}
Schema inner = object.getItems();
if (inner instanceof ObjectSchema) {
ArraySchema model = new ArraySchema();
model.setDescription(description);
model.setExample(example);
model.setItems(object.getItems());
model.setName(object.getName());
return model;
}
return null;
}
public Schema modelFromProperty(ObjectSchema object, String path) {
String description = object.getDescription();
String example = null;
Object obj = object.getExample();
if (obj != null) {
example = obj.toString();
}
XML xml = object.getXml();
Map<String, Schema> properties = object.getProperties();
Schema model = new Schema();
model.setDescription(description);
model.setExample(example);
model.setName(object.getName());
model.setXml(xml);
if (properties != null) {
flattenProperties(properties, path);
model.setProperties(properties);
}
return model;
}
@SuppressWarnings("static-method")
public Schema modelFromProperty(MapSchema object, @SuppressWarnings("unused") String path) {
String description = object.getDescription();
String example = null;
Object obj = object.getExample();
if (obj != null) {
example = obj.toString();
}
ArraySchema model = new ArraySchema();
model.setDescription(description);
model.setName(object.getName());
model.setExample(example);
model.setItems((Schema) object.getAdditionalProperties());
return model;
}
/**
* Make a Schema
*
* @param ref new property name
* @param property Schema
* @return {@link Schema} A constructed OpenAPI property
*/
public Schema makeSchema(String ref, Schema property) {
Schema newProperty = new Schema().$ref(ref);
this.copyVendorExtensions(property, newProperty);
return newProperty;
}
/**
* Copy vendor extensions from Model to another Model
*
* @param source source property
* @param target target property
*/
public void copyVendorExtensions(Schema source, Schema target) {
Map<String, Object> vendorExtensions = source.getExtensions();
for (String extName : vendorExtensions.keySet()) {
target.addExtension(extName, vendorExtensions.get(extName));
}
}
public boolean isSkipMatches() {
return skipMatches;
}
public void setSkipMatches(boolean skipMatches) {
this.skipMatches = skipMatches;
}
}

View File

@@ -0,0 +1,133 @@
package org.openapitools.codegen;
import java.util.Set;
public class SpecValidationException extends RuntimeException {
private Set<String> errors;
private Set<String> warnings;
/**
* Constructs a new runtime exception with {@code null} as its
* detail message. The cause is not initialized, and may subsequently be
* initialized by a call to {@link #initCause}.
*/
public SpecValidationException() {
}
/**
* Constructs a new runtime exception with the specified detail message.
* The cause is not initialized, and may subsequently be initialized by a
* call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public SpecValidationException(String message) {
super(message);
}
/**
* Constructs a new runtime exception with the specified detail message and
* cause. <p>Note that the detail message associated with
* {@code cause} is <i>not</i> automatically incorporated in
* this runtime exception's detail message.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public SpecValidationException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a new runtime exception with the specified cause and a
* detail message of <tt>(cause==null ? null : cause.toString())</tt>
* (which typically contains the class and detail message of
* <tt>cause</tt>). This constructor is useful for runtime exceptions
* that are little more than wrappers for other throwables.
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public SpecValidationException(Throwable cause) {
super(cause);
}
/**
* Constructs a new runtime exception with the specified detail
* message, cause, suppression enabled or disabled, and writable
* stack trace enabled or disabled.
*
* @param message the detail message.
* @param cause the cause. (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @param enableSuppression whether or not suppression is enabled
* or disabled
* @param writableStackTrace whether or not the stack trace should
* be writable
* @since 1.7
*/
public SpecValidationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public Set<String> getErrors() {
return errors;
}
public Set<String> getWarnings() {
return warnings;
}
public void setErrors(Set<String> errors) {
this.errors = errors;
}
public void setWarnings(Set<String> warnings) {
this.warnings = warnings;
}
/**
* Returns the detail message string of this throwable.
*
* @return the detail message string of this {@code Throwable} instance
* (which may be {@code null}).
*/
@Override
public String getMessage() {
int errorCount = 0;
if (errors != null) {
errorCount = errors.size();
}
int warningCount = 0;
if (warnings != null) {
warningCount = warnings.size();
}
StringBuilder sb = new StringBuilder();
sb.append(System.lineSeparator())
.append("Errors: ")
.append(System.lineSeparator());
errors.forEach(msg ->
sb.append("\t-").append(msg).append(System.lineSeparator())
);
if (!warnings.isEmpty()) {
sb.append("Warnings: ").append(System.lineSeparator());
warnings.forEach(msg ->
sb.append("\t-").append(msg).append(System.lineSeparator())
);
}
return super.getMessage() + " | " +
"Error count: " + errorCount + ", Warning count: " + warningCount + sb.toString();
}
}

View File

@@ -19,12 +19,8 @@ package org.openapitools.codegen.config;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.ClientOpts;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.CodegenConfigLoader;
import org.openapitools.codegen.CodegenConstants;
import io.swagger.v3.oas.models.OpenAPI;
import org.openapitools.codegen.*;
import org.openapitools.codegen.auth.AuthParser;
import io.swagger.parser.OpenAPIParser;
import io.swagger.v3.core.util.Json;
@@ -33,6 +29,7 @@ import io.swagger.v3.parser.core.models.ParseOptions;
import io.swagger.v3.parser.core.models.SwaggerParseResult;
import org.apache.commons.lang3.Validate;
import org.openapitools.codegen.languages.*;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -80,6 +77,7 @@ public class CodegenConfigurator implements Serializable {
private boolean verbose;
private boolean skipOverwrite;
private boolean removeOperationIdPrefix;
private boolean validateSpec;
private String templateDir;
private String auth;
private String apiPackage;
@@ -108,6 +106,7 @@ public class CodegenConfigurator implements Serializable {
private final Map<String, Object> dynamicProperties = new HashMap<String, Object>(); //the map that holds the JsonAnySetter/JsonAnyGetter values
public CodegenConfigurator() {
this.validateSpec = true;
this.setOutputDir(".");
}
@@ -211,6 +210,15 @@ public class CodegenConfigurator implements Serializable {
return this;
}
public boolean isValidateSpec() {
return validateSpec;
}
public CodegenConfigurator setValidateSpec(final boolean validateSpec) {
this.validateSpec = validateSpec;
return this;
}
public boolean isSkipOverwrite() {
return skipOverwrite;
}
@@ -514,8 +522,48 @@ public class CodegenConfigurator implements Serializable {
options.setResolve(true);
options.setFlatten(true);
SwaggerParseResult result = new OpenAPIParser().readLocation(inputSpec, authorizationValues, options);
Set<String> validationMessages = new HashSet<>(result.getMessages());
OpenAPI specification = result.getOpenAPI();
// NOTE: We will only expose errors+warnings if there are already errors in the spec.
if (validationMessages.size() > 0) {
Set<String> warnings = new HashSet<>();
if (specification != null) {
List<String> unusedModels = ModelUtils.getUnusedSchemas(specification);
if (unusedModels != null) unusedModels.forEach(name -> warnings.add("Unused model: " + name));
}
if (this.isValidateSpec()) {
StringBuilder sb = new StringBuilder();
sb.append("There were issues with the specification. The option can be disabled via validateSpec (Maven/Gradle) or --skip-validate-spec (CLI).");
sb.append(System.lineSeparator());
SpecValidationException ex = new SpecValidationException(sb.toString());
ex.setErrors(validationMessages);
ex.setWarnings(warnings);
throw ex;
} else {
StringBuilder sb = new StringBuilder();
sb.append("There were issues with the specification, but validation has been explicitly disabled.");
sb.append(System.lineSeparator());
sb.append("Errors: ").append(System.lineSeparator());
validationMessages.forEach(msg ->
sb.append("\t-").append(msg).append(System.lineSeparator())
);
if (!warnings.isEmpty()) {
sb.append("Warnings: ").append(System.lineSeparator());
warnings.forEach(msg ->
sb.append("\t-").append(msg).append(System.lineSeparator())
);
}
LOGGER.warn(sb.toString());
}
}
input.opts(new ClientOpts())
.openAPI(result.getOpenAPI());
.openAPI(specification);
return input;
}
@@ -548,12 +596,12 @@ public class CodegenConfigurator implements Serializable {
return;
}
LOGGER.info("\nVERBOSE MODE: ON. Additional debug options are injected" +
"\n - [debugSwagger] prints the openapi specification as interpreted by the codegen" +
"\n - [debugOpenAPI] prints the OpenAPI specification as interpreted by the codegen" +
"\n - [debugModels] prints models passed to the template engine" +
"\n - [debugOperations] prints operations passed to the template engine" +
"\n - [debugSupportingFiles] prints additional data passed to the template engine");
System.setProperty("debugSwagger", "");
System.setProperty("debugOpenAPI", "");
System.setProperty("debugModels", "");
System.setProperty("debugOperations", "");
System.setProperty("debugSupportingFiles", "");

View File

@@ -0,0 +1,680 @@
/*
* 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.languages;
import java.util.*;
import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Strings;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenParameter;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.DefaultCodegen;
import org.openapitools.codegen.utils.ModelUtils;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.responses.ApiResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractApexCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractApexCodegen.class);
protected Boolean serializableModel = false;
public AbstractApexCodegen() {
super();
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public String getName() {
return "apex";
}
@Override
public String getHelp() {
return "Generates an Apex API client library.";
}
@Override
public void processOpts() {
super.processOpts();
}
@Override
public String escapeReservedWord(String name) {
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@Override
public String sanitizeName(String name) {
name = super.sanitizeName(name);
if (name.contains("__")) { // Preventing namespacing
name.replaceAll("__", "_");
}
if (name.matches("^\\d.*")) { // Prevent named credentials with leading number
name.replaceAll("^\\d.*", "");
}
return name;
}
@Override
public String toVarName(String name) {
// sanitize name
name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
if (name.toLowerCase().matches("^_*class$")) {
return "propertyClass";
}
if ("_".equals(name)) {
name = "_u";
}
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$")) {
if (isReservedWord(name)) {
name = escapeReservedWord(name);
}
return name;
}
if (startsWithTwoUppercaseLetters(name)) {
name = name.substring(0, 2).toLowerCase() + name.substring(2);
}
// camelize (lower first character) the variable name
// pet_id => petId
name = camelize(name, true);
// for reserved word or word starting with number, append _
if (isReservedWord(name) || name.matches("^\\d.*")) {
name = escapeReservedWord(name);
}
return name;
}
private boolean startsWithTwoUppercaseLetters(String name) {
boolean startsWithTwoUppercaseLetters = false;
if (name.length() > 1) {
startsWithTwoUppercaseLetters = name.substring(0, 2).equals(name.substring(0, 2).toUpperCase());
}
return startsWithTwoUppercaseLetters;
}
@Override
public String toParamName(String name) {
// to avoid conflicts with 'callback' parameter for async call
if ("callback".equals(name)) {
return "paramCallback";
}
// should be the same as variable name
return toVarName(name);
}
@Override
public String toModelName(final String name) {
final String sanitizedName = sanitizeName(name);
String nameWithPrefixSuffix = sanitizedName;
if (!StringUtils.isEmpty(modelNamePrefix)) {
// add '_' so that model name can be camelized correctly
nameWithPrefixSuffix = modelNamePrefix + "_" + nameWithPrefixSuffix;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
// add '_' so that model name can be camelized correctly
nameWithPrefixSuffix = nameWithPrefixSuffix + "_" + modelNameSuffix;
}
// camelize the model name
// phone_number => PhoneNumber
final String camelizedName = camelize(nameWithPrefixSuffix);
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(camelizedName)) {
final String modelName = "Model" + camelizedName;
LOGGER.warn(camelizedName + " (reserved word) cannot be used as model name. Renamed to " + modelName);
return modelName;
}
// model name starts with number
if (camelizedName.matches("^\\d.*")) {
final String modelName = "Model" + camelizedName; // e.g. 200Response => Model200Response (after camelize)
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + modelName);
return modelName;
}
return camelizedName;
}
@Override
public String toModelFilename(String name) {
// should be the same as the model name
return toModelName(name);
}
@Override
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Schema inner = ap.getItems();
if (inner == null) {
LOGGER.warn(ap.getName() + "(array property) does not have a proper inner type defined");
// TODO maybe better defaulting to StringProperty than returning null
return null;
}
return getSchemaType(p) + "<" + getTypeDeclaration(inner) + ">";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
if (inner == null) {
LOGGER.warn(p.getName() + "(map property) does not have a proper inner type defined");
// TODO maybe better defaulting to StringProperty than returning null
return null;
}
return getSchemaType(p) + "<String, " + getTypeDeclaration(inner) + ">";
}
return super.getTypeDeclaration(p);
}
@Override
public String getAlias(String name) {
if (typeAliases != null && typeAliases.containsKey(name)) {
return typeAliases.get(name);
}
return name;
}
@Override
public String toDefaultValue(Schema p) {
if (ModelUtils.isArraySchema(p)) {
final ArraySchema ap = (ArraySchema) p;
final String pattern = "new ArrayList<%s>()";
if (ap.getItems() == null) {
return null;
}
return String.format(pattern, getTypeDeclaration(ap.getItems()));
} else if (ModelUtils.isMapSchema(p)) {
final MapSchema ap = (MapSchema) p;
final String pattern = "new HashMap<%s>()";
if (ap.getAdditionalProperties() == null) {
return null;
}
return String.format(pattern, String.format("String, %s", getTypeDeclaration((Schema) ap.getAdditionalProperties())));
} else if (ModelUtils.isLongSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString() + "l";
}
return "null";
} else if (ModelUtils.isIntegerSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString();
}
return "null";
} else if (ModelUtils.isFloatSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString() + "f";
}
return "null";
} else if (ModelUtils.isDoubleSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString() + "d";
}
return "null";
} else if (ModelUtils.isBooleanSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString();
}
return "null";
} else if (ModelUtils.isStringSchema(p)) {
if (p.getDefault() != null) {
String _default = (String) p.getDefault();
if (p.getEnum() == null) {
return "\"" + escapeText(_default) + "\"";
} else {
// convert to enum var name later in postProcessModels
return _default;
}
}
return "null";
}
return super.toDefaultValue(p);
}
@Override
public void setParameterExampleValue(CodegenParameter p) {
if (Boolean.TRUE.equals(p.isLong)) {
p.example = "2147483648L";
} else if (Boolean.TRUE.equals(p.isFile)) {
p.example = "Blob.valueOf('Sample text file\\nContents')";
} else if (Boolean.TRUE.equals(p.isDate)) {
p.example = "Date.newInstance(1960, 2, 17)";
} else if (Boolean.TRUE.equals(p.isDateTime)) {
p.example = "Datetime.newInstanceGmt(2013, 11, 12, 3, 3, 3)";
} else if (Boolean.TRUE.equals(p.isListContainer)) {
if (p.items != null && p.items.example != null) {
p.example = "new " + p.dataType + "{" + p.items.example + "}";
}
} else if (Boolean.TRUE.equals(p.isMapContainer)) {
if (p.items != null && p.items.example != null) {
p.example = "new " + p.dataType + "{" + p.items.example + "}";
}
} else if (Boolean.TRUE.equals(p.isString)) {
p.example = "'" + p.example + "'";
} else if ("".equals(p.example) || p.example == null && p.dataType != "Object") {
// Get an example object from the generated model
if (!isReservedWord(p.dataType.toLowerCase())) {
p.example = p.dataType + ".getExample()";
}
} else {
p.example = "''";
}
}
@Override
public String toExampleValue(Schema p) {
if (p == null) {
return "";
}
Object obj = p.getExample();
String example = obj == null ? "" : obj.toString();
if (ModelUtils.isArraySchema(p)) {
example = "new " + getTypeDeclaration(p) + "{" + toExampleValue(
((ArraySchema) p).getItems()) + "}";
} else if (ModelUtils.isBooleanSchema(p)) {
example = String.valueOf(!"false".equals(example));
} else if (ModelUtils.isByteArraySchema(p)) {
if (example.isEmpty()) {
example = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu";
}
((ByteArraySchema) p).setExample(example);
example = "EncodingUtil.base64Decode('" + example + "')";
} else if (ModelUtils.isDateSchema(p)) {
if (example.matches("^\\d{4}(-\\d{2}){2}")) {
example = example.substring(0, 10).replaceAll("-0?", ", ");
} else if (example.isEmpty()) {
example = "2000, 1, 23";
} else {
LOGGER.warn(String.format("The example provided for property '%s' is not a valid RFC3339 date. Defaulting to '2000-01-23'. [%s]", p
.getName(), example));
example = "2000, 1, 23";
}
example = "Date.newInstance(" + example + ")";
} else if (ModelUtils.isDateTimeSchema(p)) {
if (example.matches("^\\d{4}([-T:]\\d{2}){5}.+")) {
example = example.substring(0, 19).replaceAll("[-T:]0?", ", ");
} else if (example.isEmpty()) {
example = "2000, 1, 23, 4, 56, 7";
} else {
LOGGER.warn(String.format("The example provided for property '%s' is not a valid RFC3339 datetime. Defaulting to '2000-01-23T04-56-07Z'. [%s]", p
.getName(), example));
example = "2000, 1, 23, 4, 56, 7";
}
example = "Datetime.newInstanceGmt(" + example + ")";
} else if (ModelUtils.isNumberSchema(p)) {
example = example.replaceAll("[^-0-9.]", "");
example = example.isEmpty() ? "1.3579" : example;
} else if (ModelUtils.isFileSchema(p)) {
if (example.isEmpty()) {
example = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu";
p.setExample(example);
}
example = "EncodingUtil.base64Decode(" + example + ")";
} else if (ModelUtils.isEmailSchema(p)) {
if (example.isEmpty()) {
example = "example@example.com";
p.setExample(example);
}
example = "'" + example + "'";
} else if (ModelUtils.isLongSchema(p)) {
example = example.isEmpty() ? "123456789L" : example + "L";
} else if (ModelUtils.isMapSchema(p)) {
example = "new " + getTypeDeclaration(p) + "{'key'=>" + toExampleValue((Schema) p.getAdditionalProperties()) + "}";
} else if (ModelUtils.isPasswordSchema(p)) {
example = example.isEmpty() ? "password123" : escapeText(example);
p.setExample(example);
example = "'" + example + "'";
} else if (ModelUtils.isStringSchema(p)) {
List<String> enums = p.getEnum();
if (enums != null && example.isEmpty()) {
example = enums.get(0);
p.setExample(example);
} else if (example.isEmpty()) {
example = "";
} else {
example = escapeText(example);
p.setExample(example);
}
example = "'" + example + "'";
} else if (ModelUtils.isUUIDSchema(p)) {
example = example.isEmpty()
? "'046b6c7f-0b8a-43b9-b35d-6489e6daee91'"
: "'" + escapeText(example) + "'";
} else if (ModelUtils.isIntegerSchema(p)) {
example = example.matches("^-?\\d+$") ? example : "0";
} else if (ModelUtils.isObjectSchema(p)) {
example = example.isEmpty() ? "null" : example;
} else {
example = getTypeDeclaration(p) + ".getExample()";
}
return example;
}
@Override
public String getSchemaType(Schema p) {
String schemaType = super.getSchemaType(p);
schemaType = getAlias(schemaType);
// don't apply renaming on types from the typeMapping
if (typeMapping.containsKey(schemaType)) {
return typeMapping.get(schemaType);
}
if (null == schemaType) {
LOGGER.error("No Type defined for Property " + p);
}
return toModelName(schemaType);
}
@Override
public String toOperationId(String operationId) {
// throw exception if method name is empty
if (StringUtils.isEmpty(operationId)) {
throw new RuntimeException("Empty method/operation name (operationId) not allowed");
}
operationId = camelize(sanitizeName(operationId), true);
// method name cannot use reserved keyword, e.g. return
if (isReservedWord(operationId)) {
String newOperationId = camelize("call_" + operationId, true);
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + newOperationId);
return newOperationId;
}
return operationId;
}
@Override
public CodegenModel fromModel(String name, Schema model, Map<String, Schema> allDefinitions) {
CodegenModel cm = super.fromModel(name, model, allDefinitions);
// TODO Check enum model handling
if (cm.interfaces == null) {
cm.interfaces = new ArrayList<String>();
}
Boolean hasDefaultValues = false;
// for (de)serializing properties renamed for Apex (e.g. reserved words)
List<Map<String, String>> propertyMappings = new ArrayList<>();
for (CodegenProperty p : cm.allVars) {
hasDefaultValues |= p.defaultValue != null;
if (!p.baseName.equals(p.name)) {
Map<String, String> mapping = new HashMap<>();
mapping.put("externalName", p.baseName);
mapping.put("internalName", p.name);
propertyMappings.add(mapping);
}
}
cm.vendorExtensions.put("hasPropertyMappings", !propertyMappings.isEmpty());
cm.vendorExtensions.put("hasDefaultValues", hasDefaultValues);
cm.vendorExtensions.put("propertyMappings", propertyMappings);
if (!propertyMappings.isEmpty()) {
cm.interfaces.add("OAS.MappedProperties");
}
return cm;
}
@Override
public void postProcessParameter(CodegenParameter parameter) {
if (parameter.isBodyParam && parameter.isListContainer) {
// items of array bodyParams are being nested an extra level too deep for some reason
parameter.items = parameter.items.items;
setParameterExampleValue(parameter);
}
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
return postProcessModelsEnum(objs);
}
/* the following function is not used anywhere in this class so we'll remove it later
private static String getAccept(Operation operation) {
String accepts = null;
String defaultContentType = "application/json";
if (operation.getProduces() != null && !operation.getProduces().isEmpty()) {
StringBuilder sb = new StringBuilder();
for (String produces : operation.getProduces()) {
if (defaultContentType.equalsIgnoreCase(produces)) {
accepts = defaultContentType;
break;
} else {
if (sb.length() > 0) {
sb.append(",");
}
sb.append(produces);
}
}
if (accepts == null) {
accepts = sb.toString();
}
} else {
accepts = defaultContentType;
}
return accepts;
}*/
@Override
protected boolean needToImport(String type) {
return super.needToImport(type) && type.indexOf(".") < 0;
}
@Override
public String toEnumName(CodegenProperty property) {
return sanitizeName(camelize(property.name)) + "Enum";
}
@Override
public String toEnumVarName(String value, String datatype) {
if (value.length() == 0) {
return "EMPTY";
}
// for symbol, e.g. $, #
if (getSymbolName(value) != null) {
return getSymbolName(value).toUpperCase();
}
// number
if ("Integer".equals(datatype) || "Long".equals(datatype) ||
"Float".equals(datatype) || "Double".equals(datatype)) {
String varName = "NUMBER_" + value;
varName = varName.replaceAll("-", "MINUS_");
varName = varName.replaceAll("\\+", "PLUS_");
varName = varName.replaceAll("\\.", "_DOT_");
return varName;
}
// string
String var = value.replaceAll("\\W+", "_").toUpperCase();
if (var.matches("\\d.*")) {
return "_" + var;
} else {
return var;
}
}
@Override
public String toEnumValue(String value, String datatype) {
if ("Integer".equals(datatype) || "Double".equals(datatype)) {
return value;
} else if ("Long".equals(datatype)) {
// add l to number, e.g. 2048 => 2048l
return value + "l";
} else if ("Float".equals(datatype)) {
// add f to number, e.g. 3.14 => 3.14f
return value + "f";
} else {
return "\"" + escapeText(value) + "\"";
}
}
@Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Schema> definitions, OpenAPI openAPI) {
CodegenOperation op = super.fromOperation(
path, httpMethod, operation, definitions, openAPI);
if (op.getHasExamples()) {
// prepare examples for Apex test classes
ApiResponse apiResponse = findMethodResponse(operation.getResponses());
final Schema responseSchema = ModelUtils.getSchemaFromResponse(apiResponse);
String deserializedExample = toExampleValue(responseSchema);
for (Map<String, String> example : op.examples) {
example.put("example", escapeText(example.get("example")));
example.put("deserializedExample", deserializedExample);
}
}
return op;
}
private static CodegenModel reconcileInlineEnums(CodegenModel codegenModel, CodegenModel parentCodegenModel) {
// This generator uses inline classes to define enums, which breaks when
// dealing with models that have subTypes. To clean this up, we will analyze
// the parent and child models, look for enums that match, and remove
// them from the child models and leave them in the parent.
// Because the child models extend the parents, the enums will be available via the parent.
// Only bother with reconciliation if the parent model has enums.
if (!parentCodegenModel.hasEnums) {
return codegenModel;
}
// Get the properties for the parent and child models
final List<CodegenProperty> parentModelCodegenProperties = parentCodegenModel.vars;
List<CodegenProperty> codegenProperties = codegenModel.vars;
// Iterate over all of the parent model properties
boolean removedChildEnum = false;
for (CodegenProperty parentModelCodegenPropery : parentModelCodegenProperties) {
// Look for enums
if (parentModelCodegenPropery.isEnum) {
// Now that we have found an enum in the parent class,
// and search the child class for the same enum.
Iterator<CodegenProperty> iterator = codegenProperties.iterator();
while (iterator.hasNext()) {
CodegenProperty codegenProperty = iterator.next();
if (codegenProperty.isEnum && codegenProperty.equals(parentModelCodegenPropery)) {
// We found an enum in the child class that is
// a duplicate of the one in the parent, so remove it.
iterator.remove();
removedChildEnum = true;
}
}
}
}
if (removedChildEnum) {
// If we removed an entry from this model's vars, we need to ensure hasMore is updated
int count = 0, numVars = codegenProperties.size();
for (CodegenProperty codegenProperty : codegenProperties) {
count += 1;
codegenProperty.hasMore = (count < numVars) ? true : false;
}
codegenModel.vars = codegenProperties;
}
return codegenModel;
}
private static String sanitizePackageName(String packageName) {
packageName = packageName.trim(); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
packageName = packageName.replaceAll("[^a-zA-Z0-9_\\.]", "_");
if (Strings.isNullOrEmpty(packageName)) {
return "invalidPackageName";
}
return packageName;
}
public void setSerializableModel(Boolean serializableModel) {
this.serializableModel = serializableModel;
}
private String sanitizePath(String p) {
//prefer replace a ", instead of a fuLL URL encode for readability
return p.replaceAll("\"", "%22");
}
public String toRegularExpression(String pattern) {
return escapeText(pattern);
}
public boolean convertPropertyToBoolean(String propertyKey) {
boolean booleanValue = false;
if (additionalProperties.containsKey(propertyKey)) {
booleanValue = Boolean.valueOf(additionalProperties.get(propertyKey).toString());
}
return booleanValue;
}
public void writePropertyBack(String propertyKey, boolean value) {
additionalProperties.put(propertyKey, value);
}
@Override
public String sanitizeTag(String tag) {
return camelize(sanitizeName(tag));
}
@Override
public String toModelTestFilename(String name) {
return toModelName(name) + "Test";
}
}

View File

@@ -19,6 +19,7 @@ package org.openapitools.codegen.languages;
import com.google.common.collect.ImmutableMap;
import com.samskivert.mustache.Mustache;
import io.swagger.v3.core.util.Json;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.utils.*;
@@ -603,6 +604,12 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
operationId = "call_" + operationId;
}
// operationId starts with a number
if (operationId.matches("^\\d.*")) {
LOGGER.warn(operationId + " (starting with a number) cannot be used as method name. Renamed to " + camelize(sanitizeName("call_" + operationId)));
operationId = "call_" + operationId;
}
return camelize(sanitizeName(operationId));
}
@@ -707,12 +714,22 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
return p.getDefault().toString();
}
} else if (ModelUtils.isDateSchema(p)) {
// TODO
if (p.getDefault() != null) {
return "\"" + p.getDefault().toString() + "\"";
}
} else if (ModelUtils.isDateTimeSchema(p)) {
// TODO
if (p.getDefault() != null) {
return "\"" + p.getDefault().toString() + "\"";
}
} else if (ModelUtils.isNumberSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString();
if (ModelUtils.isFloatSchema(p)) { // float
return p.getDefault().toString() + "F";
} else if (ModelUtils.isDoubleSchema(p)) { // double
return p.getDefault().toString() + "D";
} else {
return p.getDefault().toString();
}
}
} else if (ModelUtils.isIntegerSchema(p)) {
if (p.getDefault() != null) {
@@ -955,4 +972,48 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*").replace("--", "- -");
}
@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);
}
@Override
public void setParameterExampleValue(CodegenParameter codegenParameter) {
// set the example value
// if not specified in x-example, generate a default value
// TODO need to revise how to obtain the example value
if (codegenParameter.vendorExtensions != null && codegenParameter.vendorExtensions.containsKey("x-example")) {
codegenParameter.example = Json.pretty(codegenParameter.vendorExtensions.get("x-example"));
} else if (Boolean.TRUE.equals(codegenParameter.isBoolean)) {
codegenParameter.example = "true";
} else if (Boolean.TRUE.equals(codegenParameter.isLong)) {
codegenParameter.example = "789";
} else if (Boolean.TRUE.equals(codegenParameter.isInteger)) {
codegenParameter.example = "56";
} else if (Boolean.TRUE.equals(codegenParameter.isFloat)) {
codegenParameter.example = "3.4F";
} else if (Boolean.TRUE.equals(codegenParameter.isDouble)) {
codegenParameter.example = "1.2D";
} else if (Boolean.TRUE.equals(codegenParameter.isNumber)) {
codegenParameter.example = "8.14";
} else if (Boolean.TRUE.equals(codegenParameter.isBinary)) {
codegenParameter.example = "BINARY_DATA_HERE";
} else if (Boolean.TRUE.equals(codegenParameter.isByteArray)) {
codegenParameter.example = "BYTE_ARRAY_DATA_HERE";
} else if (Boolean.TRUE.equals(codegenParameter.isFile)) {
codegenParameter.example = "/path/to/file.txt";
} else if (Boolean.TRUE.equals(codegenParameter.isDate)) {
codegenParameter.example = "2013-10-20";
} else if (Boolean.TRUE.equals(codegenParameter.isDateTime)) {
codegenParameter.example = "2013-10-20T19:20:30+01:00";
} else if (Boolean.TRUE.equals(codegenParameter.isUuid)) {
codegenParameter.example = "38400000-8cf0-11bd-b23e-10b96e4ef00d";
} else if (Boolean.TRUE.equals(codegenParameter.isString)) {
codegenParameter.example = codegenParameter.paramName + "_example";
}
}
}

View File

@@ -19,13 +19,17 @@ package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.Schema;
import com.google.common.collect.ImmutableMap;
import com.samskivert.mustache.Mustache;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.DefaultCodegen;
import org.openapitools.codegen.mustache.IndentedLambda;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.Map;
abstract public class AbstractCppCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractCppCodegen.class);
@@ -128,6 +132,38 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
);
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String toApiName(String type) {
return sanitizeName(modelNamePrefix + Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api");
}
@Override
public String toModelName(String type) {
if (type == null) {
LOGGER.warn("Model name can't be null. Default to 'UnknownModel'.");
type = "UnknownModel";
}
if (typeMapping.keySet().contains(type) || typeMapping.values().contains(type)
|| importMapping.values().contains(type) || defaultIncludes.contains(type)
|| languageSpecificPrimitives.contains(type)) {
return type;
} else {
return sanitizeName(modelNamePrefix + Character.toUpperCase(type.charAt(0)) + type.substring(1));
}
}
@Override
public String toVarName(String name) {
if (typeMapping.keySet().contains(name) || typeMapping.values().contains(name)
@@ -136,7 +172,7 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
return sanitizeName(name);
}
if (isReservedWord(name)) {
if (isReservedWord(name) || name.matches("^\\d.*")) {
return escapeReservedWord(name);
}
@@ -173,6 +209,10 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
@Override
public String toParamName(String name) {
if (isReservedWord(name) || name.matches("^\\d.*")) {
return escapeReservedWord(name);
}
return sanitizeName(super.toParamName(name));
}
@@ -185,6 +225,9 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
} else {
nameInCamelCase = sanitizeName(nameInCamelCase);
}
if (isReservedWord(nameInCamelCase) || nameInCamelCase.matches("^\\d.*")) {
nameInCamelCase = escapeReservedWord(nameInCamelCase);
}
property.nameInCamelCase = nameInCamelCase;
return property;
}
@@ -203,4 +246,23 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
public String getTypeDeclaration(String str) {
return "std::shared_ptr<" + toModelName(str) + ">";
}
public void processOpts() {
super.processOpts();
addMustacheLambdas(additionalProperties);
}
private void addMustacheLambdas(Map<String, Object> objs) {
Map<String, Mustache.Lambda> lambdas = new ImmutableMap.Builder<String, Mustache.Lambda>()
.put("multiline_comment_4", new IndentedLambda(4, " ", "///"))
.build();
if (objs.containsKey("lambda")) {
LOGGER.warn("A property named 'lambda' already exists. Mustache lambdas renamed from 'lambda' to '_lambda'.");
objs.put("_lambda", lambdas);
} else {
objs.put("lambda", lambdas);
}
}
}

View File

@@ -145,7 +145,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = sanitizeName(name);
@@ -267,10 +267,10 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
// the type.
String openAPIType = getSchemaType(p);
String ref = p.get$ref();
if(ref != null && !ref.isEmpty()) {
if (ref != null && !ref.isEmpty()) {
String tryRefV2 = "#/definitions/" + openAPIType;
String tryRefV3 = "#/components/schemas/" + openAPIType;
if(ref.equals(tryRefV2) || ref.equals(tryRefV3)) {
if (ref.equals(tryRefV2) || ref.equals(tryRefV3)) {
return toModelName(openAPIType);
}
}
@@ -296,7 +296,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
String ref = p.get$ref();
String type = null;
if(ref != null && !ref.isEmpty()) {
if (ref != null && !ref.isEmpty()) {
type = openAPIType;
} else if (typeMapping.containsKey(openAPIType)) {
type = typeMapping.get(openAPIType);
@@ -314,7 +314,13 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
// method name cannot use reserved keyword, e.g. return
if (isReservedWord(sanitizedOperationId)) {
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to "
+ camelize("call_" + operationId));
+ camelize("call_" + sanitizedOperationId));
sanitizedOperationId = "call_" + sanitizedOperationId;
}
// operationId starts with a number
if (sanitizedOperationId.matches("^\\d.*")) {
LOGGER.warn(operationId + " (starting with a number) cannot be used as method name. Renamed to " + camelize("call_" + sanitizedOperationId));
sanitizedOperationId = "call_" + sanitizedOperationId;
}
@@ -564,8 +570,10 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
enumName = enumName.replaceFirst("^_", "");
enumName = enumName.replaceFirst("_$", "");
if (isReservedWord(enumName) || enumName.matches("\\d.*")) { // reserved word or starts with number
if (isReservedWord(enumName)) { // reserved word
return escapeReservedWord(enumName);
} else if (enumName.matches("\\d.*")) { // starts with a number
return "_" + enumName;
} else {
return enumName;
}

View File

@@ -65,6 +65,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
public static final String DISABLE_HTML_ESCAPING = "disableHtmlEscaping";
public static final String BOOLEAN_GETTER_PREFIX = "booleanGetterPrefix";
public static final String BOOLEAN_GETTER_PREFIX_DEFAULT = "get";
public static final String USE_NULL_FOR_UNKNOWN_ENUM_VALUE = "useNullForUnknownEnumValue";
protected String dateLibrary = "threetenbp";
protected boolean supportAsync = false;
@@ -99,6 +100,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
protected boolean supportJava6= false;
protected boolean disableHtmlEscaping = false;
protected String booleanGetterPrefix = BOOLEAN_GETTER_PREFIX_DEFAULT;
protected boolean useNullForUnknownEnumValue = false;
public AbstractJavaCodegen() {
super();
@@ -213,6 +215,11 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
}
additionalProperties.put(BOOLEAN_GETTER_PREFIX, booleanGetterPrefix);
if (additionalProperties.containsKey(USE_NULL_FOR_UNKNOWN_ENUM_VALUE)) {
this.setUseNullForUnknownEnumValue(Boolean.valueOf(additionalProperties.get(USE_NULL_FOR_UNKNOWN_ENUM_VALUE).toString()));
}
additionalProperties.put(USE_NULL_FOR_UNKNOWN_ENUM_VALUE, useNullForUnknownEnumValue);
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
} else if (additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
@@ -877,6 +884,12 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
return newOperationId;
}
// operationId starts with a number
if (operationId.matches("^\\d.*")) {
LOGGER.warn(operationId + " (starting with a number) cannot be used as method sname. Renamed to " + camelize("call_" + operationId), true);
operationId = camelize("call_" + operationId, true);
}
return operationId;
}
@@ -1254,6 +1267,10 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
this.booleanGetterPrefix = booleanGetterPrefix;
}
public void setUseNullForUnknownEnumValue(boolean useNullForUnknownEnumValue) {
this.useNullForUnknownEnumValue = useNullForUnknownEnumValue;
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection

View File

@@ -23,13 +23,9 @@ import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenParameter;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.DefaultCodegen;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.utils.ModelUtils;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.*;
import java.io.File;
@@ -50,7 +46,7 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractPhpCodegen.class);
public static final String VARIABLE_NAMING_CONVENTION = "variableNamingConvention";
public static final String PACKAGE_PATH = "packagePath";
public static final String PACKAGE_NAME = "packageName";
public static final String SRC_BASE_PATH = "srcBasePath";
// composerVendorName/composerProjectName has be replaced by gitUserId/gitRepoId. prepare to remove these.
// public static final String COMPOSER_VENDOR_NAME = "composerVendorName";
@@ -58,7 +54,7 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
// protected String composerVendorName = null;
// protected String composerProjectName = null;
protected String invokerPackage = "php";
protected String packagePath = "php-base";
protected String packageName = "php-base";
protected String artifactVersion = null;
protected String srcBasePath = "lib";
protected String testBasePath = "test";
@@ -144,8 +140,8 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
cliOptions.add(new CliOption(VARIABLE_NAMING_CONVENTION, "naming convention of variable name, e.g. camelCase.")
.defaultValue("snake_case"));
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, "The main namespace to use for all classes. e.g. Yay\\Pets"));
cliOptions.add(new CliOption(PACKAGE_PATH, "The main package name for classes. e.g. GeneratedPetstore"));
cliOptions.add(new CliOption(SRC_BASE_PATH, "The directory under packagePath to serve as source root."));
cliOptions.add(new CliOption(PACKAGE_NAME, "The main package name for classes. e.g. GeneratedPetstore"));
cliOptions.add(new CliOption(SRC_BASE_PATH, "The directory to serve as source root."));
// cliOptions.add(new CliOption(COMPOSER_VENDOR_NAME, "The vendor name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. yaypets. IMPORTANT NOTE (2016/03): composerVendorName will be deprecated and replaced by gitUserId in the next openapi-generator release"));
cliOptions.add(new CliOption(CodegenConstants.GIT_USER_ID, CodegenConstants.GIT_USER_ID_DESC));
// cliOptions.add(new CliOption(COMPOSER_PROJECT_NAME, "The project name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. petstore-client. IMPORTANT NOTE (2016/03): composerProjectName will be deprecated and replaced by gitRepoId in the next openapi-generator release"));
@@ -157,10 +153,10 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(PACKAGE_PATH)) {
this.setPackagePath((String) additionalProperties.get(PACKAGE_PATH));
if (additionalProperties.containsKey(PACKAGE_NAME)) {
this.setPackageName((String) additionalProperties.get(PACKAGE_NAME));
} else {
additionalProperties.put(PACKAGE_PATH, packagePath);
additionalProperties.put(PACKAGE_NAME, packageName);
}
if (additionalProperties.containsKey(SRC_BASE_PATH)) {
@@ -240,16 +236,12 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
// make test path available in mustache template
additionalProperties.put("testBasePath", testBasePath);
// // apache v2 license
// supportingFiles.add(new SupportingFile("LICENSE", getPackagePath(), "LICENSE"));
// apache v2 license
// supportingFiles.add(new SupportingFile("LICENSE", "", "LICENSE"));
}
public String getPackagePath() {
return packagePath;
}
public String toPackagePath(String packageName, String basePath) {
return (getPackagePath() + File.separatorChar + toSrcPath(packageName, basePath));
public String getPackageName() {
return packageName;
}
public String toSrcPath(String packageName, String basePath) {
@@ -291,32 +283,32 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
@Override
public String apiFileFolder() {
return (outputFolder + File.separator + toPackagePath(apiPackage, srcBasePath));
return (outputFolder + File.separator + toSrcPath(apiPackage, srcBasePath));
}
@Override
public String modelFileFolder() {
return (outputFolder + File.separator + toPackagePath(modelPackage, srcBasePath));
return (outputFolder + File.separator + toSrcPath(modelPackage, srcBasePath));
}
@Override
public String apiTestFileFolder() {
return (outputFolder + File.separator + getPackagePath() + File.separator + testBasePath + File.separator + apiDirName);
return (outputFolder + File.separator + testBasePath + File.separator + apiDirName);
}
@Override
public String modelTestFileFolder() {
return (outputFolder + File.separator + getPackagePath() + File.separator + testBasePath + File.separator + modelDirName);
return (outputFolder + File.separator + testBasePath + File.separator + modelDirName);
}
@Override
public String apiDocFileFolder() {
return (outputFolder + File.separator + getPackagePath() + File.separator + apiDocPath);
return (outputFolder + File.separator + apiDocPath);
}
@Override
public String modelDocFileFolder() {
return (outputFolder + File.separator + getPackagePath() + File.separator + modelDocPath);
return (outputFolder + File.separator + modelDocPath);
}
@Override
@@ -386,8 +378,8 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
this.artifactVersion = artifactVersion;
}
public void setPackagePath(String packagePath) {
this.packagePath = packagePath;
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public void setSrcBasePath(String srcBasePath) {
@@ -500,6 +492,12 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
operationId = "call_" + operationId;
}
// operationId starts with a number
if (operationId.matches("^\\d.*")) {
LOGGER.warn(operationId + " (starting with a number) cannot be used as method name. Renamed to " + camelize(sanitizeName("call_" + operationId), true));
operationId = "call_" + operationId;
}
return camelize(sanitizeName(operationId), true);
}
@@ -702,6 +700,22 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
return super.escapeText(input).trim();
}
public void escapeMediaType(List<CodegenOperation> operationList) {
for (CodegenOperation op : operationList) {
if (!op.hasProduces) {
continue;
}
List<Map<String, String>> c = op.produces;
for (Map<String, String> mediaType : c) {
// "*/*" causes a syntax error
if ("*/*".equals(mediaType.get("mediaType"))) {
mediaType.put("mediaType", "*_/_*");
}
}
}
}
protected String extractSimpleName(String phpClassName) {
if (phpClassName == null) {
return null;

View File

@@ -18,7 +18,6 @@
package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.NumberSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
import org.apache.commons.lang3.StringUtils;
@@ -157,7 +156,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
@Override
public String toVarName(String name) {
// sanitize name
name = sanitizeName(name);
name = sanitizeName(name, "\\W-[\\$]");
if ("_".equals(name)) {
name = "_u";

View File

@@ -17,65 +17,43 @@
package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.BooleanSchema;
import io.swagger.v3.oas.models.media.ByteArraySchema;
import io.swagger.v3.oas.models.media.EmailSchema;
import io.swagger.v3.oas.models.media.FileSchema;
import io.swagger.v3.oas.models.media.PasswordSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.responses.ApiResponse;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
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 io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.info.*;
import io.swagger.v3.oas.models.OpenAPI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.*;
public class ApexClientCodegen extends AbstractJavaCodegen {
public class ApexClientCodegen extends AbstractApexCodegen {
private static final String CLASS_PREFIX = "classPrefix";
private static final String API_VERSION = "apiVersion";
private static final String BUILD_METHOD = "buildMethod";
private static final String NAMED_CREDENTIAL = "namedCredential";
private static final Logger LOGGER = LoggerFactory.getLogger(ApexClientCodegen.class);
private String classPrefix = "Swag";
private String apiVersion = "39.0";
private String classPrefix = "OAS";
private String apiVersion = "42.0";
private String buildMethod = "sfdx";
private String namedCredential = classPrefix;
private String srcPath = "force-app/main/default/";
private String sfdxConfigPath = "config/";
private HashMap<String, Object> primitiveDefaults = new HashMap<String, Object>();
public ApexClientCodegen() {
super();
importMapping.clear();
testFolder = sourceFolder = srcPath;
embeddedTemplateDir = templateDir = "apex";
outputFolder = "generated-code" + File.separator + "apex";
apiPackage = "classes";
modelPackage = "classes";
modelPackage = apiPackage = srcPath + "classes";
testPackage = "force-app.main.default.classes";
modelNamePrefix = classPrefix;
dateLibrary = "";
apiTemplateFiles.put("api.mustache", ".cls");
apiTemplateFiles.put("cls-meta.mustache", ".cls-meta.xml");
@@ -91,12 +69,12 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
cliOptions.add(CliOption.newString(BUILD_METHOD, "The build method for this package."));
cliOptions.add(CliOption.newString(NAMED_CREDENTIAL, "The named credential name for the HTTP callouts"));
supportingFiles.add(new SupportingFile("Swagger.cls", srcPath + "classes", "Swagger.cls"));
supportingFiles.add(new SupportingFile("cls-meta.mustache", srcPath + "classes", "Swagger.cls-meta.xml"));
supportingFiles.add(new SupportingFile("SwaggerTest.cls", srcPath + "classes", "SwaggerTest.cls"));
supportingFiles.add(new SupportingFile("cls-meta.mustache", srcPath + "classes", "SwaggerTest.cls-meta.xml"));
supportingFiles.add(new SupportingFile("SwaggerResponseMock.cls", srcPath + "classes", "SwaggerResponseMock.cls"));
supportingFiles.add(new SupportingFile("cls-meta.mustache", srcPath + "classes", "SwaggerResponseMock.cls-meta.xml"));
supportingFiles.add(new SupportingFile("OAS.cls", srcPath + "classes", "OAS.cls"));
supportingFiles.add(new SupportingFile("cls-meta.mustache", srcPath + "classes", "OAS.cls-meta.xml"));
supportingFiles.add(new SupportingFile("OASTest.cls", srcPath + "classes", "OASTest.cls"));
supportingFiles.add(new SupportingFile("cls-meta.mustache", srcPath + "classes", "OASTest.cls-meta.xml"));
supportingFiles.add(new SupportingFile("OASResponseMock.cls", srcPath + "classes", "OASResponseMock.cls"));
supportingFiles.add(new SupportingFile("cls-meta.mustache", srcPath + "classes", "OASResponseMock.cls-meta.xml"));
typeMapping.put("BigDecimal", "Double");
typeMapping.put("binary", "String");
@@ -109,14 +87,15 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
typeMapping.put("short", "Integer");
typeMapping.put("UUID", "String");
// https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_reserved_words.htm
setReservedWordsLowerCase(
Arrays.asList("abstract", "activate", "and", "any", "array", "as", "asc", "autonomous",
"begin", "bigdecimal", "blob", "break", "bulk", "by", "byte", "case", "cast",
"catch", "char", "class", "collect", "commit", "const", "continue",
"convertcurrency", "date", "decimal", "default", "delete", "desc", "do", "else",
"convertcurrency", "currency", "date", "datetime", "decimal", "default", "delete", "desc", "do", "else",
"end", "enum", "exception", "exit", "export", "extends", "false", "final",
"finally", "float", "for", "from", "future", "global", "goto", "group", "having",
"hint", "if", "implements", "import", "inner", "insert", "instanceof", "int",
"hint", "if", "implements", "import", "in", "inner", "insert", "instanceof", "int",
"interface", "into", "join", "last_90_days", "last_month", "last_n_days",
"last_week", "like", "limit", "list", "long", "loop", "map", "merge", "new",
"next_90_days", "next_month", "next_n_days", "next_week", "not", "null", "nulls",
@@ -124,7 +103,7 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
"pragma", "private", "protected", "public", "retrieve", "return", "returning",
"rollback", "savepoint", "search", "select", "set", "short", "sort", "stat",
"static", "super", "switch", "synchronized", "system", "testmethod", "then", "this",
"this_month", "this_week", "throw", "today", "tolabel", "tomorrow", "transaction",
"this_month", "this_week", "throw", "time", "today", "tolabel", "tomorrow", "transaction",
"trigger", "true", "try", "type", "undelete", "update", "upsert", "using",
"virtual", "webservice", "when", "where", "while", "yesterday"
));
@@ -133,6 +112,17 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
Arrays.asList("Blob", "Boolean", "Date", "Datetime", "Decimal", "Double", "ID",
"Integer", "Long", "Object", "String", "Time"
));
primitiveDefaults.put("Boolean", true);
primitiveDefaults.put("Decimal", 1);
primitiveDefaults.put("Double", 1);
primitiveDefaults.put("Integer", 1);
primitiveDefaults.put("Long", 1);
primitiveDefaults.put("String", "");
instantiationTypes.put("array", "List");
instantiationTypes.put("map", "Map");
}
@Override
@@ -162,6 +152,48 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
postProcessOpts();
}
@Override
public void preprocessOpenAPI(OpenAPI openAPI) {
Info info = openAPI.getInfo();
String calloutLabel = info.getTitle();
additionalProperties.put("calloutLabel", calloutLabel);
String sanitized = sanitizeName(calloutLabel);
additionalProperties.put("calloutName", sanitized);
supportingFiles.add(new SupportingFile("namedCredential.mustache", srcPath + "/namedCredentials",
sanitized + ".namedCredential-meta.xml"
));
if (additionalProperties.get(BUILD_METHOD).equals("sfdx")) {
generateSfdxSupportingFiles();
} else if (additionalProperties.get(BUILD_METHOD).equals("ant")) {
generateAntSupportingFiles();
}
}
@Override
public String escapeQuotationMark(String input) {
return input.replace("'", "\\'");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String escapeText(String input) {
if (input == null) {
return input;
}
return input.replace("'", "\\'").replace("\n", "\\n").replace("\r", "\\r").replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String toApiName(String name) {
return camelize(classPrefix + super.toApiName(name));
}
@Override
public String escapeReservedWord(String name) {
// Identifiers must start with a letter
@@ -191,16 +223,19 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
} else if (ModelUtils.isBooleanSchema(p)) {
// true => "true", false => "false", null => "null"
out = String.valueOf(((BooleanSchema) p).getDefault());
} else if (ModelUtils.isLongSchema(p)) { // long
out = p.getDefault() == null ? out : p.getDefault().toString() + "L";
} else if (ModelUtils.isLongSchema(p)) {
Long def = (Long) p.getDefault();
out = def == null ? out : def.toString() + "L";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
String s = inner == null ? "Object" : getTypeDeclaration(inner);
out = String.format("new Map<String, %s>()", s);
} else if (ModelUtils.isStringSchema(p)) {
String def = (String) p.getDefault();
if (def != null) {
out = p.getEnum() == null ? String.format("'%s'", escapeText(def)) : def;
if (p.getDefault() != null) {
String def = p.getDefault().toString();
if (def != null) {
out = p.getEnum() == null ? String.format("'%s'", escapeText(def)) : def;
}
}
} else {
out = super.toDefaultValue(p);
@@ -210,256 +245,10 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
return "null".equals(out) ? null : out;
}
@Override
public void setParameterExampleValue(CodegenParameter p) {
String example;
if (p.defaultValue == null) {
example = p.example;
} else {
example = p.defaultValue;
}
String type = p.baseType;
if (type == null) {
type = p.dataType;
}
if (Boolean.TRUE.equals(p.isInteger)) {
if (example == null) {
example = "56";
}
} else if (Boolean.TRUE.equals(p.isLong)) {
if (example == null) {
example = "2147483648L";
}
} else if (Boolean.TRUE.equals(p.isDouble)
|| Boolean.TRUE.equals(p.isFloat)
|| Boolean.TRUE.equals(p.isNumber)) {
if (example == null) {
example = "3.4";
}
} else if (Boolean.TRUE.equals(p.isBoolean)) {
if (Boolean.parseBoolean(p.example)) {
p.example = "1";
} else {
p.example = "0";
}
} else if (Boolean.TRUE.equals(p.isFile) || Boolean.TRUE.equals(p.isBinary)) {
example = "Blob.valueOf('Sample text file\\nContents')";
} else if (Boolean.TRUE.equals(p.isByteArray)) {
if (example == null) {
example = "YmFzZSA2NCBkYXRh";
}
example = "\"" + escapeText(example) + "\"";
} else if (Boolean.TRUE.equals(p.isDate)) {
if (example == null) {
example = "1960, 2, 17";
}
example = "Date.newInstance(" + escapeText(p.example) + ")";
} else if (Boolean.TRUE.equals(p.isDateTime)) {
if (example == null) {
example = "2013, 11, 12, 3, 3, 3";
}
example = "Datetime.newInstanceGmt(" + escapeText(p.example) + ")";
} else if (Boolean.TRUE.equals(p.isString)) {
if (example == null) {
example = p.paramName + "_example";
}
example = "\'" + escapeText(example) + "\'";
} else if (!languageSpecificPrimitives.contains(type)) {
// type is a model class, e.g. User
example = type + ".getExample()";
}
// container
if (Boolean.TRUE.equals(p.isListContainer)) {
example = setPropertyExampleValue(p.items);
example = "new " + p.dataType + "{" + example + "}";
} else if (Boolean.TRUE.equals(p.isMapContainer)) {
example = setPropertyExampleValue(p.items);
example = "new " + p.dataType + "{" + example + "}";
} else if (example == null) {
example = "null";
}
p.example = example;
}
protected String setPropertyExampleValue(CodegenProperty p) {
String example;
if (p == null) {
return "null";
}
if (p.defaultValue == null) {
example = p.example;
} else {
example = p.defaultValue;
}
String type = p.baseType;
if (type == null) {
type = p.dataType;
}
if (Boolean.TRUE.equals(p.isInteger)) {
if (example == null) {
example = "56";
}
} else if (Boolean.TRUE.equals(p.isLong)) {
if (example == null) {
example = "2147483648L";
}
} else if (Boolean.TRUE.equals(p.isDouble)
|| Boolean.TRUE.equals(p.isFloat)
|| Boolean.TRUE.equals(p.isNumber)) {
if (example == null) {
example = "3.4";
}
} else if (Boolean.TRUE.equals(p.isBoolean)) {
if (example == null) {
example = "true";
}
} else if (Boolean.TRUE.equals(p.isFile) || Boolean.TRUE.equals(p.isBinary)) {
if (example == null) {
example = "Blob.valueOf('Sample text file\\nContents')";
}
example = escapeText(example);
} else if (Boolean.TRUE.equals(p.isDate)) {
if (example == null) {
example = "1960, 2, 17";
}
example = "Date.newInstance(" + escapeText(p.example) + ")";
} else if (Boolean.TRUE.equals(p.isDateTime)) {
if (example == null) {
example = "2013, 11, 12, 3, 3, 3";
}
example = "Datetime.newInstanceGmt(" + escapeText(p.example) + ")";
} else if (Boolean.TRUE.equals(p.isString)) {
if (example == null) {
example = p.name + "_example";
}
example = "\'" + escapeText(example) + "\'";
} else if (!languageSpecificPrimitives.contains(type)) {
// type is a model class, e.g. User
example = type + ".getExample()";
}
return example;
}
@Override
public CodegenModel fromModel(String name, Schema model, Map<String, Schema> allDefinitions) {
CodegenModel cm = super.fromModel(name, model, allDefinitions);
if (cm.interfaces == null) {
cm.interfaces = new ArrayList<String>();
}
Boolean hasDefaultValues = false;
// for (de)serializing properties renamed for Apex (e.g. reserved words)
List<Map<String, String>> propertyMappings = new ArrayList<>();
for (CodegenProperty p : cm.allVars) {
hasDefaultValues |= p.defaultValue != null;
if (!p.baseName.equals(p.name)) {
Map<String, String> mapping = new HashMap<>();
mapping.put("externalName", p.baseName);
mapping.put("internalName", p.name);
propertyMappings.add(mapping);
}
}
cm.vendorExtensions.put("hasPropertyMappings", !propertyMappings.isEmpty());
cm.vendorExtensions.put("hasDefaultValues", hasDefaultValues);
cm.vendorExtensions.put("propertyMappings", propertyMappings);
if (!propertyMappings.isEmpty()) {
cm.interfaces.add("Swagger.MappedProperties");
}
return cm;
}
/* the following workaround is no longer needed
@Override
public void postProcessParameter(CodegenParameter parameter) {
if (parameter.isBodyParam && parameter.isListContainer) {
// items of array bodyParams are being nested an extra level too deep for some reason
parameter.items = parameter.items.items;
setParameterExampleValue(parameter);
}
}
*/
@Override
public void preprocessOpenAPI(OpenAPI openAPI) {
Info info = openAPI.getInfo();
String calloutLabel = info.getTitle();
additionalProperties.put("calloutLabel", calloutLabel);
String sanitized = sanitizeName(calloutLabel);
additionalProperties.put("calloutName", sanitized);
supportingFiles.add(new SupportingFile("namedCredential.mustache", srcPath + "/namedCredentials",
sanitized + ".namedCredential"
));
if (additionalProperties.get(BUILD_METHOD).equals("sfdx")) {
generateSfdxSupportingFiles();
} else if (additionalProperties.get(BUILD_METHOD).equals("ant")) {
generateAntSupportingFiles();
}
}
@Override
public CodegenOperation fromOperation(String path,
String httpMethod,
Operation operation,
Map<String, Schema> definitions,
OpenAPI openAPI) {
Boolean hasFormParams = false;
// comment out the following as there's no consume/produce in OAS3.0
// we can move the logic below to postProcessOperations if needed
/*
// only support serialization into JSON and urlencoded forms for now
operation.setConsumes(
Collections.singletonList(hasFormParameter(operation)
? "application/x-www-form-urlencoded"
: "application/json"));
// only support deserialization from JSON for now
operation.setProduces(Collections.singletonList("application/json"));
*/
CodegenOperation op = super.fromOperation(path, httpMethod, operation, definitions, openAPI);
if (op.getHasExamples()) {
// prepare examples for Apex test classes
ApiResponse responseProperty = findMethodResponse(operation.getResponses());
String deserializedExample = toExampleValue(ModelUtils.getSchemaFromResponse(responseProperty));
for (Map<String, String> example : op.examples) {
example.put("example", escapeText(example.get("example")));
example.put("deserializedExample", deserializedExample);
}
}
return op;
}
@Override
public String escapeQuotationMark(String input) {
return input.replace("'", "\\'");
}
public void setBuildMethod(String buildMethod) {
if (buildMethod.equals("ant")) {
this.srcPath = "deploy/";
} else {
this.srcPath = "src/";
}
testFolder = sourceFolder = srcPath;
this.buildMethod = buildMethod;
}
@@ -494,114 +283,6 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
));
}
@Override
public String escapeText(String input) {
if (input == null) {
return input;
}
return input.replace("'", "\\'").replace("\n", "\\n").replace("\r", "\\r");
}
@Override
public String toModelTestFilename(String name) {
return toModelName(name) + "Test";
}
@Override
public String toExampleValue(Schema p) {
if (p == null) {
return "";
}
Object obj = p.getExample();
String example = obj == null ? "" : obj.toString();
if (ModelUtils.isArraySchema(p)) { // array
example = "new " + getTypeDeclaration(p) + "{" + toExampleValue(
((ArraySchema) p).getItems()) + "}";
} else if (ModelUtils.isBooleanSchema(p)) {
example = String.valueOf(!"false".equals(example));
} else if (ModelUtils.isByteArraySchema(p)) { // byte array
if (example.isEmpty()) {
example = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu";
}
((ByteArraySchema) p).setExample(example);
example = "EncodingUtil.base64Decode('" + example + "')";
} else if (ModelUtils.isDateSchema(p)) { // date
if (example.matches("^\\d{4}(-\\d{2}){2}")) {
example = example.substring(0, 10).replaceAll("-0?", ", ");
} else if (example.isEmpty()) {
example = "2000, 1, 23";
} else {
LOGGER.warn(String.format("The example provided for property '%s' is not a valid RFC3339 date. Defaulting to '2000-01-23'. [%s]", p
.getName(), example));
example = "2000, 1, 23";
}
example = "Date.newInstance(" + example + ")";
} else if (ModelUtils.isDateTimeSchema(p)) { // datetime
if (example.matches("^\\d{4}([-T:]\\d{2}){5}.+")) {
example = example.substring(0, 19).replaceAll("[-T:]0?", ", ");
} else if (example.isEmpty()) {
example = "2000, 1, 23, 4, 56, 7";
} else {
LOGGER.warn(String.format("The example provided for property '%s' is not a valid RFC3339 datetime. Defaulting to '2000-01-23T04-56-07Z'. [%s]", p
.getName(), example));
example = "2000, 1, 23, 4, 56, 7";
}
example = "Datetime.newInstanceGmt(" + example + ")";
} else if (ModelUtils.isNumberSchema(p)) { // number
example = example.replaceAll("[^-0-9.]", "");
example = example.isEmpty() ? "1.3579" : example;
} else if (ModelUtils.isFileSchema(p)) { // file
if (example.isEmpty()) {
example = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu";
((FileSchema) p).setExample(example);
}
example = "EncodingUtil.base64Decode(" + example + ")";
} else if (ModelUtils.isEmailSchema(p)) { // email
if (example.isEmpty()) {
example = "example@example.com";
((EmailSchema) p).setExample(example);
}
example = "'" + example + "'";
} else if (ModelUtils.isLongSchema(p)) { // long
example = example.isEmpty() ? "123456789L" : example + "L";
} else if (ModelUtils.isMapSchema(p)) { // map
example = "new " + getTypeDeclaration(p) + "{'key'=>" + toExampleValue(
(Schema) p.getAdditionalProperties()) + "}";
} else if (ModelUtils.isObjectSchema(p)) { // object
example = example.isEmpty() ? "null" : example;
} else if (ModelUtils.isPasswordSchema(p)) { // password
example = example.isEmpty() ? "password123" : escapeText(example);
((PasswordSchema) p).setExample(example);
example = "'" + example + "'";
} else if (!StringUtils.isEmpty(p.get$ref())) {
example = getTypeDeclaration(p) + ".getExample()";
} else if (ModelUtils.isUUIDSchema(p)) {
example = example.isEmpty()
? "'046b6c7f-0b8a-43b9-b35d-6489e6daee91'"
: "'" + escapeText(example) + "'";
} else if (ModelUtils.isStringSchema(p)) { // string
List<String> enums = p.getEnum();
if (enums != null && example.isEmpty()) {
example = enums.get(0);
p.setExample(example);
} else if (example.isEmpty()) {
example = "aeiou";
} else {
example = escapeText(example);
p.setExample(example);
}
example = "'" + example + "'";
}
return example;
}
@Override
public String toApiName(String name) {
return camelize(classPrefix + super.toApiName(name));
}
@Override
public void updateCodegenPropertyEnum(CodegenProperty var) {
super.updateCodegenPropertyEnum(var);
@@ -612,21 +293,6 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
}
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public String getName() {
return "apex";
}
@Override
public String getHelp() {
return "Generates an Apex API client library (beta).";
}
private void generateAntSupportingFiles() {
supportingFiles.add(new SupportingFile("package.mustache", "deploy", "package.xml"));
@@ -638,11 +304,17 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
writeOptional(outputFolder, new SupportingFile("README_ant.mustache", "README.md"));
}
private void generateSfdxSupportingFiles() {
supportingFiles.add(new SupportingFile("sfdx.mustache", "", "sfdx-oss-manifest.json"));
supportingFiles.add(new SupportingFile("sfdx-project-scratch-def.json", sfdxConfigPath, "project-scratch-def.json"));
supportingFiles.add(new SupportingFile("sfdx-project.json.mustache", "sfdx-project.json"));
writeOptional(outputFolder, new SupportingFile("README_sfdx.mustache", "README.md"));
}
}

View File

@@ -603,11 +603,11 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
}
/*
* The pattern spec follows the Perl convention and style of modifiers. .NET
* does not support this syntax directly so we need to convert the pattern to a .NET compatible
* format and apply modifiers in a compatible way.
* See https://msdn.microsoft.com/en-us/library/yd1hzczs(v=vs.110).aspx for .NET options.
*/
* The pattern spec follows the Perl convention and style of modifiers. .NET
* does not support this syntax directly so we need to convert the pattern to a .NET compatible
* format and apply modifiers in a compatible way.
* See https://msdn.microsoft.com/en-us/library/yd1hzczs(v=vs.110).aspx for .NET options.
*/
public void postProcessPattern(String pattern, Map<String, Object> vendorExtensions) {
if (pattern != null) {
int i = pattern.lastIndexOf('/');
@@ -707,7 +707,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
}
// number
if(datatype.startsWith("int") || datatype.startsWith("long") ||
if (datatype.startsWith("int") || datatype.startsWith("long") ||
datatype.startsWith("double") || datatype.startsWith("float")) {
String varName = "NUMBER_" + value;
varName = varName.replaceAll("-", "MINUS_");
@@ -751,13 +751,18 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
public String getNameUsingModelPropertyNaming(String name) {
switch (CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.valueOf(getModelPropertyNaming())) {
case original: return name;
case camelCase: return camelize(name, true);
case PascalCase: return camelize(name);
case snake_case: return underscore(name);
default: throw new IllegalArgumentException("Invalid model property naming '" +
name + "'. Must be 'original', 'camelCase', " +
"'PascalCase' or 'snake_case'");
case original:
return name;
case camelCase:
return camelize(name, true);
case PascalCase:
return camelize(name);
case snake_case:
return underscore(name);
default:
throw new IllegalArgumentException("Invalid model property naming '" +
name + "'. Must be 'original', 'camelCase', " +
"'PascalCase' or 'snake_case'");
}
}

View File

@@ -60,9 +60,9 @@ public class ConfluenceWikiCodegen extends DefaultCodegen implements CodegenConf
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, CodegenConstants.ARTIFACT_VERSION_DESC));
additionalProperties.put("appName", "OpenAPI Sample");
additionalProperties.put("appDescription", "A sample openapi server");
additionalProperties.put("infoUrl", "https://helloreverb.com");
additionalProperties.put("infoEmail", "hello@helloreverb.com");
additionalProperties.put("appDescription", "A sample OpenAPI server");
additionalProperties.put("infoUrl", "https://openapi-generator.tech");
additionalProperties.put("infoEmail", "team@openapitools.org");
additionalProperties.put("licenseInfo", "All rights reserved");
additionalProperties.put("licenseUrl", "http://apache.org/licenses/LICENSE-2.0.html");
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);

View File

@@ -43,9 +43,11 @@ import java.util.Set;
public class CppPistacheServerCodegen extends AbstractCppCodegen {
protected String implFolder = "impl";
protected boolean isAddExternalLibs = false;
protected boolean isAddExternalLibs = true;
public static final String OPTIONAL_EXTERNAL_LIB = "addExternalLibs";
public static final String OPTIONAL_EXTERNAL_LIB_DESC = "Add the Possibility to fetch and compile external Libraries needed by this Framework.";
protected final String PREFIX = "";
@Override
public CodegenType getTag() {
return CodegenType.SERVER;
@@ -63,6 +65,9 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
public CppPistacheServerCodegen() {
super();
if (StringUtils.isEmpty(modelNamePrefix)) {
modelNamePrefix = PREFIX;
}
apiPackage = "org.openapitools.server.api";
modelPackage = "org.openapitools.server.model";
@@ -83,8 +88,8 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
reservedWords = new HashSet<>();
supportingFiles.add(new SupportingFile("modelbase-header.mustache", "model", "ModelBase.h"));
supportingFiles.add(new SupportingFile("modelbase-source.mustache", "model", "ModelBase.cpp"));
supportingFiles.add(new SupportingFile("modelbase-header.mustache", "model", modelNamePrefix + "ModelBase.h"));
supportingFiles.add(new SupportingFile("modelbase-source.mustache", "model", modelNamePrefix + "ModelBase.cpp"));
supportingFiles.add(new SupportingFile("cmake.mustache", "", "CMakeLists.txt"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
@@ -117,7 +122,14 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("modelNamePrefix")) {
additionalProperties().put("prefix", modelNamePrefix);
supportingFiles.clear();
supportingFiles.add(new SupportingFile("modelbase-header.mustache", "model", modelNamePrefix + "ModelBase.h"));
supportingFiles.add(new SupportingFile("modelbase-source.mustache", "model", modelNamePrefix + "ModelBase.cpp"));
supportingFiles.add(new SupportingFile("cmake.mustache", "", "CMakeLists.txt"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
}
additionalProperties.put("modelNamespaceDeclarations", modelPackage.split("\\."));
additionalProperties.put("modelNamespace", modelPackage.replaceAll("\\.", "::"));
additionalProperties.put("apiNamespaceDeclarations", apiPackage.split("\\."));
@@ -129,18 +141,6 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
}
}
/**
* Escapes a reserved word as defined in the `reservedWords` array. Handle
* escaping those terms here. This logic is only called if a variable
* matches the reserved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
}
@Override
public String toModelImport(String name) {
if (importMapping.containsKey(name)) {
@@ -150,6 +150,7 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
}
}
@Override
public CodegenModel fromModel(String name, Schema model, Map<String, Schema> allDefinitions) {
CodegenModel codegenModel = super.fromModel(name, model, allDefinitions);
@@ -245,6 +246,12 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
}
op.vendorExtensions.put("x-codegen-pistache-consumesJson", consumeJson);
op.vendorExtensions.put("x-codegen-pistache-isParsingSupported", isParsingSupported);
for(String hdr : op.imports) {
if(importMapping.containsKey(hdr)) {
continue;
}
additionalProperties.put("hasModelImport", true);
}
}
return objs;
@@ -252,7 +259,7 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
@Override
public String toModelFilename(String name) {
return initialCaps(name);
return initialCaps(toModelName(name));
}
@Override
@@ -277,7 +284,7 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
@Override
public String toApiFilename(String name) {
return initialCaps(name) + "Api";
return modelNamePrefix + initialCaps(name) + "Api";
}
/**
@@ -334,7 +341,7 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
return "0";
}
else if (ModelUtils.isByteArraySchema(p)) {
return "";
return "\"\"";
} else if (ModelUtils.isMapSchema(p)) {
String inner = getSchemaType((Schema) p.getAdditionalProperties());
return "std::map<std::string, " + inner + ">()";
@@ -392,33 +399,6 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
return toModelName(type);
}
@Override
public String toModelName(String type) {
if (typeMapping.keySet().contains(type) || typeMapping.values().contains(type)
|| importMapping.values().contains(type) || defaultIncludes.contains(type)
|| languageSpecificPrimitives.contains(type)) {
return type;
} else {
return Character.toUpperCase(type.charAt(0)) + type.substring(1);
}
}
@Override
public String toApiName(String type) {
return Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api";
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String getTypeDeclaration(String str) {
return toModelName(str);

View File

@@ -251,20 +251,6 @@ public class CppQt5ClientCodegen extends AbstractCppCodegen implements CodegenCo
return "#include \"" + folder + toModelName(name) + ".h\"";
}
/**
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
* those terms here. This logic is only called if a variable matches the reserved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
/**
* Location to write model files. You can use the modelPackage() as defined when the class is
* instantiated
@@ -378,25 +364,6 @@ public class CppQt5ClientCodegen extends AbstractCppCodegen implements CodegenCo
return toModelName(type);
}
@Override
public String toModelName(String type) {
if (type == null) {
LOGGER.warn("Model name can't be null. Default to 'UnknownModel'.");
type = "UnknownModel";
}
if (typeMapping.keySet().contains(type) ||
typeMapping.values().contains(type) ||
importMapping.values().contains(type) ||
defaultIncludes.contains(type) ||
languageSpecificPrimitives.contains(type)) {
return type;
} else {
String typeName = sanitizeName(type);
return modelNamePrefix + Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1);
}
}
@Override
public String toVarName(String name) {
// sanitize name
@@ -424,22 +391,6 @@ public class CppQt5ClientCodegen extends AbstractCppCodegen implements CodegenCo
return toVarName(name);
}
@Override
public String toApiName(String type) {
return modelNamePrefix + Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api";
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
public void setOptionalProjectFileFlag(boolean flag) {
this.optionalProjectFileFlag = flag;
}

View File

@@ -0,0 +1,434 @@
/*
* 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.languages;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.utils.ModelUtils;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.parser.util.SchemaTypeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class CppQt5QHttpEngineServerCodegen extends AbstractCppCodegen implements CodegenConfig {
@SuppressWarnings("unused")
private static final Logger LOGGER = LoggerFactory.getLogger(CppQt5QHttpEngineServerCodegen.class);
public static final String CPP_NAMESPACE = "cppNamespace";
public static final String CPP_NAMESPACE_DESC = "C++ namespace (convention: name::space::for::api).";
protected final String PREFIX = "OAI";
protected final String SRC_DIR = "/src";
protected final String MODEL_DIR = "/src/models";
protected final String APIHANDLER_DIR = "/src/handlers";
protected final String APIREQUEST_DIR = "/src/requests";
protected Set<String> foundationClasses = new HashSet<String>();
// source folder where to write the files
protected String sourceFolder = "server";
protected String apiVersion = "1.0.0";
protected Map<String, String> namespaces = new HashMap<String, String>();
protected Set<String> systemIncludes = new HashSet<String>();
protected String cppNamespace = "OpenAPI";
public CppQt5QHttpEngineServerCodegen() {
super();
// set the output folder here
outputFolder = "generated-code/cpp-qt5-qhttpengine-server";
// set modelNamePrefix as default for QHttpEngine Server
if (StringUtils.isEmpty(modelNamePrefix)) {
modelNamePrefix = PREFIX;
}
/*
* Models. You can write model files using the modelTemplateFiles map.
* if you want to create one template for file, you can do so here.
* for multiple files for model, just put another entry in the `modelTemplateFiles` with
* a different extension
*/
modelTemplateFiles.put(
"model-header.mustache",
".h");
modelTemplateFiles.put(
"model-body.mustache",
".cpp");
/*
* Api classes. You can write classes for each Api file with the apiTemplateFiles map.
* as with models, add multiple entries with different extensions for multiple files per
* class
*/
apiTemplateFiles.put(
"apihandler.h.mustache", // the template to use
".h"); // the extension for each file to write
apiTemplateFiles.put(
"apihandler.cpp.mustache", // the template to use
".cpp"); // the extension for each file to write
apiTemplateFiles.put(
"apirequest.h.mustache", // the template to use
".h"); // the extension for each file to write
apiTemplateFiles.put(
"apirequest.cpp.mustache", // the template to use
".cpp"); // the extension for each file to write
/*
* Template Location. This is the location which templates will be read from. The generator
* will use the resource stream to attempt to read the templates.
*/
embeddedTemplateDir = templateDir = "cpp-qt5-qhttpengine-server";
// CLI options
addOption(CPP_NAMESPACE, CPP_NAMESPACE_DESC, this.cppNamespace);
/*
* Additional Properties. These values can be passed to the templates and
* are available in models, apis, and supporting files
*/
additionalProperties.put("apiVersion", apiVersion);
additionalProperties().put("prefix", PREFIX);
// Write defaults namespace in properties so that it can be accessible in templates.
// At this point command line has not been parsed so if value is given
// in command line it will superseed this content
additionalProperties.put("cppNamespace", cppNamespace);
/*
* Language Specific Primitives. These types will not trigger imports by
* the client generator
*/
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"bool",
"qint32",
"qint64",
"float",
"double")
);
supportingFiles.add(new SupportingFile("helpers-header.mustache", sourceFolder + MODEL_DIR, PREFIX + "Helpers.h"));
supportingFiles.add(new SupportingFile("helpers-body.mustache", sourceFolder + MODEL_DIR, PREFIX + "Helpers.cpp"));
supportingFiles.add(new SupportingFile("object.mustache", sourceFolder + MODEL_DIR, PREFIX + "Object.h"));
supportingFiles.add(new SupportingFile("apirouter.h.mustache", sourceFolder + APIHANDLER_DIR, PREFIX + "ApiRouter.h"));
supportingFiles.add(new SupportingFile("apirouter.cpp.mustache", sourceFolder + APIHANDLER_DIR, PREFIX + "ApiRouter.cpp"));
supportingFiles.add(new SupportingFile("main.cpp.mustache", sourceFolder + SRC_DIR, "main.cpp"));
supportingFiles.add(new SupportingFile("src-CMakeLists.txt.mustache", sourceFolder + SRC_DIR, "CMakeLists.txt"));
supportingFiles.add(new SupportingFile("README.md.mustache", sourceFolder, "README.MD"));
supportingFiles.add(new SupportingFile("Makefile.mustache", sourceFolder, "Makefile"));
supportingFiles.add(new SupportingFile("CMakeLists.txt.mustache", sourceFolder, "CMakeLists.txt"));
supportingFiles.add(new SupportingFile("Dockerfile.mustache", sourceFolder, "Dockerfile"));
supportingFiles.add(new SupportingFile("LICENSE.txt.mustache", sourceFolder, "LICENSE.txt"));
super.typeMapping = new HashMap<String, String>();
typeMapping.put("date", "QDate");
typeMapping.put("DateTime", "QDateTime");
typeMapping.put("string", "QString");
typeMapping.put("integer", "qint32");
typeMapping.put("long", "qint64");
typeMapping.put("boolean", "bool");
typeMapping.put("array", "QList");
typeMapping.put("map", "QMap");
typeMapping.put("object", PREFIX + "Object");
// mapped as "file" type for OAS 3.0
typeMapping.put("ByteArray", "QByteArray");
// UUID support - possible enhancement : use QUuid instead of QString.
// beware though that Serialisation/deserialisation of QUuid does not
// come out of the box and will need to be sorted out (at least imply
// modifications on multiple templates)
typeMapping.put("UUID", "QString");
typeMapping.put("file", "QIODevice");
typeMapping.put("binary", "QIODevice");
importMapping = new HashMap<String, String>();
namespaces = new HashMap<String, String>();
foundationClasses.add("QString");
systemIncludes.add("QString");
systemIncludes.add("QList");
systemIncludes.add("QMap");
systemIncludes.add("QDate");
systemIncludes.add("QDateTime");
systemIncludes.add("QByteArray");
systemIncludes.add("QIODevice");
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("cppNamespace")) {
cppNamespace = (String) additionalProperties.get("cppNamespace");
}
additionalProperties.put("cppNamespaceDeclarations", cppNamespace.split("\\::"));
if (additionalProperties.containsKey("modelNamePrefix")) {
supportingFiles.clear();
supportingFiles.add(new SupportingFile("helpers-header.mustache", sourceFolder + MODEL_DIR, modelNamePrefix + "Helpers.h"));
supportingFiles.add(new SupportingFile("helpers-body.mustache", sourceFolder + MODEL_DIR, modelNamePrefix + "Helpers.cpp"));
supportingFiles.add(new SupportingFile("object.mustache", sourceFolder + MODEL_DIR, modelNamePrefix + "Object.h"));
supportingFiles.add(new SupportingFile("apirouter.h.mustache", sourceFolder + APIHANDLER_DIR, modelNamePrefix + "ApiRouter.h"));
supportingFiles.add(new SupportingFile("apirouter.cpp.mustache", sourceFolder + APIHANDLER_DIR, modelNamePrefix + "ApiRouter.cpp"));
supportingFiles.add(new SupportingFile("main.cpp.mustache", sourceFolder + SRC_DIR, "main.cpp"));
supportingFiles.add(new SupportingFile("src-CMakeLists.txt.mustache", sourceFolder + SRC_DIR, "CMakeLists.txt"));
supportingFiles.add(new SupportingFile("README.md.mustache", sourceFolder, "README.MD"));
supportingFiles.add(new SupportingFile("Makefile.mustache", sourceFolder, "Makefile"));
supportingFiles.add(new SupportingFile("CMakeLists.txt.mustache", sourceFolder, "CMakeLists.txt"));
supportingFiles.add(new SupportingFile("Dockerfile.mustache", sourceFolder, "Dockerfile"));
supportingFiles.add(new SupportingFile("LICENSE.txt.mustache", sourceFolder, "LICENSE.txt"));
typeMapping.put("object", modelNamePrefix + "Object");
additionalProperties().put("prefix", modelNamePrefix);
}
}
/**
* Configures the type of generator.
*
* @return the CodegenType for this generator
* @see org.openapitools.codegen.CodegenType
*/
@Override
public CodegenType getTag() {
return CodegenType.SERVER;
}
/**
* Configures a friendly name for the generator. This will be used by the generator
* to select the library with the -g flag.
*
* @return the friendly name for the generator
*/
@Override
public String getName() {
return "cpp-qt5-qhttpengine-server";
}
/**
* Returns human-friendly help for the generator. Provide the consumer with help
* tips, parameters here
*
* @return A string value for the help message
*/
@Override
public String getHelp() {
return "Generates a Qt5 C++ Server (beta) using the QHTTPEngine HTTP Library.";
}
@Override
public String toModelImport(String name) {
if( name.isEmpty() ) {
return null;
}
if (namespaces.containsKey(name)) {
return "using " + namespaces.get(name) + ";";
} else if (systemIncludes.contains(name)) {
return "#include <" + name + ">";
}
String folder = modelPackage().replace("::", File.separator);
if (!folder.isEmpty())
folder += File.separator;
return "#include \"" + folder + name + ".h\"";
}
/**
* Location to write model files. You can use the modelPackage() as defined when the class is
* instantiated
*/
@Override
public String modelFileFolder() {
return outputFolder + "/" + sourceFolder + MODEL_DIR + "/" + modelPackage().replace("::", File.separator);
}
/**
* Location to write api files. You can use the apiPackage() as defined when the class is
* instantiated
*/
@Override
public String apiFileFolder() {
return outputFolder + "/" + sourceFolder + APIHANDLER_DIR + "/" + apiPackage().replace("::", File.separator);
}
private String requestFileFolder() {
return outputFolder + "/" + sourceFolder + APIREQUEST_DIR + "/" + apiPackage().replace("::", File.separator);
}
@Override
public String toModelFilename(String name) {
return modelNamePrefix + initialCaps(name);
}
@Override
public String apiFilename(String templateName, String tag) {
String result = super.apiFilename(templateName, tag);
if (templateName.contains("apirequest")) {
result = result.replace("ApiHandler", "ApiRequest");
result = result.replace(apiFileFolder(), requestFileFolder());
}
return result;
}
@Override
public String toApiFilename(String name) {
return modelNamePrefix + initialCaps(name) + "ApiHandler";
}
/**
* Optional - type declaration. This is a String which is used by the templates to instantiate your
* types. There is typically special handling for different property types
*
* @return a string value used as the `dataType` field for model templates, `returnType` for api templates
*/
@Override
@SuppressWarnings("rawtypes")
public String getTypeDeclaration(Schema p) {
String openAPIType = getSchemaType(p);
if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Schema inner = ap.getItems();
return getSchemaType(p) + "<" + getTypeDeclaration(inner) + ">";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
return getSchemaType(p) + "<QString, " + getTypeDeclaration(inner) + ">";
} else if (ModelUtils.isBinarySchema(p)) {
return getSchemaType(p) + "*";
} else if (ModelUtils.isFileSchema(p)) {
return getSchemaType(p) + "*";
}
if (foundationClasses.contains(openAPIType)) {
return openAPIType;
} else if (languageSpecificPrimitives.contains(openAPIType)) {
return toModelName(openAPIType);
} else {
return openAPIType;
}
}
@Override
@SuppressWarnings("rawtypes")
public String toDefaultValue(Schema p) {
if (ModelUtils.isBooleanSchema(p)) {
return "false";
} else if (ModelUtils.isDateSchema(p)) {
return "NULL";
} else if (ModelUtils.isDateTimeSchema(p)) {
return "NULL";
} else if (ModelUtils.isNumberSchema(p)) {
if (SchemaTypeUtil.FLOAT_FORMAT.equals(p.getFormat())) {
return "0.0f";
}
return "0.0";
} else if (ModelUtils.isIntegerSchema(p)) {
if (SchemaTypeUtil.INTEGER64_FORMAT.equals(p.getFormat())) {
return "0L";
}
return "0";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
return "QMap<QString, " + getTypeDeclaration(inner) + ">()";
} else if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Schema inner = ap.getItems();
return "QList<" + getTypeDeclaration(inner) + ">()";
} else if (ModelUtils.isStringSchema(p)) {
return "QString(\"\")";
} else if (!StringUtils.isEmpty(p.get$ref())) {
return toModelName(ModelUtils.getSimpleRef(p.get$ref())) + "()";
}
return "NULL";
}
/**
* Optional - OpenAPI type conversion. This is used to map OpenAPI types in a `Schema` into
* either language specific types via `typeMapping` or into complex models if there is not a mapping.
*
* @return a string value of the type or complex model for this property
*/
@Override
@SuppressWarnings("rawtypes")
public String getSchemaType(Schema p) {
String openAPIType = super.getSchemaType(p);
String type = null;
if (typeMapping.containsKey(openAPIType)) {
type = typeMapping.get(openAPIType);
if (languageSpecificPrimitives.contains(type)) {
return toModelName(type);
}
if (foundationClasses.contains(type)) {
return type;
}
} else {
type = openAPIType;
}
return toModelName(type);
}
@Override
public String toVarName(String name) {
// sanitize name
String varName = name;
varName = sanitizeName(name);
// if it's all uppper case, convert to lower case
if (varName.matches("^[A-Z_]*$")) {
varName = varName.toLowerCase();
}
// camelize (lower first character) the variable name
// petId => pet_id
varName = underscore(varName);
// for reserved word or word starting with number, append _
if (isReservedWord(varName) || varName.matches("^\\d.*")) {
varName = escapeReservedWord(varName);
}
return varName;
}
@Override
public String toParamName(String name) {
return toVarName(name);
}
@Override
public String getTypeDeclaration(String str) {
return str;
}
}

View File

@@ -157,7 +157,7 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
typeMapping.put("binary", "std::string");
typeMapping.put("number", "double");
typeMapping.put("UUID", "utility::string_t");
typeMapping.put("ByteArray", "utility::string_t");
typeMapping.put("ByteArray", "utility::string_t");
super.importMapping = new HashMap<String, String>();
importMapping.put("std::vector", "#include <vector>");
@@ -200,6 +200,7 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
* Location to write model files. You can use the modelPackage() as defined
* when the class is instantiated
*/
@Override
public String modelFileFolder() {
return outputFolder + "/model";
}
@@ -218,7 +219,7 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
if (importMapping.containsKey(name)) {
return importMapping.get(name);
} else {
return "#include \"" + name + ".h\"";
return "#include \"" + sanitizeName(name) + ".h\"";
}
}
@@ -281,12 +282,12 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
@Override
public String toModelFilename(String name) {
return initialCaps(name);
return sanitizeName(initialCaps(name));
}
@Override
public String toApiFilename(String name) {
return initialCaps(name) + "Api";
return sanitizeName(initialCaps(name) + "Api");
}
/**
@@ -388,33 +389,6 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
return toModelName(type);
}
@Override
public String toModelName(String type) {
if (typeMapping.keySet().contains(type) || typeMapping.values().contains(type)
|| importMapping.values().contains(type) || defaultIncludes.contains(type)
|| languageSpecificPrimitives.contains(type)) {
return type;
} else {
return Character.toUpperCase(type.charAt(0)) + type.substring(1);
}
}
@Override
public String toApiName(String type) {
return Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api";
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public Map<String, Object> postProcessAllModels(final Map<String, Object> models) {

View File

@@ -90,6 +90,7 @@ public class CppRestbedServerCodegen extends AbstractCppCodegen {
typeMapping.put("binary", "restbed::Bytes");
typeMapping.put("number", "double");
typeMapping.put("UUID", "std::string");
typeMapping.put("ByteArray", "std::string");
super.importMapping = new HashMap<String, String>();
importMapping.put("std::vector", "#include <vector>");
@@ -148,18 +149,6 @@ public class CppRestbedServerCodegen extends AbstractCppCodegen {
additionalProperties.put("defaultInclude", defaultInclude);
}
/**
* Escapes a reserved word as defined in the `reservedWords` array. Handle
* escaping those terms here. This logic is only called if a variable
* matches the reserved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
}
/**
* Location to write model files. You can use the modelPackage() as defined
* when the class is instantiated
@@ -283,6 +272,8 @@ public class CppRestbedServerCodegen extends AbstractCppCodegen {
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
return getSchemaType(p) + "<std::string, " + getTypeDeclaration(inner) + ">";
} else if (ModelUtils.isByteArraySchema(p)) {
return "std::string";
} else if (ModelUtils.isStringSchema(p)
|| ModelUtils.isDateSchema(p)
|| ModelUtils.isDateTimeSchema(p) || ModelUtils.isFileSchema(p)
@@ -313,6 +304,8 @@ public class CppRestbedServerCodegen extends AbstractCppCodegen {
return "0L";
}
return "0";
} else if (ModelUtils.isByteArraySchema(p)) {
return "\"\"";
} else if (ModelUtils.isMapSchema(p)) {
String inner = getSchemaType((Schema) p.getAdditionalProperties());
return "std::map<std::string, " + inner + ">()";
@@ -361,33 +354,4 @@ public class CppRestbedServerCodegen extends AbstractCppCodegen {
type = openAPIType;
return toModelName(type);
}
@Override
public String toModelName(String type) {
if (typeMapping.keySet().contains(type) || typeMapping.values().contains(type)
|| importMapping.values().contains(type) || defaultIncludes.contains(type)
|| languageSpecificPrimitives.contains(type)) {
return type;
} else {
return Character.toUpperCase(type.charAt(0)) + type.substring(1);
}
}
@Override
public String toApiName(String type) {
return Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api";
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
}

View File

@@ -32,7 +32,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
public class CppTizenClientCodegen extends DefaultCodegen implements CodegenConfig {
public class CppTizenClientCodegen extends AbstractCppCodegen implements CodegenConfig {
protected static String PREFIX = "ArtikCloud";
protected String sourceFolder = "src";
protected String documentationFolder = "doc";
@@ -270,14 +270,6 @@ public class CppTizenClientCodegen extends DefaultCodegen implements CodegenConf
return "" + paramName;
}
@Override
public String escapeReservedWord(String name) {
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@Override
public String toOperationId(String operationId) {
// throw exception if method name is empty
@@ -293,16 +285,13 @@ public class CppTizenClientCodegen extends DefaultCodegen implements CodegenConf
// add_pet_by_id => addPetById
return camelize(operationId, true);
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
/**
* Output the Getter name for boolean property, e.g. getActive
*
* @param name the name of the property
* @return getter name based on naming convention
*/
public String toBooleanGetter(String name) {
return "get" + getterAndSetterCapitalize(name);
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
}

View File

@@ -523,25 +523,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
}
}
@SuppressWarnings("unchecked")
@Override
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
Map<String, Object> allProcessedModels = super.postProcessAllModels(objs);
if (!additionalProperties.containsKey("gsonFactoryMethod")) {
List<Object> allModels = new ArrayList<Object>();
for (String name : allProcessedModels.keySet()) {
Map<String, Object> models = (Map<String, Object>) allProcessedModels.get(name);
try {
allModels.add(((List<Object>) models.get("models")).get(0));
} catch (Exception e) {
e.printStackTrace();
}
}
additionalProperties.put("parent", modelInheritanceSupportInGson(allModels));
}
return allProcessedModels;
}
@Override
public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
objs = super.postProcessModelsEnum(objs);
@@ -564,34 +545,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
return objs;
}
public static List<Map<String, Object>> modelInheritanceSupportInGson(List<?> allModels) {
Map<CodegenModel, List<CodegenModel>> byParent = new LinkedHashMap<>();
for (Object model : allModels) {
Map entry = (Map) model;
CodegenModel parent = ((CodegenModel)entry.get("model")).parentModel;
if(null!= parent) {
byParent.computeIfAbsent(parent, k -> new LinkedList<>()).add((CodegenModel)entry.get("model"));
}
}
List<Map<String, Object>> parentsList = new ArrayList<>();
for (CodegenModel parentModel : byParent.keySet()) {
List<Map<String, Object>> childrenList = new ArrayList<>();
Map<String, Object> parent = new HashMap<>();
parent.put("classname", parentModel.classname);
List<CodegenModel> childrenModels = byParent.get(parentModel);
for (CodegenModel model : childrenModels) {
Map<String, Object> child = new HashMap<>();
child.put("name", model.name);
child.put("classname", model.classname);
childrenList.add(child);
}
parent.put("children", childrenList);
parent.put("discriminator", parentModel.discriminator);
parentsList.add(parent);
}
return parentsList;
}
public void setUseRxJava(boolean useRxJava) {
this.useRxJava = useRxJava;
doNotUseRx = false;

View File

@@ -18,7 +18,6 @@
package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.Operation;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenConstants;
@@ -42,7 +41,9 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
private boolean interfaceOnly = false;
private boolean returnResponse = false;
private boolean generatePom = true;
private String primaryResourceName;
public JavaJAXRSSpecServerCodegen() {
super();
invokerPackage = "org.openapitools.api";
@@ -147,19 +148,26 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
if (pos > 0) {
basePath = basePath.substring(0, pos);
}
String operationKey = basePath;
if (StringUtils.isEmpty(basePath)) {
basePath = "default";
basePath = tag;
operationKey = "";
primaryResourceName = tag;
} else if (basePath.matches("\\{.*\\}")) {
basePath = tag;
operationKey = "";
co.subresourceOperation = true;
} else {
if (co.path.startsWith("/" + basePath)) {
co.path = co.path.substring(("/" + basePath).length());
}
co.subresourceOperation = !co.path.isEmpty();
}
List<CodegenOperation> opList = operations.get(basePath);
List<CodegenOperation> opList = operations.get(operationKey);
if (opList == null || opList.isEmpty()) {
opList = new ArrayList<CodegenOperation>();
operations.put(basePath, opList);
operations.put(operationKey, opList);
}
opList.add(co);
co.baseName = basePath;
@@ -186,4 +194,14 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
public String getHelp() {
return "Generates a Java JAXRS Server according to JAXRS 2.0 specification.";
}
@Override
public String toApiName(final String name) {
String computed = name;
if (computed.length() == 0) {
return primaryResourceName + "Api";
}
computed = sanitizeName(computed);
return camelize(computed) + "Api";
}
}

Some files were not shown because too many files have changed in this diff Show More