Compare commits

..

1 Commits

Author SHA1 Message Date
William Cheng
bb51faa1f7 unalias body parameters 2018-12-11 00:23:12 +08:00
4403 changed files with 38816 additions and 133628 deletions

View File

@@ -1,117 +0,0 @@
let fs = require('fs');
let path = require('path');
let util = require('util');
let yaml = require('./js-yaml.js');
let samples = require('./samples.json');
class LabelMatch {
constructor (match, label) {
this.match = match;
this.label = label;
}
}
class FileError {
constructor (file, actualLabels, expectedLabels) {
this.file = file;
this.actual = actualLabels;
this.expected = expectedLabels;
}
}
class TextError {
constructor (text, actualLabels, expectedLabels) {
this.text = text;
this.actual = actualLabels;
this.expected = expectedLabels;
}
}
let labels = [];
function labelsForFile(file) {
let body = fs.readFileSync(file);
return labelsForText(body)
}
function labelsForText(text) {
let addLabels = new Set();
let body = text;
for (const v of labels) {
if (v.match.test(body)) {
addLabels.add(v.label)
}
// reset regex state
v.match.lastIndex = 0
}
return addLabels;
}
try {
let config = yaml.safeLoad(fs.readFileSync('../auto-labeler.yml', 'utf8'));
if (config && config.labels && Object.keys(config.labels).length > 0) {
for (const labelName in config.labels) {
if (config.labels.hasOwnProperty(labelName)) {
let matchAgainst = config.labels[labelName];
if (Array.isArray(matchAgainst)) {
matchAgainst.forEach(regex => {
// noinspection JSCheckFunctionSignatures
labels.push(new LabelMatch(new RegExp(regex, 'g'), labelName));
})
}
}
}
}
if (labels.length === 0) {
// noinspection ExceptionCaughtLocallyJS
throw new Error("Expected to parse config.labels, but failed.")
}
let fileErrors = [];
samples.files.forEach(function(tester){
let file = path.normalize(path.join('..', '..', 'bin', tester.input));
let expectedLabels = new Set(tester.matches);
let actualLabels = labelsForFile(file);
let difference = new Set([...actualLabels].filter(x => !expectedLabels.has(x)));
if (difference.size > 0) {
fileErrors.push(new FileError(file, actualLabels, expectedLabels));
}
});
let textErrors = [];
samples.text.forEach(function(tester){
let expectedLabels = new Set(tester.matches);
let actualLabels = labelsForText(tester.input);
let difference = new Set([...actualLabels].filter(x => !expectedLabels.has(x)));
if (difference.size > 0) {
textErrors.push(new TextError(tester.input, actualLabels, expectedLabels));
}
});
// These are separate (file vs text) in case we want to preview where these would fail in the file. not priority at the moment.
if (fileErrors.length > 0) {
console.warn('There were %d file tester errors', fileErrors.length);
fileErrors.forEach(function(errs) {
console.log("file: %j\n actual: %j\n expected: %j", errs.file, util.inspect(errs.actual), util.inspect(errs.expected))
});
}
if (textErrors.length > 0) {
console.warn('There were %d text tester errors', textErrors.length);
textErrors.forEach(function(errs){
console.log("input: %j\n actual: %j\n expected: %j", errs.text, util.inspect(errs.actual), util.inspect(errs.expected))
})
}
let totalErrors = fileErrors.length + textErrors.length;
if (totalErrors === 0) {
console.log('Success!');
} else {
console.log('Failure: %d total errors', totalErrors);
}
} catch (e) {
console.log(e);
}

3917
.github/.test/js-yaml.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -7,14 +7,6 @@ assignees: ''
---
#### Bug Report Checklist
- [ ] Have you provided a full/minimal spec to reproduce the issue?
- [ ] What's the version of OpenAPI Generator used?
- [ ] Have you search for related issues/PRs?
- [ ] What's the actual output vs expected output?
- [ ] [Optional] Bounty to sponsor the fix ([example](https://www.bountysource.com/issues/66123212-javascript-client-produces-a-wrong-object-for-a-string-enum-type-that-is-used-with-ref))
<!--
Please follow the issue template below for bug reports.
Also please indicate in the issue title which language/library is concerned. Eg: [BUG][JAVA] Bug generating foo with bar

View File

@@ -1,290 +0,0 @@
comment: |
👍 Thanks for opening this issue!
🏷 I have applied any labels matching special text in your issue.
The team will review the labels and make any necessary changes.
labels:
'Announcement':
- '\s*?\[[Aa]nnouncement\]\s*?'
'Breaking change (with fallback)':
- '\s*?[bB]reaking [cC]hange [wW]ith [fF]allback\s*?'
'Breaking change (without fallback)':
- '\s*?[bB]reaking [cC]hange [wW]ithout [fF]allback\s*?'
'Client: Ada':
- '\s*?\[ada\]\s*?'
- '\s*?-[gl] ada(?!-)\b'
'Client: Android':
- '\s*?\[android\]\s*?'
- '\s*?-[gl] android(?!-)\b'
'Client: Apex':
- '\s*?\[apex\]\s*?'
- '\s*?-[gl] apex(?!-)\b'
'Client: Bash':
- '\s*?\[bash\]\s*?'
- '\s*?-[gl] bash(?!-)\b'
'Client: C':
- '\s*?\[[cC]\]\s*?'
- '\s*?-[gl] c(?!-)\b'
# 'Client: Ceylon':
'Client: C++':
- '\s*?\[cpp(-.*)?-client\]\s*?'
- '\s*?-[gl] cpp(-.*)?-client\s*?'
- '\s*?-[gl] cpp-restsdk(?!-)\b'
- '\s*?-[gl] cpp-tizen(?!-)\b'
'Client: C-Sharp':
- '\s*?-[gl] csharp(?!-)\b'
- '\s*?[cC]-[sS]harp [cC]lient\s*?'
- '\s*?-[gl] csharp-dotnet2\s*?'
- '\s*?-[gl] csharp-refactor?\s*?'
- '\s*?\[[Cc]#\]'
- '\s*?\[csharp\]\s*?'
'Client: Clojure':
- '\s*?\[clojure\]\s*?'
- '\s*?-[gl] clojure(?!-)\b'
# 'Client: Crystal':
'Client: Dart':
- '\s*?\[dart\]\s*?'
- '\s*?-[gl] dart(?!-)\b'
'Client: Dukescript':
- '\s*?\[dukescript\]\s*?'
- '\s*?-g dukescript\s*?'
'Client: Eiffel':
- '\s*?\[eiffel\]\s*?'
- '\s*?-[gl] eiffel(?!-)\b'
'Client: Elixir':
- '\s*?\[elixir\]\s*?'
- '\s*?-[gl] elixir(?!-)\b'
'Client: Elm':
- '\s*?\[elm\]\s*?'
- '\s*?-[gl] elm(?!-)\b'
'Client: Erlang':
- '\s*?\[erlang(-.*)?-client\]\s*?'
- '\s*?-[gl] erlang(-.*)?-client\s*?'
- '\s*?\[erlang-proper\]\s*?'
- '\s*?-[gl] erlang-proper\s*?'
'Client: Flash/ActionScript':
- '\s*?\[flash\]\s*?'
- '\s*?-[gl] flash(?!-)\b'
'Client: Go':
- '\s*?\[go\]\s*?'
- '\s*?-[gl] go(?!-)\b'
'Client: Groovy':
- '\s*?\[groovy\]\s*?'
- '\s*?-[gl] groovy(?!-)\b'
'Client: HTML':
- '\s*?\[html[2]?\]\s*?'
- '\s*?-[gl] html[2]?\s*?'
'Client: Haskell':
- '\s*?\[haskell(-.*)?-client\]\s*?'
- '\s*?-[gl] haskell(-.*)?-client\s*?'
'Client: JMeter':
- '\s*?\[jmeter\]\s*?'
- '\s*?-[gl] jmeter\s*?'
'Client: Java':
- '\s*?\[java\]\s*?'
- '\s*?-[gl] java(?!-)\b'
'Client: JavaScript/Node.js':
- '\s*?\[javascript\]\s*?'
- '\s*?-[gl] javascript\s*?'
- '\s*?-[gl] javascript-(\S)*\s*?'
# 'Client: Julia': # NOTE: Not yet implemented
'Client: Kotlin':
- '\s*?\[kotlin\]\s*?'
- '\s*?-[gl] kotlin(?!-)\b'
'Client: Lisp':
- '\s*?\[lisp\]\s*?'
- '\s*?-[gl] lisp(?!-)\b'
'Client: Lua':
- '\s*?\[lua\]\s*?'
- '\s*?-[gl] lua(?!-)\b'
'Client: Objc':
- '\s*?\[objc\]\s*?'
- '\s*?-[gl] objc\s*?'
# 'Client: OCaml':
'Client: Perl':
- '\s*?\[perl\]\s*?'
- '\s*?-[gl] perl(?!-)\b'
# 'Client: PHP':
'Client: PowerShell':
- '\s*?\[powershell\]\s*?'
- '\s*?-[gl] powershell\s*?'
'Client: Python':
- '\s*?\[python\]\s*?'
- '\s*?-[gl] python(?!-)\b'
'Client: QT':
- '\s*?\[cpp-qt5-client\]\s*?'
- '\s*?-[gl] cpp-qt5-client\s*?'
'Client: R':
- '\s*?\[[rR]\]\s*?'
- '\s*?-[gl] r(?!-)\b'
'Client: Reason ML':
- '\s*?\[reasonml\]\s*?'
- '\s*?-[g] reasonml\s*?'
'Client: Retrofit':
- '\s*?retrofit.*?\s*?'
'Client: Ruby':
- '\s*?\[ruby\]\s*?'
- '\s*?-[gl] ruby(?!-)\b'
'Client: Rust':
- '\s*?\[rust\]\s*?'
- '\s*?-[gl] rust(?!-)\b'
'Client: Scala':
- '\s*?\[scalaz\]\s*?'
- '\s*?-[gl] scalaz\s*?'
- '\s*?\[scala-(?!finch)[a-z]+\]\b'
- '\s*?-[gl] scala-(?!finch)[a-z]+?(?!-)\b'
'Client: Swift':
- '\s*?\[swift[34]+\]\s*?'
- '\s*?-[gl] swift[34]+\s*?'
- '\s*?-[gl] swift2-deprecated\s*?'
'Client: TypeScript':
- '\s*?\[typescript-[\-a-z]+\]\s*?'
- '\s*?-[gl] typescript-[\-a-z]+\s*?'
# 'Client: VB/VB.net': # NOTE: Not yet implemented
# 'Client: Visual Basic': # TODO: REMOVE UNUSED LABEL
'Config: Apache':
- '\s*?\[apache2\]\s*?'
- '\s*?-[gl] apache2\s*?'
'Docker':
- '\s*?\[docker\]\s*?'
'Documentation: Cwiki':
- '\s*?\[cwiki\]\s*?'
- '\s*?-[gl] cwiki\s*?'
'Documentation: Dynamic HTML':
- '\s*?\[dynamic-html\]\s*?'
- '\s*?-[gl] dynamic-html\s*?'
'Enhancement: CI/Test':
- '\s*?\[ci\]\s*?'
'Enhancement: Code format':
- '\s*?\[format(ting)?\]\s*?'
# 'Enhancement: Compatibility':
'Enhancement: Feature':
- '\s*?\[feat(ure)?s*?'
'Enhancement: General':
- '\s*?\[general\]\s*?'
- '\s*?\[core\]\s*?'
# 'Enhancement: New generator':
'Enhancement: Performance':
- '\s*?\[perf\]\s*?'
# 'Feature List: API clients':
# 'Feature List: API documentations':
# 'Feature List: API servers':
# 'Feature: Authentication':
# 'Feature: Composition / Inheritance':
# 'Feature: Documentation':
# 'Feature: Enum':
# 'Feature: Generator':
'Feature: OAS 3.0 spec support':
- '\s*?\[oas3[\.0]?\]\s*?'
# 'General: Awaiting feedback':
'General: Discussion':
- '\s*?\[discussion\]\s*?'
'General: Question':
- '\s*?\[question\]\s*?'
'General: Suggestion':
- '\s*?\[suggestion\]\s*?'
'General: Support':
- '\s*?\[support\]\s*?'
'Issue: Bug':
- '\s*?\[bug(s)?\]\s*?'
- '\s*?\[fix(es)?\]\s*?'
# 'Issue: Invalid spec':
# 'Issue: Migration':
# 'Issue: Non-operational':
# 'Issue: Platform':
# 'Issue: Regression':
'Issue: Security':
- '\s*?\[security\]\s*?'
# 'Issue: Unable to reproduce':
# 'Issue: Undo changes':
# 'Issue: Usage/Installation':
# 'Issue: Workaround available':
'OpenAPI Generator CLI':
- '\s*?\[cli\]\s*?'
'OpenAPI Generator Gradle Plugin':
- '\s*?\[gradle\]\s*?'
'OpenAPI Generator Maven Plugin':
- '\s*?\[maven\]\s*?'
'OpenAPI Generator Online':
- '\s*?\[online\]\s*?'
'Schema: MySQL':
- '\s*?\[mysql\]\s*?'
- '\s*?-[gl] mysql\s*?'
'Schema: GraphQL':
- '\s*?\[graphql-schema\]\s*?'
- '\s*?-[gl] graphql-schema\s*?'
'Server: Ada':
- '\s*?\[ada(-.*)?-server\]\s*?'
- '\s*?-[gl] ada(-.*)?-server\s*?'
'Server: C++':
- '\s*?\[cpp(-.*)?-server\]\s*?'
- '\s*?-[gl] cpp(-.*)?-server\s*?'
'Server: C-Sharp':
- '\s*?\[aspnetcore\]\s*?'
- '\s*?-[gl] aspnetcore\s*?'
- '\s*?\[csharp-nancyfx\]\s*?'
- '\s*?-[gl] csharp-nancyfx\s*?'
# 'Server: Ceylon': # TODO: REMOVE UNUSED LABEL
'Server: Eiffel':
- '\s*?\[eiffel(-.*)?-server\]\s*?'
- '\s*?-[gl] eiffel(-.*)?-server\s*?'
'Server: Elixir':
- '\s*?\[elixir(-.*)?-server\]\s*?'
- '\s*?-[gl] elixir(-.*)?-server\s*?'
'Server: Erlang':
- '\s*?\[erlang-server\]\s*?'
- '\s*?-[gl] erlang-server\s*?'
'Server: Go':
- '\s*?\[go(-.*)?-server\]\s*?'
- '\s*?-[gl] go(-.*)?-server\s*?'
'Server: GraphQL':
- '\s*?\[graphql(-.*)?-server\]\s*?'
- '\s*?-[gl] graphql(-.*)?-server\s*?'
'Server: Haskell':
- '\s*?\[haskell]\s*?'
- '\s*?-[gl] haskell(?!-)\b'
'Server: Java':
- '\s*?\[java-.*?\]\s*?'
- '\s*?-[gl] java-.*?\s*?'
- '\s*?-[gl] jaxrx-.*?\s*?'
'Server: Kotlin':
- '\s*?\[ktor]\s*?'
- '\s*?\[kotlin-spring]\s*?'
- '\s*?\[kotlin(-.*)?-server\]\s*?'
- '\s*?-[gl] kotlin(-.*)?-server\s*?'
- '\s*?-[gl] kotlin-spring\s*?'
'Server: Nodejs':
- '\s*?\[nodejs(-.*)?-server\]\s*?'
- '\s*?-[gl] nodejs(-.*)?-server\s*?'
'Server: PHP':
- '\s*?\[php-.*?\]\s*?'
- '\s*?-[gl] php-.*?\s*?'
'Server: Perl':
- '\s*?\[perl(-.*)?-server\]\s*?'
- '\s*?-g perl(-.*)?-server\s*?'
'Server: Python':
- '\s*?\[python-.*?\]\s*?'
- '\s*?-[gl] python-.*?\s*?'
'Server: Ruby':
- '\s*?\[ruby-.*?\]\s*?'
- '\s*?-[gl] ruby-.*?\s*?'
'Server: Rust':
- '\s*?\[rust(-.*)?-server\]\s*?'
- '\s*?-[gl] rust(-.*)?-server\s*?'
'Server: Scala':
- '\s*?\[scala(-.*)?-server\]\s*?'
- '\s*?-[gl] scala(-.*)?-server\s*?'
- '\s*?\[scalatra\]\s*?'
- '\s*?-[gl] scalatra\s*?'
- '\s*?\[scala-finch\]\s*?'
- '\s*?-[gl] scala-finch\s*?'
'Server: Spring':
- '\s*?\[spring\]\s*?'
- '\s*?-[g] spring\s*?'
# 'Swagger-Parser':
'WIP':
- '\s*?\[wip\]\s*?'
- '\s*?\[WIP\]\s*?'
- '\bWIP:.*?'
'help wanted':
- '\s*?\[help wanted\]\s*?'

5
.gitignore vendored
View File

@@ -27,7 +27,6 @@ packages/
.packages
.vagrant/
.vscode/
**/.vs
.settings
@@ -129,6 +128,7 @@ samples/client/petstore/swift3/**/SwaggerClientTests/Podfile.lock
# C#
*.csproj.user
samples/client/petstore/csharp/SwaggerClient/IO.Swagger.userprefs
samples/client/petstore/csharp/SwaggerClientTest/.vs
samples/client/petstore/csharp/SwaggerClientTest/obj
samples/client/petstore/csharp/SwaggerClientTest/bin
samples/client/petstore/csharp/SwaggerClientTest/packages
@@ -146,8 +146,6 @@ samples/client/petstore/csharp/SwaggerClient/bin/Debug/
samples/client/petstore/csharp/SwaggerClient/packages
samples/client/petstore/csharp/SwaggerClient/TestResult.xml
samples/client/petstore/csharp/SwaggerClientWithPropertyChanged/IO.Swagger.userprefs
samples/client/petstore/csharp-refactor/OpenAPIClient/TestResult.xml
samples/client/petstore/csharp-refactor/OpenAPIClient/nuget.exe
# Python
*.pyc
@@ -180,7 +178,6 @@ samples/client/petstore/kotlin/src/main/kotlin/test/
samples/client/petstore/kotlin-threetenbp/build
samples/client/petstore/kotlin-string/build
samples/server/petstore/kotlin-server/ktor/build
samples/openapi3/client/petstore/kotlin/build
\?
# haskell

View File

@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
OpenAPI Petstore
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
OpenAPI spec version: 1.0.0
-->
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{19F1DEBC-DE5E-4517-8062-F000CD499087}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Org.OpenAPITools.Test</RootNamespace>
<AssemblyName>Org.OpenAPITools.Test</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml" />
<Reference Include="Newtonsoft.Json">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath Condition="Exists('..\..\vendor')">..\..\vendor\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="JsonSubTypes">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\JsonSubTypes.1.5.1\lib\net45\JsonSubTypes.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\JsonSubTypes.1.5.1\lib\net45\JsonSubTypes.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\JsonSubTypes.1.5.1\lib\net45\JsonSubTypes.dll</HintPath>
<HintPath Condition="Exists('..\..\vendor')">..\..\vendor\JsonSubTypes.1.5.1\lib\net45\JsonSubTypes.dll</HintPath>
</Reference>
<Reference Include="RestSharp">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\RestSharp.106.5.4\lib\net452\RestSharp.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\RestSharp.106.5.4\lib\net452\RestSharp.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\RestSharp.106.5.4\lib\net452\RestSharp.dll</HintPath>
<HintPath Condition="Exists('..\..\vendor')">..\..\vendor\RestSharp.106.5.4\lib\net452\RestSharp.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
<HintPath Condition="Exists('..\..\vendor')">..\..\vendor\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="obj\**" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MsBuildToolsPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\Org.OpenAPITools\Org.OpenAPITools.csproj">
<Project>{321C8C3F-0156-40C1-AE42-D59761FB9B6C}</Project>
<Name>Org.OpenAPITools</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="linux-logo.png" />
</ItemGroup>
</Project>

View File

@@ -1,70 +0,0 @@
/*
* OpenAPI Petstore
* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
*
* OpenAPI spec version: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
package org.openapitools.client.model;
import org.apache.commons.lang3.builder.EqualsBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
/**
* Model tests for ArrayOfArrayOfNumberOnly
*/
public class ArrayOfArrayOfNumberOnlyTest {
private final ArrayOfArrayOfNumberOnly model = new ArrayOfArrayOfNumberOnly();
/**
* Model tests for ArrayOfArrayOfNumberOnly
*/
@Test
public void test() {
// TODO: test ArrayOfArrayOfNumberOnly
}
/**
* Test the property 'arrayArrayNumber'
*/
@Test
public void arrayArrayNumberTest() {
BigDecimal b1 = new BigDecimal("12.3");
BigDecimal b2 = new BigDecimal("5.6");
List<BigDecimal> arrayArrayNumber = new ArrayList<BigDecimal>();
arrayArrayNumber.add(b1);
arrayArrayNumber.add(b2);
model.getArrayArrayNumber().add(arrayArrayNumber);
// create another instance for comparison
BigDecimal b3 = new BigDecimal("12.3");
BigDecimal b4 = new BigDecimal("5.6");
ArrayOfArrayOfNumberOnly model2 = new ArrayOfArrayOfNumberOnly();
List<BigDecimal> arrayArrayNumber2 = new ArrayList<BigDecimal>();
arrayArrayNumber2.add(b1);
arrayArrayNumber2.add(b2);
model2.getArrayArrayNumber().add(arrayArrayNumber2);
Assert.assertTrue(model2.equals(model));
}
}

View File

@@ -1,103 +0,0 @@
/*
* OpenAPI Petstore
* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
*
* OpenAPI spec version: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
package org.openapitools.client.model;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.openapitools.client.model.Category;
import org.openapitools.client.model.Tag;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
/**
* Model tests for Pet
*/
public class PetTest {
private final Pet model = new Pet();
/**
* Model tests for Pet
*/
@Test
public void testPet() {
// test Pet
model.setId(1029L);
model.setName("Dog");
Pet model2 = new Pet();
model2.setId(1029L);
model2.setName("Dog");
Assert.assertTrue(model.equals(model2));
}
/**
* Test the property 'id'
*/
@Test
public void idTest() {
// TODO: test id
}
/**
* Test the property 'category'
*/
@Test
public void categoryTest() {
// TODO: test category
}
/**
* Test the property 'name'
*/
@Test
public void nameTest() {
// TODO: test name
}
/**
* Test the property 'photoUrls'
*/
@Test
public void photoUrlsTest() {
// TODO: test photoUrls
}
/**
* Test the property 'tags'
*/
@Test
public void tagsTest() {
// TODO: test tags
}
/**
* Test the property 'status'
*/
@Test
public void statusTest() {
// TODO: test status
}
}

View File

@@ -27,7 +27,7 @@
:notebook_with_decorative_cover: The eBook [A Beginner's Guide to Code Generation for REST APIs](https://gumroad.com/l/swagger_codegen_beginner) is a good starting point for beginners :notebook_with_decorative_cover:
:warning: If the OpenAPI spec, templates or any input (e.g. options, environment variables) is obtained from an untrusted source or environment, please make sure you've reviewed these inputs before using OpenAPI Generator to generate the API client, server stub or documentation to avoid potential security issues (e.g. [code injection](https://en.wikipedia.org/wiki/Code_injection)) :warning:
:warning: If the OpenAPI spec, templates or any input (e.g. options, envirionment variables) is obtained from an untrusted source or environment, please make sure you've reviewed these inputs before using OpenAPI Generator to generate the API client, server stub or documentation to avoid potential security issues (e.g. [code injection](https://en.wikipedia.org/wiki/Code_injection)) :warning:
:bangbang: Both "OpenAPI Tools" (https://OpenAPITools.org - the parent organization of OpenAPI Generator) and "OpenAPI Generator" are not affiliated with OpenAPI Initiative (OAI) :bangbang:
@@ -504,7 +504,6 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- [b<>com](https://b-com.com/en)
- [Bithost GmbH](https://www.bithost.ch)
- [Boxever](https://www.boxever.com/)
- [GenFlow](https://github.com/RepreZen/GenFlow)
- [GMO Pepabo](https://pepabo.com/en/)
- [JustStar](https://www.juststarinfo.com)
- [Klarna](https://www.klarna.com/)
@@ -530,12 +529,9 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- 2018/06/27 - [Lessons Learned from Leading an Open-Source Project Supporting 30+ Programming Languages](https://speakerdeck.com/wing328/lessons-learned-from-leading-an-open-source-project-supporting-30-plus-programming-languages) - [William Cheng](https://github.com/wing328) at [LinuxCon + ContainerCon + CloudOpen China 2018](http://bit.ly/2waDKKX)
- 2018/07/19 - [OpenAPI Generator Contribution Quickstart - RingCentral Go SDK](https://medium.com/ringcentral-developers/openapi-generator-for-go-contribution-quickstart-8cc72bf37b53) by [John Wang](https://github.com/grokify)
- 2018/08/22 - [OpenAPI Generatorのプロジェクト構成などのメモ](https://yinm.info/20180822/) by [Yusuke Iinuma](https://github.com/yinm)
- 2018/09/12 - [RepreZen and OpenAPI 3.0: Now is the Time](https://www.reprezen.com/blog/reprezen-openapi-3.0-upgrade-now-is-the-time) by [Miles Daffin](https://www.reprezen.com/blog/author/miles-daffin)
- 2018/10/31 - [A node package wrapper for openapi-generator](https://github.com/HarmoWatch/openapi-generator-cli)
- 2018/11/03 - [OpenAPI Generator + golang + Flutter でアプリ開発](http://ryuichi111std.hatenablog.com/entry/2018/11/03/214005) by [Ryuichi Daigo](https://github.com/ryuichi111)
- 2018/11/19 - [OpenAPIs are everywhere](https://youtu.be/-lDot4Yn7Dg) by [Jeremie Bresson (Unblu)](https://github.com/jmini) at [EclipseCon Europe 2018](https://www.eclipsecon.org/europe2018)
- 2018/12/09 - [openapi-generator をカスタマイズする方法](https://qiita.com/watiko/items/0961287c02eac9211572) by [@watiko](https://qiita.com/watiko)
- 2019/01/03 - [Calling a Swagger service from Apex using openapi-generator](https://lekkimworld.com/2019/01/03/calling-a-swagger-service-from-apex-using-openapi-generator/) by [Mikkel Flindt Heisterberg](https://lekkimworld.com)
## [6 - About Us](#table-of-contents)
@@ -570,7 +566,7 @@ Here is a list of template creators:
* Dart 2: @swipesight
* Dart (Jaguar): @jaumard
* Elixir: @niku
* Elm: @eriktim
* Elm: @trenneman
* Eiffel: @jvelilla
* Erlang: @tsloughter
* Erlang (PropEr): @jfacorro @robertoaloi
@@ -696,8 +692,8 @@ If you want to join the committee, please kindly apply by sending an email to te
| Clojure | |
| Dart | @ircecho (2017/07) @swipesight (2018/09) @jaumard (2018/09) |
| Eiffel | @jvelilla (2017/09) |
| Elixir | @mrmstn (2018/12) |
| Elm | @eriktim (2018/09) |
| Elixir | |
| Elm | @trenneman (2018/09) |
| Erlang | @tsloughter (2017/11) @jfacorro (2018/10) @robertoaloi (2018/10) |
| Go | @antihax (2017/11) @bvwells (2017/12) @grokify (2018/07) @kemokemo (2018/09 |
| GraphQL | @renepardon (2018/12) |
@@ -736,7 +732,7 @@ OpenAPI Generator is a fork of [Swagger Codegen](https://github.com/swagger-api/
- [Daiki Matsudate](https://github.com/d-date)
- [Daniel](https://github.com/Danielku15)
- [Emiliano Bonassi](https://github.com/emilianobonassi)
- [Erik Timmers](https://github.com/eriktim)
- [Erik Timmers](https://github.com/trenneman)
- [Esteban Marin](https://github.com/macjohnny)
- [Gustavo Paz](https://github.com/gustavoapaz)
- [Javier Velilla](https://github.com/jvelilla)

View File

@@ -23,9 +23,6 @@ install:
- git clone https://github.com/wing328/swagger-samples
- ps: Start-Process -FilePath 'C:\maven\apache-maven-3.2.5\bin\mvn' -ArgumentList 'jetty:run' -WorkingDirectory "$env:appveyor_build_folder\swagger-samples\java\java-jersey-jaxrs-ci"
build_script:
# build C# API client (refactor)
- nuget restore samples\client\petstore\csharp-refactor\OpenAPIClient\Org.OpenAPITools.sln
- msbuild samples\client\petstore\csharp-refactor\OpenAPIClient\Org.OpenAPITools.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
# build C# API client
- nuget restore samples\client\petstore\csharp\OpenAPIClient\Org.OpenAPITools.sln
- msbuild samples\client\petstore\csharp\OpenAPIClient\Org.OpenAPITools.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
@@ -40,8 +37,6 @@ build_script:
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 (refactor)
- nunit-console samples\client\petstore\csharp-refactor\OpenAPIClient\src\Org.OpenAPITools.Test\bin\Debug\Org.OpenAPITools.Test.dll --result=myresults.xml;format=AppVeyor
# 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)

View File

@@ -27,11 +27,11 @@ 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/csharp-refactor/ -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g csharp-refactor -o samples/client/petstore/csharp-refactor/OpenAPIClient --additional-properties packageGuid={321C8C3F-0156-40C1-AE42-D59761FB9B6C},useCompareNetObjects=true $@"
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g csharp-refactor -o samples/client/petstore/csharp-refactor/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-refactor/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj"
cp ./CI/samples.ci/client/petstore/csharp-refactor/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj ./samples/client/petstore/csharp-refactor/OpenAPIClient/src/Org.OpenAPITools.Test/
#echo "restore csproject file: CI/samples/client/petstore/csharp/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj"
#cp ./CI/samples.ci/client/petstore/csharp/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj ./samples/client/petstore/csharp-refactor/OpenAPIClient/src/Org.OpenAPITools.Test/

View File

@@ -44,6 +44,4 @@ cp CI/samples.ci/client/petstore/java/test-manual/common/ConfigurationTest.java
cp CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/auth/ApiKeyAuthTest.java samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/auth/ApiKeyAuthTest.java
cp CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/auth/HttpBasicAuthTest.java samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/auth/HttpBasicAuthTest.java
cp CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/model/EnumValueTest.java samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/model/EnumValueTest.java
cp CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/model/PetTest.java samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/model/PetTest.java
cp CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/model/ArrayOfArrayOfNumberOnly.java samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/model/ArrayOfArrayOfNumberOnlyTest.java
cp CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/JSONTest.java samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/JSONTest.java

View File

@@ -29,6 +29,7 @@ fi
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/Javascript/es6 \
-i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g javascript \
-o samples/client/petstore/javascript-es6 $@"
-o samples/client/petstore/javascript-es6 \
--additional-properties useES6=true $@"
java -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags

View File

@@ -1,38 +0,0 @@
#!/bin/sh
SCRIPT="$0"
echo "# START SCRIPT: $SCRIPT"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
if [ ! -f "$executable" ]
then
mvn -B clean package
fi
SPEC="modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml"
GENERATOR="go"
STUB_DIR="samples/openapi3/client/petstore/go/go-petstore"
echo "Removing files and folders under $STUB_DIR"
rm -rf $STUB_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/go -i $SPEC -g $GENERATOR -o $STUB_DIR -DpackageName=petstore $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -1,35 +0,0 @@
#!/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
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 -t modules/openapi-generator/src/main/resources/kotlin-client -g kotlin --artifact-id kotlin-petstore-client -D dateLibrary=java8 -o samples/openapi3/client/petstore/kotlin $@"
echo "Cleaning previously generated files if any from samples/openapi3/client/petstore/kotlin"
rm -rf samples/openapi3/client/petstore/kotlin
echo "Generating Kotling client..."
java $JAVA_OPTS -jar $executable $ags

View File

@@ -28,6 +28,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"
# complex module name used for testing
ags="generate -t modules/openapi-generator/src/main/resources/perl -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -g perl -o samples/client/petstore/perl -DhideGenerationTimestamp=true $@"
ags="generate -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -g perl -o samples/client/petstore/perl -DhideGenerationTimestamp=true $@"
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/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3-deprecated -c ./bin/swift3-petstore-objcCompatible.json -o samples/client/petstore/swift3/objcCompatible $@"
ags="generate -t modules/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -c ./bin/swift3-petstore-objcCompatible.json -o samples/client/petstore/swift3/objcCompatible $@"
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/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3-deprecated -c ./bin/swift3-petstore-promisekit.json -o samples/client/petstore/swift3/promisekit $@"
ags="generate -t modules/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -c ./bin/swift3-petstore-promisekit.json -o samples/client/petstore/swift3/promisekit $@"
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/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3-deprecated -c ./bin/swift3-petstore-rxswift.json -o samples/client/petstore/swift3/rxswift $@"
ags="generate -t modules/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -c ./bin/swift3-petstore-rxswift.json -o samples/client/petstore/swift3/rxswift $@"
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/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3-deprecated -c ./bin/swift3-petstore-unwraprequired.json -o samples/client/petstore/swift3/unwraprequired $@"
ags="generate -t modules/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -c ./bin/swift3-petstore-unwraprequired.json -o samples/client/petstore/swift3/unwraprequired $@"
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/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3-deprecated -c ./bin/swift3-petstore.json -o samples/client/petstore/swift3/default $@"
ags="generate -t modules/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -c ./bin/swift3-petstore.json -o samples/client/petstore/swift3/default $@"
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 swift3-deprecated -c bin\swift3-petstore-promisekit.json -o samples\client\petstore\swift3\promisekit
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -c bin\swift3-petstore-promisekit.json -o samples\client\petstore\swift3\promisekit
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 swift3-deprecated -c bin\swift3-petstore-rxswift.json -o samples\client\petstore\swift3\rxswift
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -c bin\swift3-petstore-rxswift.json -o samples\client\petstore\swift3\rxswift
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 swift3-deprecated -o samples\client\petstore\swift3\default
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -o samples\client\petstore\swift3\default
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -12,7 +12,7 @@ codegen="${cli}/target/openapi-generator-cli.jar"
# We code in a list of commands here as source processing is potentially buggy (requires undocumented conventional use of annotations).
# A list of known commands helps us determine if we should compile CLI. There's an edge-case where a new command not added to this
# list won't be considered a "real" command. We can get around that a bit by checking CLI completions beforehand if it exists.
commands="list,generate,meta,help,config-help,validate,version"
commands="list,generate,meta,langs,help,config-help,validate,version"
# if CLI jar exists, check $1 against completions available in the CLI
if [[ -f "${codegen}" && -n "$(java ${JAVA_OPTS} -jar "${codegen}" completion | grep "^$1\$" )" ]]; then

View File

@@ -1,19 +0,0 @@
CONFIG OPTIONS for c
sortParamsByRequiredFlag
Sort method arguments to place required parameters before optional parameters. (Default: true)
ensureUniqueParams
Whether to ensure parameter names are unique in an operation (rename parameters that are not). (Default: true)
allowUnicodeIdentifiers
boolean, toggles whether unicode identifiers are allowed in names or not, default is false (Default: false)
prependFormOrBodyParameters
Add form or body parameters to the beginning of the parameter list. (Default: false)
hideGenerationTimestamp
Hides the generation timestamp when files are generated. (Default: true)
Back to the [generators list](README.md)

View File

@@ -1,25 +0,0 @@
CONFIG OPTIONS for cpp-qt5-client
sortParamsByRequiredFlag
Sort method arguments to place required parameters before optional parameters. (Default: true)
ensureUniqueParams
Whether to ensure parameter names are unique in an operation (rename parameters that are not). (Default: true)
allowUnicodeIdentifiers
boolean, toggles whether unicode identifiers are allowed in names or not, default is false (Default: false)
prependFormOrBodyParameters
Add form or body parameters to the beginning of the parameter list. (Default: false)
cppNamespace
C++ namespace (convention: name::space::for::api). (Default: OpenAPI)
cppNamespace
C++ namespace (convention: name::space::for::api). (Default: OpenAPI)
optionalProjectFile
Generate client.pri. (Default: true)
Back to the [generators list](README.md)

View File

@@ -69,7 +69,4 @@ CONFIG OPTIONS for csharp
validatable
Generates self-validatable models. (Default: true)
useCompareNetObjects
Use KellermanSoftware.CompareNetObjects for deep recursive object comparison. WARNING: this option incurs potential performance impact. (Default: false)
Back to the [generators list](README.md)

View File

@@ -1,10 +0,0 @@
CONFIG OPTIONS for erlang-proper
packageName
Erlang application name (convention: lowercase). (Default: openapi)
packageName
Erlang application version (Default: 1.0.0)
Back to the [generators list](README.md)

View File

@@ -1,13 +0,0 @@
CONFIG OPTIONS for graphql-schema
packageName
GraphQL package name (convention: lowercase). (Default: openapi2graphql)
packageVersion
GraphQL package version. (Default: 1.0.0)
hideGenerationTimestamp
Hides the generation timestamp when files are generated. (Default: true)
Back to the [generators list](README.md)

View File

@@ -1,13 +0,0 @@
CONFIG OPTIONS for graphql-server
packageName
GraphQL express server package name (convention: lowercase). (Default: openapi3graphql-server)
packageVersion
GraphQL express server package version. (Default: 1.0.0)
hideGenerationTimestamp
Hides the generation timestamp when files are generated. (Default: true)
Back to the [generators list](README.md)

View File

@@ -146,9 +146,6 @@ CONFIG OPTIONS for java
feignVersion
Version of OpenFeign: '10.x', '9.x' (default) (Default: false)
useReflectionEqualsHashCode
Use org.apache.commons.lang3.builder for equals and hashCode in the models. WARNING: This will fail under a security manager, unless the appropriate permissions are set up correctly and also there's potential performance impact. (Default: false)
library
library template (sub-template) to use (Default: okhttp-gson)
jersey1 - HTTP client: Jersey client 1.19.4. JSON processing: Jackson 2.8.9. Enable Java6 support using '-DsupportJava6=true'. Enable gzip request encoding using '-DuseGzipFeature=true'.

View File

@@ -59,7 +59,7 @@ CONFIG OPTIONS for javascript
Hides the generation timestamp when files are generated. (Default: true)
useES6
use JavaScript ES6 (ECMAScript 6) (beta). Default is ES6. (Default: true)
use JavaScript ES6 (ECMAScript 6) (beta). Default is ES5. (Default: false)
modelPropertyNaming
Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name (Default: camelCase)

View File

@@ -40,4 +40,7 @@ CONFIG OPTIONS for php-slim
artifactVersion
The version to use in the composer package version field. e.g. 1.2.3
phpcsStandard
PHP CodeSniffer <standard> option. Accepts name or path of the coding standard to use. (Default: PSR12)
Back to the [generators list](README.md)

View File

@@ -156,7 +156,7 @@ Corresponding java code: `CodegenProperty.datatype` is renamed to `CodegenProper
`.swagger-codegen-ignore` is replaced by `.openapi-generator-ignore`.
The syntax inside the file stays the same.
You don't need to rename the file manually, OpenAPI Generator will do it when your run it against an existing output directory.
You don't need to rename the file manually, OpenAPI Generator will do it when your run it against an existing an existing output directory.
(When there is no `.openapi-generator-ignore` in a folder, if a `.swagger-codegen-ignore` file is present it will be considered and renamed to `.openapi-generator-ignore`).

View File

@@ -20,7 +20,7 @@ Version `4.0.0` is a major release, which contains some breaking changes without
The option is replaced with `-g` (`--generator-name`).
* `-g` allows the same values as `-l`
* See `list` command for the list of generator name
* See `langs` command for the list of generator name
=== From 3.1.x to 3.2.0

View File

@@ -50,6 +50,7 @@ public class OpenAPIGenerator {
ListGenerators.class,
Generate.class,
Meta.class,
Langs.class,
Help.class,
ConfigHelp.class,
Validate.class,
@@ -71,7 +72,7 @@ public class OpenAPIGenerator {
System.exit(1);
}
} catch (ParseArgumentsUnexpectedException e) {
System.err.printf(Locale.ROOT,"[error] %s%n%nSee 'openapi-generator help' for usage.%n", e.getMessage());
System.err.printf(Locale.ROOT,"[error] %s%n%nSee 'openapi-generator-cli help' for usage.%n", e.getMessage());
System.exit(1);
} catch (ParseOptionMissingException | ParseOptionMissingValueException e) {
System.err.printf(Locale.ROOT,"[error] %s%n", e.getMessage());

View File

@@ -50,7 +50,7 @@ public class Generate implements Runnable {
private Boolean verbose;
@Option(name = {"-g", "--generator-name"}, title = "generator name",
description = "generator to use (see list command for list)")
description = "generator to use (see langs command for list)")
private String generatorName;
@Option(name = {"-o", "--output"}, title = "output directory",
@@ -208,9 +208,6 @@ public class Generate implements Runnable {
@Option(name = {"--enable-post-process-file"}, title = "enable post-process file", description = CodegenConstants.ENABLE_POST_PROCESS_FILE)
private Boolean enablePostProcessFile;
@Option(name = {"--generate-alias-as-model"}, title = "generate alias (array, map) as model", description = CodegenConstants.GENERATE_ALIAS_AS_MODEL_DESC)
private Boolean generateAliasAsModel;
@Override
public void run() {
if (logToStderr != null) {
@@ -337,10 +334,6 @@ public class Generate implements Runnable {
configurator.setEnablePostProcessFile(enablePostProcessFile);
}
if (generateAliasAsModel != null) {
configurator.setGenerateAliasAsModel(generateAliasAsModel);
}
applySystemPropertiesKvpList(systemProperties, configurator);
applyInstantiationTypesKvpList(instantiationTypes, configurator);
applyImportMappingsKvpList(importMappings, configurator);

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright 2018 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.cmd;
import ch.lambdaj.collection.LambdaIterable;
import io.airlift.airline.Command;
import org.openapitools.codegen.CodegenConfig;
import java.util.Locale;
import static ch.lambdaj.Lambda.on;
import static ch.lambdaj.collection.LambdaCollections.with;
import static java.util.ServiceLoader.load;
/**
* User: lanwen Date: 24.03.15 Time: 20:25
*/
@Command(name = "langs", description = "Shows available languages (deprecated. use 'list' instead)")
public class Langs implements Runnable {
@Override
public void run() {
LambdaIterable<String> langs =
with(load(CodegenConfig.class)).extract(on(CodegenConfig.class).getName());
System.out.printf(Locale.ROOT, "Available languages (generators): %s%n", langs);
}
}

View File

@@ -0,0 +1,131 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.invoke
import org.openapitools.generator.gradle.plugin.extensions.OpenApiGeneratorGenerateExtension
import org.openapitools.generator.gradle.plugin.extensions.OpenApiGeneratorMetaExtension
import org.openapitools.generator.gradle.plugin.extensions.OpenApiGeneratorValidateExtension
import org.openapitools.generator.gradle.plugin.tasks.GenerateTask
import org.openapitools.generator.gradle.plugin.tasks.GeneratorsTask
import org.openapitools.generator.gradle.plugin.tasks.MetaTask
import org.openapitools.generator.gradle.plugin.tasks.ValidateTask
/**
* A plugin providing common Open API Generator use cases.
*
* @author Jim Schubert
*/
@Suppress("unused")
class OpenApiGeneratorPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.run {
val meta = extensions.create(
"openApiMeta",
OpenApiGeneratorMetaExtension::class.java,
project
)
val validate = extensions.create(
"openApiValidate",
OpenApiGeneratorValidateExtension::class.java,
project
)
val generate = extensions.create(
"openApiGenerate",
OpenApiGeneratorGenerateExtension::class.java,
project
)
generate.outputDir.set("$buildDir/generate-resources/main")
tasks {
"openApiGenerators"(GeneratorsTask::class) {
group = pluginGroup
description = "Lists generators available via Open API Generators."
}
"openApiMeta"(MetaTask::class) {
group = pluginGroup
description = "Generates a new generator to be consumed via Open API Generator."
generatorName.set(meta.generatorName)
packageName.set(meta.packageName)
outputFolder.set(meta.outputFolder)
}
"openApiValidate"(ValidateTask::class) {
group = pluginGroup
description = "Validates an Open API 2.0 or 3.x specification document."
inputSpec.set(validate.inputSpec)
}
"openApiGenerate"(GenerateTask::class) {
group = pluginGroup
description = "Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents."
verbose.set(generate.verbose)
validateSpec.set(generate.validateSpec)
generatorName.set(generate.generatorName)
outputDir.set(generate.outputDir)
inputSpec.set(generate.inputSpec)
templateDir.set(generate.templateDir)
auth.set(generate.auth)
systemProperties.set(generate.systemProperties)
configFile.set(generate.configFile)
skipOverwrite.set(generate.skipOverwrite)
apiPackage.set(generate.apiPackage)
modelPackage.set(generate.modelPackage)
modelNamePrefix.set(generate.modelNamePrefix)
modelNameSuffix.set(generate.modelNameSuffix)
instantiationTypes.set(generate.instantiationTypes)
typeMappings.set(generate.typeMappings)
additionalProperties.set(generate.additionalProperties)
languageSpecificPrimitives.set(generate.languageSpecificPrimitives)
importMappings.set(generate.importMappings)
invokerPackage.set(generate.invokerPackage)
groupId.set(generate.groupId)
id.set(generate.id)
version.set(generate.version)
library.set(generate.library)
gitUserId.set(generate.gitUserId)
gitRepoId.set(generate.gitRepoId)
releaseNote.set(generate.releaseNote)
httpUserAgent.set(generate.httpUserAgent)
reservedWordsMappings.set(generate.reservedWordsMappings)
ignoreFileOverride.set(generate.ignoreFileOverride)
removeOperationIdPrefix.set(generate.removeOperationIdPrefix)
apiFilesConstrainedTo.set(generate.apiFilesConstrainedTo)
modelFilesConstrainedTo.set(generate.modelFilesConstrainedTo)
supportingFilesConstrainedTo.set(generate.supportingFilesConstrainedTo)
generateModelTests.set(generate.generateModelTests)
generateModelDocumentation.set(generate.generateModelDocumentation)
generateApiTests.set(generate.generateApiTests)
generateApiDocumentation.set(generate.generateApiDocumentation)
withXml.set(generate.withXml)
configOptions.set(generate.configOptions)
}
}
}
}
companion object {
const val pluginGroup = "OpenAPI Tools"
}
}

View File

@@ -0,0 +1,286 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin.extensions
import org.gradle.api.Project
import org.gradle.kotlin.dsl.listProperty
import org.gradle.kotlin.dsl.property
/**
* Gradle project level extension object definition for the generate task
*
* @author Jim Schubert
*/
open class OpenApiGeneratorGenerateExtension(project: Project) {
/**
* The verbosity of generation
*/
val verbose = project.objects.property<Boolean>()
/**
* Whether or not an input specification should be validated upon generation.
*/
val validateSpec = project.objects.property<Boolean>()
/**
* The name of the generator which will handle codegen. (see "openApiGenerators" task)
*/
val generatorName = project.objects.property<String>()
/**
* The output target directory into which code will be generated.
*/
val outputDir = project.objects.property<String>()
/**
* The Open API 2.0/3.x specification location.
*/
val inputSpec = project.objects.property<String>()
/**
* The template directory holding a custom template.
*/
val templateDir = project.objects.property<String?>()
/**
* Adds authorization headers when fetching the OpenAPI definitions remotely.
* Pass in a URL-encoded string of name:header with a comma separating multiple values
*/
val auth = project.objects.property<String>()
/**
* Sets specified system properties.
*/
val systemProperties = project.objects.property<Map<String, String>>()
/**
* Path to json configuration file.
* File content should be in a json format { "optionKey":"optionValue", "optionKey1":"optionValue1"...}
* Supported options can be different for each language. Run config-help -g {generator name} command for language specific config options.
*/
val configFile = project.objects.property<String>()
/**
* Specifies if the existing files should be overwritten during the generation.
*/
val skipOverwrite = project.objects.property<Boolean?>()
/**
* Package for generated api classes
*/
val apiPackage = project.objects.property<String>()
/**
* Package for generated models
*/
val modelPackage = project.objects.property<String>()
/**
* Prefix that will be prepended to all model names. Default is the empty string.
*/
val modelNamePrefix = project.objects.property<String>()
/**
* Suffix that will be appended to all model names. Default is the empty string.
*/
val modelNameSuffix = project.objects.property<String>()
/**
* Sets instantiation type mappings.
*/
val instantiationTypes = project.objects.property<Map<String, String>>()
/**
* Sets mappings between OpenAPI spec types and generated code types.
*/
val typeMappings = project.objects.property<Map<String, String>>()
/**
* Sets additional properties that can be referenced by the mustache templates.
*/
val additionalProperties = project.objects.property<Map<String, String>>()
/**
* Specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double.
*/
val languageSpecificPrimitives = project.objects.listProperty<String>()
/**
* Specifies mappings between a given class and the import that should be used for that class.
*/
val importMappings = project.objects.property<Map<String, String>>()
/**
* Root package for generated code.
*/
val invokerPackage = project.objects.property<String>()
/**
* GroupId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
*/
val groupId = project.objects.property<String>()
/**
* ArtifactId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
*/
val id = project.objects.property<String>()
/**
* Artifact version in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
*/
val version = project.objects.property<String>()
/**
* Reference the library template (sub-template) of a generator.
*/
val library = project.objects.property<String?>()
/**
* Git user ID, e.g. openapitools.
*/
val gitUserId = project.objects.property<String?>()
/**
* Git repo ID, e.g. openapi-generator.
*/
val gitRepoId = project.objects.property<String?>()
/**
* Release note, default to 'Minor update'.
*/
val releaseNote = project.objects.property<String?>()
/**
* HTTP user agent, e.g. codegen_csharp_api_client, default to 'OpenAPI-Generator/{packageVersion}}/{language}'
*/
val httpUserAgent = project.objects.property<String?>()
/**
* Specifies how a reserved name should be escaped to. Otherwise, the default _<name> is used.
*/
val reservedWordsMappings = project.objects.property<Map<String, String>>()
/**
* Specifies an override location for the .openapi-generator-ignore file. Most useful on initial generation.
*/
val ignoreFileOverride = project.objects.property<String?>()
/**
* Remove prefix of operationId, e.g. config_getId => getId
*/
val removeOperationIdPrefix = project.objects.property<Boolean?>()
/**
* Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all).
*
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
*/
val apiFilesConstrainedTo = project.objects.listProperty<String>()
/**
* Defines which model-related files should be generated. This allows you to create a subset of generated files (or none at all).
*
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
*/
val modelFilesConstrainedTo = project.objects.listProperty<String>()
/**
* Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all).
*
* Supporting files are those related to projects/frameworks which may be modified
* by consumers.
*
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
*/
val supportingFilesConstrainedTo = project.objects.listProperty<String>()
/**
* Defines whether or not model-related _test_ files should be generated.
*
* This option enables/disables generation of ALL model-related _test_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
val generateModelTests = project.objects.property<Boolean>()
/**
* Defines whether or not model-related _documentation_ files should be generated.
*
* This option enables/disables generation of ALL model-related _documentation_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
val generateModelDocumentation = project.objects.property<Boolean>()
/**
* Defines whether or not api-related _test_ files should be generated.
*
* This option enables/disables generation of ALL api-related _test_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
val generateApiTests = project.objects.property<Boolean>()
/**
* Defines whether or not api-related _documentation_ files should be generated.
*
* This option enables/disables generation of ALL api-related _documentation_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
val generateApiDocumentation = project.objects.property<Boolean>()
/**
* A special-case setting which configures some generators with XML support. In some cases,
* this forces json OR xml, so the default here is false.
*/
val withXml = project.objects.property<Boolean>()
/**
* A map of options specific to a generator.
*/
val configOptions = project.objects.property<Map<String, String>>()
init {
applyDefaults()
}
@Suppress("MemberVisibilityCanBePrivate")
fun applyDefaults(){
releaseNote.set("Minor update")
modelNamePrefix.set("")
modelNameSuffix.set("")
generateModelTests.set(true)
generateModelDocumentation.set(true)
generateApiTests.set(true)
generateApiDocumentation.set(true)
withXml.set(false)
configOptions.set(mapOf())
validateSpec.set(true)
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin.extensions
import org.gradle.api.Project
import org.gradle.kotlin.dsl.property
/**
* Gradle project level extension object definition for the meta-generator task
*
* @author Jim Schubert
*/
open class OpenApiGeneratorMetaExtension(project: Project) {
/**
* The human-readable generator name of the newly created template generator.
*/
val generatorName = project.objects.property<String>()
/**
* The packageName generatorName to put the main class into (defaults to org.openapitools.codegen)
*/
val packageName = project.objects.property<String>()
/**
* Where to write the generated files (current dir by default).
*/
val outputFolder = project.objects.property<String>()
init {
generatorName.set("default")
packageName.set("org.openapitools.codegen")
outputFolder.set("")
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin.extensions
import org.gradle.api.Project
import org.gradle.kotlin.dsl.property
/**
* Gradle project level extension object definition for the generators task
*
* @author Jim Schubert
*/
open class OpenApiGeneratorValidateExtension(project: Project) {
/**
* The input specification to validate. Supports all formats supported by the Parser.
*/
val inputSpec = project.objects.property<String>()
}

View File

@@ -0,0 +1,554 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
import org.gradle.internal.logging.text.StyledTextOutput
import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.gradle.kotlin.dsl.listProperty
import org.gradle.kotlin.dsl.property
import org.openapitools.codegen.CodegenConstants
import org.openapitools.codegen.DefaultGenerator
import org.openapitools.codegen.config.CodegenConfigurator
/**
* A task which generates the desired code.
*
* Example (CLI):
*
* ./gradlew -q openApiGenerate
*
* @author Jim Schubert
*/
open class GenerateTask : DefaultTask() {
/**
* The verbosity of generation
*/
@get:Internal
val verbose = project.objects.property<Boolean>()
/**
* Whether or not an input specification should be validated upon generation.
*/
@get:Internal
val validateSpec = project.objects.property<Boolean>()
/**
* The name of the generator which will handle codegen. (see "openApiGenerators" task)
*/
@get:Internal
val generatorName = project.objects.property<String>()
/**
* The output target directory into which code will be generated.
*/
@get:Internal
val outputDir = project.objects.property<String>()
/**
* The Open API 2.0/3.x specification location.
*/
@get:Internal
val inputSpec = project.objects.property<String>()
/**
* The template directory holding a custom template.
*/
@get:Internal
val templateDir = project.objects.property<String?>()
/**
* Adds authorization headers when fetching the OpenAPI definitions remotely.
* Pass in a URL-encoded string of name:header with a comma separating multiple values
*/
@get:Internal
val auth = project.objects.property<String>()
/**
* Sets specified system properties.
*/
@get:Internal
val systemProperties = project.objects.property<Map<String, String>>()
/**
* Path to json configuration file.
* File content should be in a json format { "optionKey":"optionValue", "optionKey1":"optionValue1"...}
* Supported options can be different for each language. Run config-help -g {generator name} command for language specific config options.
*/
@get:Internal
val configFile = project.objects.property<String>()
/**
* Specifies if the existing files should be overwritten during the generation.
*/
@get:Internal
val skipOverwrite = project.objects.property<Boolean?>()
/**
* Package for generated api classes
*/
@get:Internal
val apiPackage = project.objects.property<String>()
/**
* Package for generated models
*/
@get:Internal
val modelPackage = project.objects.property<String>()
/**
* Prefix that will be prepended to all model names. Default is the empty string.
*/
@get:Internal
val modelNamePrefix = project.objects.property<String>()
/**
* Suffix that will be appended to all model names. Default is the empty string.
*/
@get:Internal
val modelNameSuffix = project.objects.property<String>()
/**
* Sets instantiation type mappings.
*/
@get:Internal
val instantiationTypes = project.objects.property<Map<String, String>>()
/**
* Sets mappings between OpenAPI spec types and generated code types.
*/
@get:Internal
val typeMappings = project.objects.property<Map<String, String>>()
/**
* Sets additional properties that can be referenced by the mustache templates in the format of name=value,name=value.
* You can also have multiple occurrences of this option.
*/
@get:Internal
val additionalProperties = project.objects.property<Map<String, String>>()
/**
* Specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double.
*/
@get:Internal
val languageSpecificPrimitives = project.objects.listProperty<String>()
/**
* Specifies mappings between a given class and the import that should be used for that class.
*/
@get:Internal
val importMappings = project.objects.property<Map<String, String>>()
/**
* Root package for generated code.
*/
@get:Internal
val invokerPackage = project.objects.property<String>()
/**
* GroupId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
*/
@get:Internal
val groupId = project.objects.property<String>()
/**
* ArtifactId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
*/
@get:Internal
val id = project.objects.property<String>()
/**
* Artifact version in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
*/
@get:Internal
val version = project.objects.property<String>()
/**
* Reference the library template (sub-template) of a generator.
*/
@get:Internal
val library = project.objects.property<String?>()
/**
* Git user ID, e.g. openapitools.
*/
@get:Internal
val gitUserId = project.objects.property<String?>()
/**
* Git repo ID, e.g. openapi-generator.
*/
@get:Internal
val gitRepoId = project.objects.property<String?>()
/**
* Release note, default to 'Minor update'.
*/
@get:Internal
val releaseNote = project.objects.property<String?>()
/**
* HTTP user agent, e.g. codegen_csharp_api_client, default to 'OpenAPI-Generator/{packageVersion}}/{language}'
*/
@get:Internal
val httpUserAgent = project.objects.property<String?>()
/**
* Specifies how a reserved name should be escaped to.
*/
@get:Internal
val reservedWordsMappings = project.objects.property<Map<String, String>>()
/**
* Specifies an override location for the .openapi-generator-ignore file. Most useful on initial generation.
*/
@get:Internal
val ignoreFileOverride = project.objects.property<String?>()
/**
* Remove prefix of operationId, e.g. config_getId => getId
*/
@get:Internal
val removeOperationIdPrefix = project.objects.property<Boolean?>()
/**
* Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all).
*
* This option enables/disables generation of ALL api-related files.
*
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
*/
@get:Internal
val apiFilesConstrainedTo = project.objects.listProperty<String>()
/**
* Defines which model-related files should be generated. This allows you to create a subset of generated files (or none at all).
*
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
*/
@get:Internal
val modelFilesConstrainedTo = project.objects.listProperty<String>()
/**
* Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all).
*
* Supporting files are those related to projects/frameworks which may be modified
* by consumers.
*
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
*/
@get:Internal
val supportingFilesConstrainedTo = project.objects.listProperty<String>()
/**
* Defines whether or not model-related _test_ files should be generated.
*
* This option enables/disables generation of ALL model-related _test_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
@get:Internal
val generateModelTests = project.objects.property<Boolean>()
/**
* Defines whether or not model-related _documentation_ files should be generated.
*
* This option enables/disables generation of ALL model-related _documentation_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
@get:Internal
val generateModelDocumentation = project.objects.property<Boolean>()
/**
* Defines whether or not api-related _test_ files should be generated.
*
* This option enables/disables generation of ALL api-related _test_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
@get:Internal
val generateApiTests = project.objects.property<Boolean>()
/**
* Defines whether or not api-related _documentation_ files should be generated.
*
* This option enables/disables generation of ALL api-related _documentation_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
@get:Internal
val generateApiDocumentation = project.objects.property<Boolean>()
/**
* A special-case setting which configures some generators with XML support. In some cases,
* this forces json OR xml, so the default here is false.
*/
@get:Internal
val withXml = project.objects.property<Boolean>()
/**
* A dynamic map of options specific to a generator.
*/
@get:Internal
val configOptions = project.objects.property<Map<String, String>>()
private val originalEnvironmentVariables = mutableMapOf<String, String?>()
private fun <T : Any?> Property<T>.ifNotEmpty(block: Property<T>.(T) -> Unit) {
if (isPresent) {
val item: T? = get()
if (item != null) {
when (get()) {
is String -> if ((get() as String).isNotEmpty()) {
block(get())
}
is String? -> if (true == (get() as String?)?.isNotEmpty()) {
block(get())
}
else -> block(get())
}
}
}
}
@Suppress("unused")
@TaskAction
fun doWork() {
val configurator: CodegenConfigurator = if (configFile.isPresent) {
CodegenConfigurator.fromFile(configFile.get())
} else CodegenConfigurator()
try {
if (systemProperties.isPresent) {
systemProperties.get().forEach { (key, value) ->
// 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)
}
}
if (supportingFilesConstrainedTo.isPresent && supportingFilesConstrainedTo.get().isNotEmpty()) {
System.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesConstrainedTo.get().joinToString(","))
} else {
System.clearProperty(CodegenConstants.SUPPORTING_FILES)
}
if (modelFilesConstrainedTo.isPresent && modelFilesConstrainedTo.get().isNotEmpty()) {
System.setProperty(CodegenConstants.MODELS, modelFilesConstrainedTo.get().joinToString(","))
} else {
System.clearProperty(CodegenConstants.MODELS)
}
if (apiFilesConstrainedTo.isPresent && apiFilesConstrainedTo.get().isNotEmpty()) {
System.setProperty(CodegenConstants.APIS, apiFilesConstrainedTo.get().joinToString(","))
} else {
System.clearProperty(CodegenConstants.APIS)
}
System.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.get().toString())
System.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.get().toString())
System.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.get().toString())
System.setProperty(CodegenConstants.API_TESTS, generateApiTests.get().toString())
System.setProperty(CodegenConstants.WITH_XML, withXml.get().toString())
// now override with any specified parameters
verbose.ifNotEmpty { value ->
configurator.isVerbose = value
}
validateSpec.ifNotEmpty { value ->
configurator.isValidateSpec = value
}
skipOverwrite.ifNotEmpty { value ->
configurator.isSkipOverwrite = value ?: false
}
inputSpec.ifNotEmpty { value ->
configurator.inputSpec = value
}
generatorName.ifNotEmpty { value ->
configurator.generatorName = value
}
outputDir.ifNotEmpty { value ->
configurator.outputDir = value
}
auth.ifNotEmpty { value ->
configurator.auth = value
}
templateDir.ifNotEmpty { value ->
configurator.templateDir = value
}
apiPackage.ifNotEmpty { value ->
configurator.apiPackage = value
}
modelPackage.ifNotEmpty { value ->
configurator.modelPackage = value
}
modelNamePrefix.ifNotEmpty { value ->
configurator.modelNamePrefix = value
}
modelNameSuffix.ifNotEmpty { value ->
configurator.modelNameSuffix = value
}
invokerPackage.ifNotEmpty { value ->
configurator.invokerPackage = value
}
groupId.ifNotEmpty { value ->
configurator.groupId = value
}
id.ifNotEmpty { value ->
configurator.artifactId = value
}
version.ifNotEmpty { value ->
configurator.artifactVersion = value
}
library.ifNotEmpty { value ->
configurator.library = value
}
gitUserId.ifNotEmpty { value ->
configurator.gitUserId = value
}
gitRepoId.ifNotEmpty { value ->
configurator.gitRepoId = value
}
releaseNote.ifNotEmpty { value ->
configurator.releaseNote = value
}
httpUserAgent.ifNotEmpty { value ->
configurator.httpUserAgent = value
}
ignoreFileOverride.ifNotEmpty { value ->
configurator.ignoreFileOverride = value
}
removeOperationIdPrefix.ifNotEmpty { value ->
configurator.removeOperationIdPrefix = value!!
}
if (systemProperties.isPresent) {
systemProperties.get().forEach { entry ->
configurator.addSystemProperty(entry.key, entry.value)
}
}
if (instantiationTypes.isPresent) {
instantiationTypes.get().forEach { entry ->
configurator.addInstantiationType(entry.key, entry.value)
}
}
if (importMappings.isPresent) {
importMappings.get().forEach { entry ->
configurator.addImportMapping(entry.key, entry.value)
}
}
if (typeMappings.isPresent) {
typeMappings.get().forEach { entry ->
configurator.addTypeMapping(entry.key, entry.value)
}
}
if (additionalProperties.isPresent) {
additionalProperties.get().forEach { entry ->
configurator.addAdditionalProperty(entry.key, entry.value)
}
}
if (languageSpecificPrimitives.isPresent) {
languageSpecificPrimitives.get().forEach {
configurator.addLanguageSpecificPrimitive(it)
}
}
if (reservedWordsMappings.isPresent) {
reservedWordsMappings.get().forEach { entry ->
configurator.addAdditionalReservedWordMapping(entry.key, entry.value)
}
}
val clientOptInput = configurator.toClientOptInput()
val codgenConfig = clientOptInput.config
if (configOptions.isPresent) {
val userSpecifiedConfigOptions = configOptions.get()
codgenConfig.cliOptions().forEach {
if (userSpecifiedConfigOptions.containsKey(it.opt)) {
clientOptInput.config.additionalProperties()[it.opt] = userSpecifiedConfigOptions[it.opt]
}
}
}
try {
val out = services.get(StyledTextOutputFactory::class.java).create("openapi")
out.withStyle(StyledTextOutput.Style.Success)
DefaultGenerator().opts(clientOptInput).generate()
out.println("Successfully generated code to ${configurator.outputDir}")
} catch (e: RuntimeException) {
throw GradleException("Code generation failed.", e)
}
} finally {
// Reset all modified system properties back to their original state
originalEnvironmentVariables.forEach {
when {
it.value == null -> System.clearProperty(it.key)
else -> System.setProperty(it.key, it.value)
}
}
originalEnvironmentVariables.clear()
}
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
import org.gradle.internal.logging.text.StyledTextOutput
import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.openapitools.codegen.CodegenConfigLoader
import org.openapitools.codegen.CodegenType
/**
* A task which lists out the generators available in OpenAPI Generator
*
* Example (CLI):
*
* ./gradlew -q openApiGenerators
*
* @author Jim Schubert
*/
open class GeneratorsTask : DefaultTask() {
@Suppress("unused")
@TaskAction
fun doWork() {
val generators = CodegenConfigLoader.getAll()
val out = services.get(StyledTextOutputFactory::class.java).create("openapi")
StringBuilder().apply {
val types = CodegenType.values()
append("The following generators are available:")
append(System.lineSeparator())
append(System.lineSeparator())
for (type in types) {
append(type.name).append(" generators:")
append(System.lineSeparator())
generators.filter { it.tag == type }
.sortedBy { it.name }
.forEach({ generator ->
append(" - ")
append(generator.name)
append(System.lineSeparator())
})
append(System.lineSeparator())
append(System.lineSeparator())
}
out.withStyle(StyledTextOutput.Style.Success)
out.formatln("%s%n", toString())
}
}
}

View File

@@ -0,0 +1,132 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin.tasks
import com.samskivert.mustache.Mustache
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
import org.gradle.internal.logging.text.StyledTextOutput
import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.gradle.kotlin.dsl.property
import org.openapitools.codegen.CodegenConfig
import org.openapitools.codegen.CodegenConstants
import org.openapitools.codegen.DefaultGenerator
import org.openapitools.codegen.SupportingFile
import java.io.File
import java.io.IOException
import java.nio.charset.Charset
/**
* A task which generates a new generator (meta). Useful for redistributable generator packages.
*
* @author Jim Schubert
*/
open class MetaTask : DefaultTask() {
@get:Internal
val generatorName = project.objects.property<String>()
@get:Internal
val packageName = project.objects.property<String>()
@get:Internal
val outputFolder = project.objects.property<String>()
@Suppress("unused")
@TaskAction
fun doWork() {
val packageToPath = packageName.get().replace(".", File.separator)
val dir = File(outputFolder.get())
val klass = "${generatorName.get().titleCasedTextOnly()}Generator"
val templateResourceDir = generatorName.get().hyphenatedTextOnly()
val out = services.get(StyledTextOutputFactory::class.java).create("openapi")
out.withStyle(StyledTextOutput.Style.Info)
logger.debug("package: {}", packageName.get())
logger.debug("dir: {}", dir.absolutePath)
logger.debug("generator class: {}", klass)
val supportingFiles = listOf(
SupportingFile("pom.mustache", "", "pom.xml"),
SupportingFile("generatorClass.mustache", dir("src", "main", "java", packageToPath), "$klass.java"),
SupportingFile("README.mustache", "", "README.md"),
SupportingFile("api.template", dir("src", "main", "resources", templateResourceDir), "api.mustache"),
SupportingFile("model.template", dir("src", "main", "resources", templateResourceDir), "model.mustache"),
SupportingFile("myFile.template", dir("src", "main", "resources", templateResourceDir), "myFile.mustache"),
SupportingFile("services.mustache", dir("src", "main", "resources", "META-INF", "services"), CodegenConfig::class.java.canonicalName))
val currentVersion = CodegenConstants::class.java.`package`.implementationVersion
val data = mapOf("generatorPackage" to packageToPath,
"generatorClass" to klass,
"name" to templateResourceDir,
"fullyQualifiedGeneratorClass" to "${packageName.get()}.$klass",
"openapiGeneratorVersion" to currentVersion)
val generator = DefaultGenerator()
supportingFiles.map {
try {
val destinationFolder = File(File(dir.absolutePath), it.folder)
destinationFolder.mkdirs()
val outputFile = File(destinationFolder, it.destinationFilename)
val template = generator.readTemplate(File("codegen", it.templateFile).path)
var formatted = template
if (it.templateFile.endsWith(".mustache")) {
formatted = Mustache.compiler()
.withLoader(loader(generator))
.defaultValue("")
.compile(template).execute(data)
}
outputFile.writeText(formatted, Charset.forName("UTF8"))
out.formatln("Wrote file to %s", outputFile.absolutePath)
// TODO: register outputs
// return outputFile
} catch (e: IOException) {
logger.error(e.message)
throw GradleException("Can't generate project", e)
}
}
out.withStyle(StyledTextOutput.Style.Success)
out.formatln("Created generator %s", klass)
}
private fun loader(generator: DefaultGenerator): Mustache.TemplateLoader {
return Mustache.TemplateLoader { name ->
generator.getTemplateReader("codegen${File.separator}$name.mustache")
}
}
private fun String.titleCasedTextOnly(): String =
this.split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "", transform = String::capitalize)
private fun String.hyphenatedTextOnly(): String =
this.split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "-", transform = String::toLowerCase)
private fun dir(vararg parts: String): String =
parts.joinToString(separator = File.separator)
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin.tasks
import io.swagger.parser.OpenAPIParser
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.options.Option
import org.gradle.internal.logging.text.StyledTextOutput
import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.gradle.kotlin.dsl.property
/**
* A generator which validates an Open API spec. This task outputs a list of validation issues and errors.
*
* Example:
* cli:
*
* ./gradlew openApiValidate --input=/path/to/file
*
* build.gradle:
*
* openApiMeta {
* inputSpec = "path/to/spec.yaml"
* }
*
* @author Jim Schubert
*/
open class ValidateTask : DefaultTask() {
@get:Internal
var inputSpec = project.objects.property<String>()
@Suppress("unused")
@get:Internal
@set:Option(option = "input", description = "The input specification.")
var input: String? = null
set(value) {
inputSpec.set(value)
}
@Suppress("unused")
@TaskAction
fun doWork() {
val spec = inputSpec.get()
logger.quiet("Validating spec $spec")
val result = OpenAPIParser().readLocation(spec, null, null)
val messages = result.messages.toSet()
val out = services.get(StyledTextOutputFactory::class.java).create("openapi")
if (messages.isNotEmpty()) {
out.withStyle(StyledTextOutput.Style.Error)
out.println("\nSpec is invalid.\nIssues:\n")
messages.forEach {
out.withStyle(StyledTextOutput.Style.Error)
out.println("\t$it\n")
}
throw GradleException("Validation failed.")
} else {
out.withStyle(StyledTextOutput.Style.Success)
out.println("Spec is valid.")
}
}
}

View File

@@ -0,0 +1,71 @@
package org.openapitools.generator.gradle.plugin
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.testng.annotations.Test
import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class GenerateTaskDslTest : TestBase() {
override var temp: File = createTempDir(javaClass.simpleName)
private val defaultBuildGradle = """
plugins {
id 'org.openapi.generator'
}
openApiGenerate {
generatorName = "kotlin"
inputSpec = file("spec.yaml").absolutePath
outputDir = file("build/kotlin").absolutePath
apiPackage = "org.openapitools.example.api"
invokerPackage = "org.openapitools.example.invoker"
modelPackage = "org.openapitools.example.model"
configOptions = [
dateLibrary: "java8"
]
}
""".trimIndent()
@Test
fun `openApiGenerate should create an expected file structure from DSL config`() {
// Arrange
val projectFiles = mapOf(
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml")
)
withProject(defaultBuildGradle, projectFiles)
// Act
val result = GradleRunner.create()
.withProjectDir(temp)
.withArguments("openApiGenerate")
.withPluginClasspath()
.build()
// Assert
assertTrue(result.output.contains("Successfully generated code to"), "User friendly generate notice is missing.")
listOf(
"build/kotlin/.openapi-generator-ignore",
"build/kotlin/docs/PetsApi.md",
"build/kotlin/docs/Pets.md",
"build/kotlin/docs/Error.md",
"build/kotlin/docs/Pet.md",
"build/kotlin/README.md",
"build/kotlin/build.gradle",
"build/kotlin/.openapi-generator/VERSION",
"build/kotlin/settings.gradle",
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Pets.kt",
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Pet.kt",
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Error.kt",
"build/kotlin/src/main/kotlin/org/openapitools/example/api/PetsApi.kt",
"build/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt"
).map {
val f = File(temp, it)
assertTrue(f.exists() && f.isFile, "An expected file was not generated when invoking the generation.")
}
assertEquals(TaskOutcome.SUCCESS, result.task(":openApiGenerate")?.outcome,
"Expected a successful run, but found ${result.task(":openApiGenerate")?.outcome}")
}
}

View File

@@ -0,0 +1,38 @@
package org.openapitools.generator.gradle.plugin
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.testng.annotations.Test
import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class GeneratorsTaskDslTest : TestBase() {
override var temp: File = createTempDir(javaClass.simpleName)
@Test
fun `openApiGenerators should list generators available to the user`() {
// Arrange
withProject("""
| plugins {
| id 'org.openapi.generator'
| }
""".trimMargin())
// Act
val result = GradleRunner.create()
.withProjectDir(temp)
.withArguments("openApiGenerators")
.withPluginClasspath()
.build()
// Assert
assertTrue(result.output.contains("The following generators are available:"), "User friendly generator notice is missing.")
assertTrue(result.output.contains("CLIENT generators:"), "Expected client generator header is missing.")
assertTrue(result.output.contains("android"), "Spot-checking listed client generators is missing a client generator.")
assertTrue(result.output.contains("SERVER generators:"), "Expected server generator header is missing.")
assertTrue(result.output.contains("kotlin-server"), "Spot-checking listed server generators is missing a server generator.")
assertEquals(TaskOutcome.SUCCESS, result.task(":openApiGenerators")?.outcome,
"Expected a successful run, but found ${result.task(":openApiGenerators")?.outcome}")
}
}

View File

@@ -0,0 +1,58 @@
package org.openapitools.generator.gradle.plugin
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.testng.annotations.Test
import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class MetaTaskDslTest : TestBase() {
override var temp: File = createTempDir(javaClass.simpleName)
@Test
fun `openApiMeta should generate desired project contents`() {
// Arrange
val buildDirReplacement = "\$buildDir/meta"
withProject("""
| plugins {
| id 'org.openapi.generator'
| }
|
| openApiMeta {
| generatorName = "Sample"
| packageName = "org.openapitools.example"
| outputFolder = "$buildDirReplacement".toString()
| }
""".trimMargin())
// Act
val result = GradleRunner.create()
.withProjectDir(temp)
.withArguments("openApiMeta")
.withPluginClasspath()
.build()
// Assert
assertTrue(result.output.contains("Wrote file to"), "User friendly write notice is missing.")
// To avoid any OS-specific output causing issues with our stdout comparisons, only compare on expected filenames.
listOf(
"SampleGenerator.java",
"README.md",
"api.mustache",
"model.mustache",
"myFile.mustache",
"org.openapitools.codegen.CodegenConfig",
"pom.xml"
).map {
assertTrue(result.output.contains(it), "Expected $it to be listed in gradle stdout.")
}
assertEquals(
TaskOutcome.SUCCESS,
result.task(":openApiMeta")?.outcome,
"Expected a successful run, but found ${result.task(":openApiMeta")?.outcome}"
)
}
}

View File

@@ -0,0 +1,34 @@
package org.openapitools.generator.gradle.plugin
import org.testng.annotations.AfterMethod
import org.testng.annotations.BeforeMethod
import java.io.File
import java.io.InputStream
abstract class TestBase {
protected open lateinit var temp: File
@BeforeMethod
protected fun before() {
temp = createTempDir(javaClass.simpleName)
temp.deleteOnExit()
}
@AfterMethod
protected fun after(){
temp.deleteRecursively()
}
protected fun withProject(
buildContents: String,
projectFiles: Map<String, InputStream> = mapOf()
) {
val buildFile = File(temp,"build.gradle")
buildFile.writeText(buildContents)
projectFiles.forEach { entry ->
val target = File(temp, entry.key)
entry.value.copyTo(target.outputStream())
}
}
}

View File

@@ -0,0 +1,99 @@
package org.openapitools.generator.gradle.plugin
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome.FAILED
import org.gradle.testkit.runner.TaskOutcome.SUCCESS
import org.testng.annotations.Test
import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class ValidateTaskDslTest : TestBase() {
override var temp: File = createTempDir(javaClass.simpleName)
@Test
fun `openApiValidate should fail on non-file spec`() {
// Arrange
withProject("""
| plugins {
| id 'org.openapi.generator'
| }
|
| openApiValidate {
| inputSpec = "some_location"
| }
""".trimMargin())
// Act
val result = GradleRunner.create()
.withProjectDir(temp)
.withArguments("openApiValidate")
.withPluginClasspath()
.buildAndFail()
// Assert
assertTrue(result.output.contains("unable to read location `some_location`"), "Unexpected/no message presented to the user for a spec pointing to an invalid URI.")
assertEquals(FAILED, result.task(":openApiValidate")?.outcome,
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}")
}
@Test
fun `openApiValidate should succeed on valid spec`() {
// Arrange
val projectFiles = mapOf(
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml")
)
withProject("""
| plugins {
| id 'org.openapi.generator'
| }
|
| openApiValidate {
| inputSpec = file("spec.yaml").absolutePath
| }
""".trimMargin(), projectFiles)
// Act
val result = GradleRunner.create()
.withProjectDir(temp)
.withArguments("openApiValidate")
.withPluginClasspath()
.build()
// Assert
assertTrue(result.output.contains("Spec is valid."), "Unexpected/no message presented to the user for a valid spec.")
assertEquals(SUCCESS, result.task(":openApiValidate")?.outcome,
"Expected a successful run, but found ${result.task(":openApiValidate")?.outcome}")
}
@Test
fun `openApiValidate should fail on invalid spec`() {
// Arrange
val projectFiles = mapOf(
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0-invalid.yaml")
)
withProject("""
| plugins {
| id 'org.openapi.generator'
| }
|
| openApiValidate {
| inputSpec = file('spec.yaml').absolutePath
| }
""".trimMargin(), projectFiles)
// Act
val result = GradleRunner.create()
.withProjectDir(temp)
.withArguments("openApiValidate")
.withPluginClasspath()
.buildAndFail()
// Assert
assertTrue(result.output.contains("Spec is invalid."), "Unexpected/no message presented to the user for an invalid spec.")
assertEquals(FAILED, result.task(":openApiValidate")?.outcome,
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}")
}
}

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

@@ -0,0 +1,109 @@
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
'201':
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Pet:
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Error:
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string

View File

@@ -181,5 +181,3 @@ compileTestKotlin {
jvmTarget = "1.8"
}
}
uploadArchives.dependsOn 'check'

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.GeneratorProperties
/**
@@ -324,6 +323,8 @@ open class GenerateTask : DefaultTask() {
@get:Internal
val configOptions = project.objects.property<Map<String, String>>()
private val originalEnvironmentVariables = mutableMapOf<String, String?>()
private fun <T : Any?> Property<T>.ifNotEmpty(block: Property<T>.(T) -> Unit) {
if (isPresent) {
val item: T? = get()
@@ -351,33 +352,36 @@ open class GenerateTask : DefaultTask() {
try {
if (systemProperties.isPresent) {
systemProperties.get().forEach { (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)
}
}
if (supportingFilesConstrainedTo.isPresent && supportingFilesConstrainedTo.get().isNotEmpty()) {
GeneratorProperties.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesConstrainedTo.get().joinToString(","))
System.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesConstrainedTo.get().joinToString(","))
} else {
GeneratorProperties.clearProperty(CodegenConstants.SUPPORTING_FILES)
System.clearProperty(CodegenConstants.SUPPORTING_FILES)
}
if (modelFilesConstrainedTo.isPresent && modelFilesConstrainedTo.get().isNotEmpty()) {
GeneratorProperties.setProperty(CodegenConstants.MODELS, modelFilesConstrainedTo.get().joinToString(","))
System.setProperty(CodegenConstants.MODELS, modelFilesConstrainedTo.get().joinToString(","))
} else {
GeneratorProperties.clearProperty(CodegenConstants.MODELS)
System.clearProperty(CodegenConstants.MODELS)
}
if (apiFilesConstrainedTo.isPresent && apiFilesConstrainedTo.get().isNotEmpty()) {
GeneratorProperties.setProperty(CodegenConstants.APIS, apiFilesConstrainedTo.get().joinToString(","))
System.setProperty(CodegenConstants.APIS, apiFilesConstrainedTo.get().joinToString(","))
} else {
GeneratorProperties.clearProperty(CodegenConstants.APIS)
System.clearProperty(CodegenConstants.APIS)
}
GeneratorProperties.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.get().toString())
GeneratorProperties.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.get().toString())
GeneratorProperties.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.get().toString())
GeneratorProperties.setProperty(CodegenConstants.API_TESTS, generateApiTests.get().toString())
GeneratorProperties.setProperty(CodegenConstants.WITH_XML, withXml.get().toString())
System.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.get().toString())
System.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.get().toString())
System.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.get().toString())
System.setProperty(CodegenConstants.API_TESTS, generateApiTests.get().toString())
System.setProperty(CodegenConstants.WITH_XML, withXml.get().toString())
// now override with any specified parameters
verbose.ifNotEmpty { value ->
@@ -537,7 +541,14 @@ open class GenerateTask : DefaultTask() {
throw GradleException("Code generation failed.", e)
}
} finally {
GeneratorProperties.reset()
// 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

@@ -48,12 +48,14 @@ class GenerateTaskDslTest : TestBase() {
listOf(
"build/kotlin/.openapi-generator-ignore",
"build/kotlin/docs/PetsApi.md",
"build/kotlin/docs/Pets.md",
"build/kotlin/docs/Error.md",
"build/kotlin/docs/Pet.md",
"build/kotlin/README.md",
"build/kotlin/build.gradle",
"build/kotlin/.openapi-generator/VERSION",
"build/kotlin/settings.gradle",
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Pets.kt",
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Pet.kt",
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Error.kt",
"build/kotlin/src/main/kotlin/org/openapitools/example/api/PetsApi.kt",

View File

@@ -23,7 +23,7 @@
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>3.3.1</version>
<version>3.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
@@ -34,12 +34,12 @@
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-compat</artifactId>
<version>3.5.0</version>
<version>3.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.3.1</version>
<version>3.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>

View File

@@ -51,7 +51,6 @@ import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.config.GeneratorProperties;
import org.sonatype.plexus.build.incremental.BuildContext;
import org.sonatype.plexus.build.incremental.DefaultBuildContext;
import org.slf4j.Logger;
@@ -145,6 +144,12 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(name = "skipOverwrite", required = false)
private Boolean skipOverwrite;
/**
* Specifies if the existing files should be overwritten during the generation.
*/
@Parameter(name = "removeOperationIdPrefix", required = false)
private Boolean removeOperationIdPrefix;
/**
* The package to use for generated api objects/classes
*/
@@ -205,36 +210,6 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(name = "ignoreFileOverride", required = false)
private String ignoreFileOverride;
/**
* To remove operationId prefix (e.g. user_getName => getName)
*/
@Parameter(name = "removeOperationIdPrefix", required = false)
private Boolean removeOperationIdPrefix;
/**
* To write all log messages (not just errors) to STDOUT
*/
@Parameter(name = "logToStderr", required = false)
private Boolean logToStderr;
/**
* To file post-processing hook
*/
@Parameter(name = "enablePostProcessFile", required = false)
private Boolean enablePostProcessFile;
/**
* To skip spec validation
*/
@Parameter(name = "skipValidateSpec", required = false)
private Boolean skipValidateSpec;
/**
* To generate alias (array, map) as model
*/
@Parameter(name = "generateAliasAsModel", required = false)
private Boolean generateAliasAsModel;
/**
* A map of language-specific parameters as passed with the -c option to the command line
*/
@@ -457,22 +432,6 @@ public class CodeGenMojo extends AbstractMojo {
configurator.setIgnoreFileOverride(ignoreFileOverride);
}
if (skipValidateSpec != null) {
configurator.setSkipOverwrite(skipValidateSpec);
}
if (logToStderr != null) {
configurator.setLogToStderr(logToStderr);
}
if (enablePostProcessFile != null) {
configurator.setEnablePostProcessFile(enablePostProcessFile);
}
if (generateAliasAsModel != null) {
configurator.setGenerateAliasAsModel(generateAliasAsModel);
}
// TODO: After 3.0.0 release (maybe for 3.1.0): Fully deprecate lang.
if (isNotEmpty(generatorName)) {
configurator.setGeneratorName(generatorName);
@@ -540,28 +499,28 @@ public class CodeGenMojo extends AbstractMojo {
// Set generation options
if (null != generateApis && generateApis) {
GeneratorProperties.setProperty(CodegenConstants.APIS, "");
System.setProperty(CodegenConstants.APIS, "");
} else {
GeneratorProperties.clearProperty(CodegenConstants.APIS);
System.clearProperty(CodegenConstants.APIS);
}
if (null != generateModels && generateModels) {
GeneratorProperties.setProperty(CodegenConstants.MODELS, modelsToGenerate);
System.setProperty(CodegenConstants.MODELS, modelsToGenerate);
} else {
GeneratorProperties.clearProperty(CodegenConstants.MODELS);
System.clearProperty(CodegenConstants.MODELS);
}
if (null != generateSupportingFiles && generateSupportingFiles) {
GeneratorProperties.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesToGenerate);
System.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesToGenerate);
} else {
GeneratorProperties.clearProperty(CodegenConstants.SUPPORTING_FILES);
System.clearProperty(CodegenConstants.SUPPORTING_FILES);
}
GeneratorProperties.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.toString());
GeneratorProperties.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.toString());
GeneratorProperties.setProperty(CodegenConstants.API_TESTS, generateApiTests.toString());
GeneratorProperties.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.toString());
GeneratorProperties.setProperty(CodegenConstants.WITH_XML, withXml.toString());
System.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.toString());
System.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.toString());
System.setProperty(CodegenConstants.API_TESTS, generateApiTests.toString());
System.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.toString());
System.setProperty(CodegenConstants.WITH_XML, withXml.toString());
if (configOptions != null) {
// Retained for backwards-compataibility with configOptions -> instantiation-types
@@ -634,13 +593,13 @@ public class CodeGenMojo extends AbstractMojo {
if (environmentVariables != null) {
for (String key : environmentVariables.keySet()) {
originalEnvironmentVariables.put(key, GeneratorProperties.getProperty(key));
originalEnvironmentVariables.put(key, System.getProperty(key));
String value = environmentVariables.get(key);
if (value == null) {
// don't put null values
value = "";
}
GeneratorProperties.setProperty(key, value);
System.setProperty(key, value);
configurator.addSystemProperty(key, value);
}
}
@@ -721,9 +680,9 @@ public class CodeGenMojo extends AbstractMojo {
// when running the plugin multiple consecutive times with different configurations.
for (Map.Entry<String, String> entry : originalEnvironmentVariables.entrySet()) {
if (entry.getValue() == null) {
GeneratorProperties.clearProperty(entry.getKey());
System.clearProperty(entry.getKey());
} else {
GeneratorProperties.setProperty(entry.getKey(), entry.getValue());
System.setProperty(entry.getKey(), entry.getValue());
}
}
}

View File

@@ -1,129 +0,0 @@
package org.openapitools.codegen.online.api;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openapitools.codegen.online.model.ResponseCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.text.MatchesPattern.matchesPattern;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@WebMvcTest(GenApiController.class)
public class GenApiControllerTest {
private static final String OPENAPI_URL = "http://petstore.swagger.io/v2/swagger.json";
private static final String UUID_REGEX = "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[89aAbB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}";
@Autowired
private MockMvc mockMvc;
@Test
public void clientLanguages() throws Exception {
getLanguages("clients", "java");
}
@Test
public void serverFrameworks() throws Exception {
getLanguages("servers", "spring");
}
public void getLanguages(String type, String expected) throws Exception {
mockMvc.perform(get("/api/gen/" + type))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.[*]").value(hasItem(expected)));
}
@Test
public void clientOptions() throws Exception {
getOptions("clients", "java");
}
@Test
public void clientOptionsUnknown() throws Exception {
mockMvc.perform(get("/api/gen/clients/unknown"))
.andExpect(status().isNotFound());
}
@Test
public void serverOptions() throws Exception {
getOptions("servers", "spring");
}
@Test
public void serverOptionsUnknown() throws Exception {
mockMvc.perform(get("/api/gen/servers/unknown"))
.andExpect(status().isNotFound());
}
private void getOptions(String type, String name) throws Exception {
mockMvc.perform(get("/api/gen/" + type + "/" + name))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.sortParamsByRequiredFlag.opt").value("sortParamsByRequiredFlag"));
}
@Test
public void generateClient() throws Exception {
generateAndDownload("clients", "java");
}
@Test
public void generateServer() throws Exception {
generateAndDownload("servers", "spring");
}
private void generateAndDownload(String type, String name) throws Exception {
String result = mockMvc.perform(post("http://test.com:1234/api/gen/" + type + "/" + name)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content("{\"openAPIUrl\": \"" + OPENAPI_URL + "\"}"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.code").value(matchesPattern(UUID_REGEX)))
.andExpect(jsonPath("$.link").value(matchesPattern("http\\:\\/\\/test.com\\:1234\\/api\\/gen\\/download\\/" + UUID_REGEX)))
.andReturn().getResponse().getContentAsString();
String code = new ObjectMapper().readValue(result, ResponseCode.class).getCode();
mockMvc.perform(get("http://test.com:1234/api/gen/download/" + code))
.andExpect(content().contentType("application/zip"))
.andExpect(status().isOk())
.andExpect(header().string(HttpHeaders.CONTENT_LENGTH, not(0)));
}
@Test
public void generateWIthForwardedHeaders() throws Exception {
String result = mockMvc.perform(post("http://test.com:1234/api/gen/clients/java")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.header("X-Forwarded-Proto", "https")
.header("X-Forwarded-Host", "forwarded.com")
.header("X-Forwarded-Port", "5678")
.content("{\"openAPIUrl\": \"" + OPENAPI_URL + "\"}"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.code").value(matchesPattern(UUID_REGEX)))
.andExpect(jsonPath("$.link").value(matchesPattern("https\\:\\/\\/forwarded.com\\:5678\\/api\\/gen\\/download\\/" + UUID_REGEX)))
.andReturn().getResponse().getContentAsString();
String code = new ObjectMapper().readValue(result, ResponseCode.class).getCode();
mockMvc.perform(get("http://test.com:1234/api/gen/download/" + code))
.andExpect(content().contentType("application/zip"))
.andExpect(status().isOk())
.andExpect(header().string(HttpHeaders.CONTENT_LENGTH, not(0)));
}
}

View File

@@ -204,7 +204,7 @@
<version>${swagger-core-version}</version>
</dependency>
<dependency>
<groupId>${swagger-parser-groupid}</groupId>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser</artifactId>
<version>${swagger-parser-version}</version>
</dependency>

View File

@@ -81,8 +81,6 @@ public interface CodegenConfig {
String escapeTextWhileAllowingNewLines(String text);
String encodePath(String text);
String escapeUnsafeCharacters(String input);
String escapeReservedWord(String name);
@@ -173,8 +171,6 @@ public interface CodegenConfig {
void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations);
Map<String, Object> updateAllModels(Map<String, Object> objs);
Map<String, Object> postProcessAllModels(Map<String, Object> objs);
Map<String, Object> postProcessModels(Map<String, Object> objs);
@@ -264,11 +260,11 @@ public interface CodegenConfig {
boolean isEnablePostProcessFile();
void setEnablePostProcessFile(boolean isEnablePostProcessFile);
public void setEnablePostProcessFile(boolean isEnablePostProcessFile);
// set OpenAPI and schemas
void setGlobalOpenAPI(OpenAPI openAPI);
public void setGlobalOpenAPI(OpenAPI openAPI);
void setGlobalSchemas(OpenAPI openAPI);
public void setGlobalSchemas(OpenAPI openAPI);
}

View File

@@ -283,10 +283,4 @@ public class CodegenConstants {
public static final String ENABLE_POST_PROCESS_FILE_DESC = "Enable post-processing file using environment variables.";
public static final String OPEN_API_SPEC_NAME = "openAPISpecName";
public static final String GENERATE_ALIAS_AS_MODEL = "generateAliasAsModel";
public static final String GENERATE_ALIAS_AS_MODEL_DESC = "Generate alias to map, array as models";
public static final String USE_COMPARE_NET_OBJECTS = "useCompareNetObjects";
public static final String USE_COMPARE_NET_OBJECTS_DESC = "Use KellermanSoftware.CompareNetObjects for deep recursive object comparison. WARNING: this option incurs potential performance impact.";
}

View File

@@ -22,13 +22,11 @@ import io.swagger.v3.oas.models.ExternalDocumentation;
import java.util.*;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.apache.commons.lang3.builder.ToStringBuilder;
@JsonIgnoreProperties({"parentModel", "interfaceModels"})
public class CodegenModel {
public String parent, parentSchema;
public List<String> interfaces;
public List<String> allParents;
// References to parent and interface CodegenModels. Only set when code generator supports inheritance.
public CodegenModel parentModel;
@@ -48,18 +46,18 @@ public class CodegenModel {
public String arrayModelType;
public boolean isAlias; // Is this effectively an alias of another simple type
public boolean isString, isInteger;
public List<CodegenProperty> vars = new ArrayList<CodegenProperty>(); // all properties (without parent's properties)
public List<CodegenProperty> allVars = new ArrayList<CodegenProperty>(); // all properties (with parent's properties)
public List<CodegenProperty> vars = new ArrayList<CodegenProperty>();
public List<CodegenProperty> requiredVars = new ArrayList<CodegenProperty>(); // a list of required properties
public List<CodegenProperty> optionalVars = new ArrayList<CodegenProperty>(); // a list of optional properties
public List<CodegenProperty> readOnlyVars = new ArrayList<CodegenProperty>(); // a list of read-only properties
public List<CodegenProperty> readWriteVars = new ArrayList<CodegenProperty>(); // a list of properties for read, write
public List<CodegenProperty> allVars = new ArrayList<CodegenProperty>();
public List<CodegenProperty> parentVars = new ArrayList<CodegenProperty>();
public Map<String, Object> allowableValues;
// Sorted sets of required parameters.
public Set<String> mandatory = new TreeSet<String>(); // without parent's required properties
public Set<String> allMandatory = new TreeSet<String>(); // with parent's required properties
public Set<String> mandatory = new TreeSet<String>();
public Set<String> allMandatory;
public Set<String> imports = new TreeSet<String>();
public boolean hasVars, emptyVars, hasMoreModels, hasEnums, isEnum, hasRequired, hasOptional, isArrayModel, hasChildren, isMapModel;
@@ -71,59 +69,16 @@ public class CodegenModel {
//The type of the value from additional properties. Used in map like objects.
public String additionalPropertiesType;
{
// By default these are the same collections. Where the code generator supports inheritance, composed models
// store the complete closure of owned and inherited properties in allVars and allMandatory.
allVars = vars;
allMandatory = mandatory;
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("parent", parent)
.append("parentSchema", parentSchema)
.append("interfaces", interfaces)
.append("parentModel", parentModel)
.append("interfaceModels", interfaceModels)
.append("children", children)
.append("name", name)
.append("classname", classname)
.append("title", title)
.append("description", description)
.append("classVarName", classVarName)
.append("modelJson", modelJson)
.append("dataType", dataType)
.append("xmlPrefix", xmlPrefix)
.append("xmlNamespace", xmlNamespace)
.append("xmlName", xmlName)
.append("classFilename", classFilename)
.append("unescapedDescription", unescapedDescription)
.append("discriminator", discriminator)
.append("defaultValue", defaultValue)
.append("arrayModelType", arrayModelType)
.append("isAlias", isAlias)
.append("isString", isString)
.append("isInteger", isInteger)
.append("vars", vars)
.append("requiredVars", requiredVars)
.append("optionalVars", optionalVars)
.append("readOnlyVars", readOnlyVars)
.append("readWriteVars", readWriteVars)
.append("allVars", allVars)
.append("parentVars", parentVars)
.append("allowableValues", allowableValues)
.append("mandatory", mandatory)
.append("allMandatory", allMandatory)
.append("imports", imports)
.append("hasVars", hasVars)
.append("emptyVars", emptyVars)
.append("hasMoreModels", hasMoreModels)
.append("hasEnums", hasEnums)
.append("isEnum", isEnum)
.append("hasRequired", hasRequired)
.append("hasOptional", hasOptional)
.append("isArrayModel", isArrayModel)
.append("hasChildren", hasChildren)
.append("isMapModel", isMapModel)
.append("hasOnlyReadOnly", hasOnlyReadOnly)
.append("externalDocumentation", externalDocumentation)
.append("vendorExtensions", vendorExtensions)
.append("additionalPropertiesType", additionalPropertiesType)
.toString();
return String.format(Locale.ROOT, "%s(%s)", name, classname);
}
@Override
@@ -139,8 +94,6 @@ public class CodegenModel {
return false;
if (interfaces != null ? !interfaces.equals(that.interfaces) : that.interfaces != null)
return false;
if (allParents != null ? !allParents.equals(that.allParents) : that.allParents != null)
return false;
if (parentModel != null ? !parentModel.equals(that.parentModel) : that.parentModel != null)
return false;
if (interfaceModels != null ? !interfaceModels.equals(that.interfaceModels) : that.interfaceModels != null)
@@ -216,7 +169,6 @@ public class CodegenModel {
int result = parent != null ? parent.hashCode() : 0;
result = 31 * result + (parentSchema != null ? parentSchema.hashCode() : 0);
result = 31 * result + (interfaces != null ? interfaces.hashCode() : 0);
result = 31 * result + (allParents != null ? allParents.hashCode() : 0);
result = 31 * result + (parentModel != null ? parentModel.hashCode() : 0);
result = 31 * result + (interfaceModels != null ? interfaceModels.hashCode() : 0);
result = 31 * result + (name != null ? name.hashCode() : 0);
@@ -274,18 +226,10 @@ public class CodegenModel {
return interfaces;
}
public List<String> getAllParents() {
return allParents;
}
public void setInterfaces(List<String> interfaces) {
this.interfaces = interfaces;
}
public void setAllParents(List<String> allParents) {
this.allParents = allParents;
}
public CodegenModel getParentModel() {
return parentModel;
}
@@ -616,18 +560,4 @@ public class CodegenModel {
}
}
}
/**
* Remove self reference import
*/
public void removeSelfReferenceImport() {
for (CodegenProperty cp : allVars) {
// detect self import
if (cp.dataType.equalsIgnoreCase(this.classname) ||
(cp.isContainer && cp.items.dataType.equalsIgnoreCase(this.classname))) {
this.imports.remove(this.classname); // remove self import
cp.isSelfReference = true;
}
}
}
}

View File

@@ -18,12 +18,36 @@
package org.openapitools.codegen;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
public final class CodegenModelFactory {
private static final Map<CodegenModelType, Class<?>> typeMapping = new HashMap<CodegenModelType, Class<?>>();
/**
* Configure a different implementation class.
*
* @param type the type that shall be replaced
* @param implementation the implementation class must extend the default class and must provide a public no-arg constructor
*/
public static void setTypeMapping(CodegenModelType type, Class<?> implementation) {
if (!type.getDefaultImplementation().isAssignableFrom(implementation)) {
throw new IllegalArgumentException(implementation.getSimpleName() + " doesn't extend " + type.getDefaultImplementation().getSimpleName());
}
try {
implementation.getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
typeMapping.put(type, implementation);
}
@SuppressWarnings("unchecked")
public static <T> T newInstance(CodegenModelType type) {
Class<?> classType = typeMapping.get(type);
try {
return (T) type.getDefaultImplementation().getDeclaredConstructor().newInstance();
return (T) (classType != null ? classType : type.getDefaultImplementation()).getDeclaredConstructor().newInstance();
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
throw new RuntimeException(e);
}

View File

@@ -61,7 +61,6 @@ public class CodegenProperty implements Cloneable {
public boolean isReadOnly;
public boolean isWriteOnly;
public boolean isNullable;
public boolean isSelfReference;
public List<String> _enum;
public Map<String, Object> allowableValues;
public CodegenProperty items;
@@ -440,7 +439,6 @@ public class CodegenProperty implements Cloneable {
result = prime * result + ((isReadOnly ? 13 : 31));
result = prime * result + ((isWriteOnly ? 13 : 31));
result = prime * result + ((isNullable ? 13 : 31));
result = prime * result + ((isSelfReference ? 13 : 31));
result = prime * result + ((items == null) ? 0 : items.hashCode());
result = prime * result + ((mostInnerItems == null) ? 0 : mostInnerItems.hashCode());
result = prime * result + ((jsonSchema == null) ? 0 : jsonSchema.hashCode());
@@ -599,9 +597,6 @@ public class CodegenProperty implements Cloneable {
if (this.isNullable != other.isNullable) {
return false;
}
if (this.isSelfReference != other.isSelfReference ) {
return false;
}
if (this._enum != other._enum && (this._enum == null || !this._enum.equals(other._enum))) {
return false;
}
@@ -795,7 +790,6 @@ public class CodegenProperty implements Cloneable {
", isReadOnly=" + isReadOnly +
", isWriteOnly=" + isWriteOnly +
", isNullable=" + isNullable +
", isSelfReference=" + isSelfReference +
", _enum=" + _enum +
", allowableValues=" + allowableValues +
", items=" + items +

View File

@@ -53,7 +53,6 @@ import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.openapitools.codegen.CodegenDiscriminator.MappedModel;
import org.openapitools.codegen.config.GeneratorProperties;
import org.openapitools.codegen.examples.ExampleGenerator;
import org.openapitools.codegen.serializer.SerializerUtils;
import org.openapitools.codegen.utils.ModelUtils;
@@ -71,6 +70,7 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
@@ -82,8 +82,8 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.escape;
import static org.openapitools.codegen.utils.StringUtils.underscore;
import static org.openapitools.codegen.utils.StringUtils.escape;
public class DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
@@ -115,7 +115,6 @@ public class DefaultCodegen implements CodegenConfig {
protected List<CliOption> cliOptions = new ArrayList<CliOption>();
protected boolean skipOverwrite;
protected boolean removeOperationIdPrefix;
protected boolean supportsMultipleInheritance;
protected boolean supportsInheritance;
protected boolean supportsMixins;
protected Map<String, String> supportedLibraries = new LinkedHashMap<String, String>();
@@ -208,91 +207,58 @@ public class DefaultCodegen implements CodegenConfig {
this.setEnablePostProcessFile(Boolean.valueOf(additionalProperties
.get(CodegenConstants.ENABLE_POST_PROCESS_FILE).toString()));
}
if (additionalProperties.containsKey(CodegenConstants.GENERATE_ALIAS_AS_MODEL)) {
ModelUtils.setGenerateAliasAsModel(Boolean.valueOf(additionalProperties
.get(CodegenConstants.GENERATE_ALIAS_AS_MODEL).toString()));
}
}
// override with any special post-processing for all models
@SuppressWarnings({"static-method", "unchecked"})
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
return objs;
}
/**
* Loop through all models to update different flags (e.g. isSelfReference), children models, etc
*
* @param objs Map of models
* @return maps of models with various updates
*/
public Map<String, Object> updateAllModels(Map<String, Object> objs) {
// Index all CodegenModels by model name.
Map<String, CodegenModel> allModels = new HashMap<String, CodegenModel>();
for (Entry<String, Object> entry : objs.entrySet()) {
String modelName = toModelName(entry.getKey());
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
allModels.put(modelName, cm);
if (supportsInheritance) {
// Index all CodegenModels by model name.
Map<String, CodegenModel> allModels = new HashMap<String, CodegenModel>();
for (Entry<String, Object> entry : objs.entrySet()) {
String modelName = toModelName(entry.getKey());
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
allModels.put(modelName, cm);
}
}
}
// Fix up all parent and interface CodegenModel references.
for (CodegenModel cm : allModels.values()) {
if (cm.getParent() != null) {
cm.setParentModel(allModels.get(cm.getParent()));
// Fix up all parent and interface CodegenModel references.
for (CodegenModel cm : allModels.values()) {
if (cm.getParent() != null) {
cm.setParentModel(allModels.get(cm.getParent()));
}
if (cm.getInterfaces() != null && !cm.getInterfaces().isEmpty()) {
cm.setInterfaceModels(new ArrayList<CodegenModel>(cm.getInterfaces().size()));
for (String intf : cm.getInterfaces()) {
CodegenModel intfModel = allModels.get(intf);
if (intfModel != null) {
cm.getInterfaceModels().add(intfModel);
}
}
}
}
if (cm.getInterfaces() != null && !cm.getInterfaces().isEmpty()) {
cm.setInterfaceModels(new ArrayList<CodegenModel>(cm.getInterfaces().size()));
for (String intf : cm.getInterfaces()) {
CodegenModel intfModel = allModels.get(intf);
if (intfModel != null) {
cm.getInterfaceModels().add(intfModel);
// Let parent know about all its children
for (String name : allModels.keySet()) {
CodegenModel cm = allModels.get(name);
CodegenModel parent = allModels.get(cm.getParent());
// if a discriminator exists on the parent, don't add this child to the inheritance hierarchy
// TODO Determine what to do if the parent discriminator name == the grandparent discriminator name
while (parent != null) {
if (parent.getChildren() == null) {
parent.setChildren(new ArrayList<CodegenModel>());
}
parent.getChildren().add(cm);
parent.hasChildren = true;
if (parent.getDiscriminator() == null) {
parent = allModels.get(parent.getParent());
} else {
parent = null;
}
}
}
}
// Let parent know about all its children
for (String name : allModels.keySet()) {
CodegenModel cm = allModels.get(name);
CodegenModel parent = allModels.get(cm.getParent());
// if a discriminator exists on the parent, don't add this child to the inheritance hierarchy
// TODO Determine what to do if the parent discriminator name == the grandparent discriminator name
while (parent != null) {
if (parent.getChildren() == null) {
parent.setChildren(new ArrayList<CodegenModel>());
}
parent.getChildren().add(cm);
parent.hasChildren = true;
if (parent.getDiscriminator() == null) {
parent = allModels.get(parent.getParent());
} else {
parent = null;
}
}
}
// loop through properties of each model to detect self-reference
for (Map.Entry<String, Object> entry : objs.entrySet()) {
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
for (CodegenProperty cp : cm.allVars) {
// detect self import
if (cp.dataType.equalsIgnoreCase(cm.classname) ||
(cp.isContainer && cp.items.dataType.equalsIgnoreCase(cm.classname))) {
cm.imports.remove(cm.classname); // remove self import
cp.isSelfReference = true;
}
}
}
}
return objs;
}
@@ -337,7 +303,7 @@ public class DefaultCodegen implements CodegenConfig {
enumVar.put("isString", isDataTypeString(cm.dataType));
enumVars.add(enumVar);
}
// if "x-enum-varnames" or "x-enum-descriptions" defined, update varnames
// if "x-enum-varnames" defined, update varnames
updateEnumVarsWithExtensions(enumVars, cm.getVendorExtensions());
cm.allowableValues.put("enumVars", enumVars);
}
@@ -348,30 +314,6 @@ public class DefaultCodegen implements CodegenConfig {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.allVars) {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.requiredVars) {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.optionalVars) {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.parentVars) {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.readOnlyVars) {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.readWriteVars) {
updateCodegenPropertyEnum(var);
}
}
return objs;
}
@@ -561,12 +503,6 @@ public class DefaultCodegen implements CodegenConfig {
.replace("\"", "\\\""));
}
// override with any special encoding and escaping logic
@SuppressWarnings("static-method")
public String encodePath(String input) {
return escapeText(input);
}
/**
* override with any special text escaping logic to handle unsafe
* characters so as to avoid code injection
@@ -1381,53 +1317,64 @@ public class DefaultCodegen implements CodegenConfig {
ComposedSchema cs = (ComposedSchema) schema;
List<Schema> schemas = ModelUtils.getInterfaces(cs);
if (cs.getAllOf() != null) {
List<String> names = new ArrayList<>();
for (Schema s : schemas) {
names.add(getSingleSchemaType(s));
for (Schema s : cs.getAllOf()) {
if (s != null) {
//schema = s;
}
//LOGGER.info("ALL OF SCHEMA: {}", s);
}
if (names.size() == 0) {
LOGGER.error("allOf has no member defined: {}. Default to ERROR_ALLOF_SCHEMA", cs);
return "ERROR_ALLOF_SCHEMA";
} else if (names.size() == 1) {
return names.get(0);
} else {
LOGGER.warn("allOf with multiple schemas defined. Using only the first one: {}. To fully utilize allOf, please use $ref instead of inline schema definition", names.get(0));
return names.get(0);
}
LOGGER.info("Composed schema not yet supported: {}", cs);
// get the model (allOf)
return getAlias("UNKNOWN_COMPOSED_SCHMEA");
} else if (cs.getAnyOf() != null) { // anyOf
List<String> names = new ArrayList<>();
List<String> names = new ArrayList<String>();
for (Schema s : schemas) {
names.add(getSingleSchemaType(s));
if (StringUtils.isNotBlank(s.get$ref())) { // reference to another definition/schema
String schemaName = ModelUtils.getSimpleRef(s.get$ref());
if (StringUtils.isNotEmpty(schemaName)) {
names.add(getAlias(schemaName));
} else {
LOGGER.warn("Error obtaining the datatype from ref:" + schema.get$ref() + ". Default to 'object'");
return "object";
}
} else {
// primitive type or model
names.add(getAlias(getPrimitiveType(s)));
}
return "anyOf<" + String.join(",", names) + ">";
}
return "anyOf<" + String.join(",", names) + ">";
} else if (cs.getOneOf() != null) { // oneOf
List<String> names = new ArrayList<>();
List<String> names = new ArrayList<String>();
for (Schema s : schemas) {
names.add(getSingleSchemaType(s));
if (StringUtils.isNotBlank(s.get$ref())) { // reference to another definition/schema
String schemaName = ModelUtils.getSimpleRef(s.get$ref());
if (StringUtils.isNotEmpty(schemaName)) {
names.add(getAlias(schemaName));
} else {
LOGGER.warn("Error obtaining the datatype from ref:" + schema.get$ref() + ". Default to 'object'");
return "object";
}
} else {
// primitive type or model
names.add(getAlias(getPrimitiveType(s)));
}
return "oneOf<" + String.join(",", names) + ">";
}
return "oneOf<" + String.join(",", names) + ">";
}
}
return getSingleSchemaType(schema);
}
private String getSingleSchemaType(Schema schema) {
Schema unaliasSchema = ModelUtils.unaliasSchema(globalSchemas, schema);
if (StringUtils.isNotBlank(unaliasSchema.get$ref())) { // reference to another definition/schema
if (StringUtils.isNotBlank(schema.get$ref())) { // reference to another definition/schema
// get the schema/model name from $ref
String schemaName = ModelUtils.getSimpleRef(unaliasSchema.get$ref());
String schemaName = ModelUtils.getSimpleRef(schema.get$ref());
if (StringUtils.isNotEmpty(schemaName)) {
return getAlias(schemaName);
} else {
LOGGER.warn("Error obtaining the datatype from ref:" + unaliasSchema.get$ref() + ". Default to 'object'");
LOGGER.warn("Error obtaining the datatype from ref:" + schema.get$ref() + ". Default to 'object'");
return "object";
}
} else { // primitive type or model
return getAlias(getPrimitiveType(unaliasSchema));
return getAlias(getPrimitiveType(schema));
}
}
@@ -1504,15 +1451,14 @@ public class DefaultCodegen implements CodegenConfig {
}
/**
* Capitalize the string. Please use org.openapitools.codegen.utils.StringUtils.camelize instead as this method will be deprecated.
* Capitalize the string
*
* @param name string to be capitalized
* @return capitalized string
* @deprecated
*/
@SuppressWarnings("static-method")
public String initialCaps(String name) {
return camelize(name);
return StringUtils.capitalize(name);
}
/**
@@ -1608,7 +1554,7 @@ public class DefaultCodegen implements CodegenConfig {
* @return capitalized model name
*/
public String toModelName(final String name) {
return initialCaps(modelNamePrefix + "_" + name + "_" + modelNameSuffix);
return initialCaps(modelNamePrefix + name + modelNameSuffix);
}
/**
@@ -1672,7 +1618,6 @@ public class DefaultCodegen implements CodegenConfig {
// parent model
final String parentName = ModelUtils.getParentName(composed, allDefinitions);
final List<String> allParents = ModelUtils.getAllParentsName(composed, allDefinitions);
final Schema parent = StringUtils.isBlank(parentName) || allDefinitions == null ? null : allDefinitions.get(parentName);
final boolean hasParent = StringUtils.isNotBlank(parentName);
@@ -1721,16 +1666,19 @@ public class DefaultCodegen implements CodegenConfig {
m.interfaces.add(modelName);
addImport(m, modelName);
if (allDefinitions != null && refSchema != null) {
if (allParents.contains(modelName) && supportsMultipleInheritance) {
// multiple inheritance
addProperties(allProperties, allRequired, refSchema, allDefinitions);
} else if (parentName != null && parentName.equals(modelName) && supportsInheritance) {
// single inheritance
addProperties(allProperties, allRequired, refSchema, allDefinitions);
} else {
// composition
if (hasParent || supportsInheritance) {
if (supportsInheritance || parentName.equals(modelName)) {
// inheritance
addProperties(allProperties, allRequired, refSchema, allDefinitions);
} else {
// composition
//LOGGER.debug("Parent {} not set to model name {}", parentName, modelName);
addProperties(properties, required, refSchema, allDefinitions);
}
} else if (!supportsMixins && !supportsInheritance) {
addProperties(properties, required, refSchema, allDefinitions);
}
}
if (composed.getAnyOf() != null) {
@@ -1748,16 +1696,13 @@ public class DefaultCodegen implements CodegenConfig {
if (parent != null) {
m.parentSchema = parentName;
m.parent = toModelName(parentName);
if (supportsMultipleInheritance) {
m.allParents = new ArrayList<String>();
for (String pname : allParents) {
String pModelName = toModelName(pname);
m.allParents.add(pModelName);
addImport(m, pModelName);
addImport(m, m.parent);
if (allDefinitions != null && !allDefinitions.isEmpty()) {
if (hasParent || supportsInheritance) {
addProperties(allProperties, allRequired, parent, allDefinitions);
} else {
addProperties(properties, required, parent, allDefinitions);
}
} else { // single inheritance
addImport(m, m.parent);
}
}
@@ -1768,14 +1713,15 @@ public class DefaultCodegen implements CodegenConfig {
// component is the child schema
addProperties(properties, required, component, allDefinitions);
// includes child's properties (all, required) in allProperties, allRequired
addProperties(allProperties, allRequired, component, allDefinitions);
if (hasParent || supportsInheritance) {
addProperties(allProperties, allRequired, component, allDefinitions);
}
}
break; // at most one child only
break; // at most one schema not using $ref
}
}
addVars(m, unaliasPropertySchema(allDefinitions, properties), required, unaliasPropertySchema(allDefinitions, allProperties), allRequired);
addVars(m, unaliasPropertySchema(allDefinitions, properties), required, allProperties, allRequired);
// end of code block for composed schema
} else {
@@ -1799,8 +1745,7 @@ public class DefaultCodegen implements CodegenConfig {
m.isString = Boolean.TRUE;
}
// passing null to allProperties and allRequired as there's no parent
addVars(m, unaliasPropertySchema(allDefinitions, schema.getProperties()), schema.getRequired(), null, null);
addVars(m, unaliasPropertySchema(allDefinitions, schema.getProperties()), schema.getRequired());
}
// remove duplicated properties
@@ -1822,7 +1767,7 @@ public class DefaultCodegen implements CodegenConfig {
return null;
}
CodegenDiscriminator discriminator = new CodegenDiscriminator();
discriminator.setPropertyName(toVarName(schema.getDiscriminator().getPropertyName()));
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()) {
@@ -1840,7 +1785,7 @@ public class DefaultCodegen implements CodegenConfig {
.map(s -> ModelUtils.getSimpleRef(s.get$ref()))
.collect(Collectors.toSet());
if (parentSchemas.contains(schemaName)) {
discriminator.getMappedModels().add(new MappedModel(childName, toModelName(childName)));
discriminator.getMappedModels().add(new MappedModel(childName, childName));
}
}
});
@@ -1852,36 +1797,20 @@ public class DefaultCodegen implements CodegenConfig {
addParentContainer(codegenModel, codegenModel.name, schema);
}
/**
* Add schema's properties to "properties" and "required" list
*
* @param properties all properties
* @param required required property only
* @param schema schema in which the properties will be added to the lists
* @param allSchemas all schemas
*/
protected void addProperties(Map<String, Schema> properties, List<String> required, Schema
schema, Map<String, Schema> allSchemas) {
if (schema instanceof ComposedSchema) {
ComposedSchema composedSchema = (ComposedSchema) schema;
if (composedSchema.getAllOf() == null) {
return;
}
for (Schema component : composedSchema.getAllOf()) {
addProperties(properties, required, component, allSchemas);
}
if (composedSchema.getOneOf() != null) {
throw new RuntimeException("Please report the issue: Cannot process oneOf (Composed Scheme) in addProperties: " + schema);
}
if (composedSchema.getAnyOf() != null) {
throw new RuntimeException("Please report the issue: Cannot process anyOf (Composed Schema) in addProperties: " + schema);
}
return;
}
Schema unaliasSchema = ModelUtils.unaliasSchema(globalSchemas, schema);
if (StringUtils.isNotBlank(schema.get$ref())) {
Schema interfaceSchema = allSchemas.get(ModelUtils.getSimpleRef(schema.get$ref()));
addProperties(properties, required, interfaceSchema, allSchemas);
@@ -2118,8 +2047,6 @@ public class DefaultCodegen implements CodegenConfig {
allowableValues.put("values", _enum);
property.allowableValues = allowableValues;
}
} else if (ModelUtils.isFreeFormObject(p)){
property.isFreeFormObject = true;
}
property.dataType = getTypeDeclaration(p);
@@ -2333,8 +2260,6 @@ public class DefaultCodegen implements CodegenConfig {
if (property.defaultValue != null) {
property.defaultValue = property.defaultValue.replace(", " + property.items.baseType, ", " + toEnumName(property.items));
}
updateCodegenPropertyEnum(property);
}
}
@@ -2913,7 +2838,7 @@ public class DefaultCodegen implements CodegenConfig {
}
codegenParameter.jsonSchema = Json.pretty(parameter);
if (GeneratorProperties.getProperty("debugParser") != null) {
if (System.getProperty("debugParser") != null) {
LOGGER.info("working on Parameter " + parameter.getName());
LOGGER.info("JSON schema: " + codegenParameter.jsonSchema);
}
@@ -2923,7 +2848,7 @@ public class DefaultCodegen implements CodegenConfig {
}
if (parameter.getSchema() != null) {
Schema parameterSchema = ModelUtils.unaliasSchema(globalSchemas, parameter.getSchema());
Schema parameterSchema = parameter.getSchema();
if (parameterSchema == null) {
LOGGER.warn("warning! Schema not found for parameter \"" + parameter.getName() + "\", using String");
parameterSchema = new StringSchema().description("//TODO automatically added by openapi-generator due to missing type definition.");
@@ -2997,6 +2922,7 @@ public class DefaultCodegen implements CodegenConfig {
// set boolean flag (e.g. isString)
setParameterBooleanFlagWithCodegenProperty(codegenParameter, codegenProperty);
String parameterDataType = this.getParameterDataType(parameter, parameterSchema);
if (parameterDataType != null) {
codegenParameter.dataType = parameterDataType;
@@ -3499,69 +3425,49 @@ public class DefaultCodegen implements CodegenConfig {
return properties;
}
private void addVars(CodegenModel model, Map<String, Schema> properties, List<String> required) {
addVars(model, properties, required, null, null);
}
private void addVars(CodegenModel m, Map<String, Schema> properties, List<String> required,
Map<String, Schema> allProperties, List<String> allRequired) {
m.hasRequired = false;
if (properties != null && !properties.isEmpty()) {
m.hasVars = true;
m.hasEnums = false; // TODO need to fix as its false in both cases
m.hasEnums = false;
Set<String> mandatory = required == null ? Collections.<String>emptySet()
: new TreeSet<String>(required);
// update "vars" without parent's properties (all, required)
addVars(m, m.vars, properties, mandatory);
m.allMandatory = m.mandatory = mandatory;
} else {
m.emptyVars = true;
m.hasVars = false;
m.hasEnums = false; // TODO need to fix as its false in both cases
m.hasEnums = false;
}
if (allProperties != null) {
Set<String> allMandatory = allRequired == null ? Collections.<String>emptySet()
: new TreeSet<String>(allRequired);
// update "vars" with parent's properties (all, required)
addVars(m, m.allVars, allProperties, allMandatory);
m.allMandatory = allMandatory;
} else { // without parent, allVars and vars are the same
m.allVars = m.vars;
m.allMandatory = m.mandatory;
}
// loop through list to update property name with toVarName
Set<String> renamedMandatory = new TreeSet<String>();
Iterator<String> mandatoryIterator = m.mandatory.iterator();
while (mandatoryIterator.hasNext()) {
renamedMandatory.add(toVarName(mandatoryIterator.next()));
}
m.mandatory = renamedMandatory;
Set<String> renamedAllMandatory = new TreeSet<String>();
Iterator<String> allMandatoryIterator = m.allMandatory.iterator();
while (allMandatoryIterator.hasNext()) {
renamedAllMandatory.add(toVarName(allMandatoryIterator.next()));
}
m.allMandatory = renamedAllMandatory;
}
/**
* Add variables (properties) to codegen model (list of properties, various flags, etc)
*
* @param m Codegen model
* @param vars list of codegen properties (e.g. vars, allVars) to be updated with the new properties
* @param properties a map of properties (schema)
* @param mandatory a set of required properties' name
*/
private void addVars(CodegenModel m, List<CodegenProperty> vars, Map<String, Schema> properties, Set<String> mandatory) {
for (Map.Entry<String, Schema> entry : properties.entrySet()) {
private void addVars(CodegenModel
m, List<CodegenProperty> vars, Map<String, Schema> properties, Set<String> mandatory) {
// convert set to list so that we can access the next entry in the loop
List<Map.Entry<String, Schema>> propertyList = new ArrayList<Map.Entry<String, Schema>>(properties.entrySet());
final int totalCount = propertyList.size();
for (int i = 0; i < totalCount; i++) {
Map.Entry<String, Schema> entry = propertyList.get(i);
final String key = entry.getKey();
final Schema prop = entry.getValue();
if (prop == null) {
LOGGER.warn("Please report the issue. There shouldn't be null property for " + key);
LOGGER.warn("null property for " + key);
} else {
final CodegenProperty cp = fromProperty(key, prop);
cp.required = mandatory.contains(key);
@@ -3578,7 +3484,14 @@ public class DefaultCodegen implements CodegenConfig {
m.hasOnlyReadOnly = false;
}
// TODO revise the logic to include map
if (i + 1 != totalCount) {
cp.hasMore = true;
// check the next entry to see if it's read only
if (!Boolean.TRUE.equals(propertyList.get(i + 1).getValue().getReadOnly())) {
cp.hasMoreNonReadOnly = true; // next entry is not ready only
}
}
if (cp.isContainer) {
addImport(m, typeMapping.get("array"));
}
@@ -3602,7 +3515,7 @@ public class DefaultCodegen implements CodegenConfig {
if (Boolean.TRUE.equals(cp.isReadOnly)) {
m.readOnlyVars.add(cp);
} else { // else add to readWriteVars (list of properties)
// duplicated properties will be removed by removeAllDuplicatedProperty later
// FIXME: readWriteVars can contain duplicated properties. Debug/breakpoint here while running C# generator (Dog and Cat models)
m.readWriteVars.add(cp);
}
}
@@ -4034,9 +3947,6 @@ public class DefaultCodegen implements CodegenConfig {
if (Boolean.TRUE.equals(property.isFile)) {
parameter.isFile = true;
}
if (Boolean.TRUE.equals(property.isModel)) {
parameter.isModel = true;
}
}
@@ -4084,9 +3994,8 @@ public class DefaultCodegen implements CodegenConfig {
enumVar.put("isString", isDataTypeString(dataType));
enumVars.add(enumVar);
}
// if "x-enum-varnames" or "x-enum-descriptions" defined, update varnames
Map<String, Object> extensions = var.mostInnerItems != null ? var.mostInnerItems.getVendorExtensions() : var.getVendorExtensions();
updateEnumVarsWithExtensions(enumVars, extensions);
// if "x-enum-varnames" defined, update varnames
updateEnumVarsWithExtensions(enumVars, var.getVendorExtensions());
allowableValues.put("enumVars", enumVars);
// handle default value for enum, e.g. available => StatusEnum.AVAILABLE
@@ -4104,19 +4013,13 @@ public class DefaultCodegen implements CodegenConfig {
}
}
private void updateEnumVarsWithExtensions(List<Map<String, Object>> enumVars, Map<String, Object> vendorExtensions) {
if (vendorExtensions != null) {
updateEnumVarsWithExtensions(enumVars, vendorExtensions, "x-enum-varnames", "name");
updateEnumVarsWithExtensions(enumVars, vendorExtensions, "x-enum-descriptions", "enumDescription");
}
}
private void updateEnumVarsWithExtensions(List<Map<String, Object>> enumVars, Map<String, Object> vendorExtensions, String extensionKey, String key) {
if (vendorExtensions.containsKey(extensionKey)) {
List<String> values = (List<String>) vendorExtensions.get(extensionKey);
int size = Math.min(enumVars.size(), values.size());
private void updateEnumVarsWithExtensions
(List<Map<String, Object>> enumVars, Map<String, Object> vendorExtensions) {
if (vendorExtensions != null && vendorExtensions.containsKey("x-enum-varnames")) {
List<String> alias = (List<String>) vendorExtensions.get("x-enum-varnames");
int size = Math.min(enumVars.size(), alias.size());
for (int i = 0; i < size; i++) {
enumVars.get(i).put(key, values.get(i));
enumVars.get(i).put("name", alias.get(i));
}
}
}
@@ -4202,9 +4105,6 @@ public class DefaultCodegen implements CodegenConfig {
protected Parameter getParameterFromRef(String ref, OpenAPI openAPI) {
String parameterName = ref.substring(ref.lastIndexOf('/') + 1);
Map<String, Parameter> parameterMap = openAPI.getComponents().getParameters();
if (parameterMap == null ) { // can't find the ref
throw new RuntimeException(ref + " not defined in the spec.");
}
return parameterMap.get(parameterName);
}
@@ -4404,7 +4304,7 @@ public class DefaultCodegen implements CodegenConfig {
body, Map<String, Schema> schemas, Set<String> imports) {
List<CodegenParameter> parameters = new ArrayList<CodegenParameter>();
LOGGER.debug("debugging fromRequestBodyToFormParameters= " + body);
Schema schema = ModelUtils.getSchemaFromRequestBody(body);
Schema schema = ModelUtils.unaliasSchema(globalSchemas, ModelUtils.getSchemaFromRequestBody(body));
if (StringUtils.isNotBlank(schema.get$ref())) {
schema = schemas.get(ModelUtils.getSimpleRef(schema.get$ref()));
}
@@ -4419,7 +4319,7 @@ public class DefaultCodegen implements CodegenConfig {
// array of schema
if (ModelUtils.isArraySchema(s)) {
final ArraySchema arraySchema = (ArraySchema) s;
Schema inner = arraySchema.getItems();
Schema inner = ModelUtils.unaliasSchema(globalSchemas, (arraySchema.getItems()));
if (inner == null) {
LOGGER.warn("warning! No inner type supplied for array parameter \"" + s.getName() + "\", using String");
inner = new StringSchema().description("//TODO automatically added by openapi-generator due to missing iner type definition in the spec");
@@ -4571,14 +4471,14 @@ public class DefaultCodegen implements CodegenConfig {
String name = null;
LOGGER.debug("Request body = " + body);
Schema schema = ModelUtils.getSchemaFromRequestBody(body);
Schema schema = ModelUtils.unaliasSchema(globalSchemas, ModelUtils.getSchemaFromRequestBody(body));
if (StringUtils.isNotBlank(schema.get$ref())) {
name = ModelUtils.getSimpleRef(schema.get$ref());
schema = schemas.get(name);
}
if (ModelUtils.isMapSchema(schema)) {
Schema inner = ModelUtils.getAdditionalProperties(schema);
Schema inner = ModelUtils.unaliasSchema(globalSchemas, ModelUtils.getAdditionalProperties(schema));
if (inner == null) {
inner = new StringSchema().description("//TODO automatically added by openapi-generator");
schema.setAdditionalProperties(inner);
@@ -4606,7 +4506,7 @@ public class DefaultCodegen implements CodegenConfig {
setParameterNullable(codegenParameter, codegenProperty);
} else if (ModelUtils.isArraySchema(schema)) {
final ArraySchema arraySchema = (ArraySchema) schema;
Schema inner = arraySchema.getItems();
Schema inner = ModelUtils.unaliasSchema(globalSchemas, arraySchema.getItems());
if (inner == null) {
inner = new StringSchema().description("//TODO automatically added by openapi-generator");
arraySchema.setItems(inner);
@@ -4651,25 +4551,6 @@ public class DefaultCodegen implements CodegenConfig {
codegenProperty = codegenProperty.items;
}
} else if (ModelUtils.isFreeFormObject(schema)) {
// HTTP request body is free form object
CodegenProperty codegenProperty = fromProperty("FREE_FORM_REQUEST_BODY", schema);
if (codegenProperty != null) {
if (StringUtils.isEmpty(bodyParameterName)) {
codegenParameter.baseName = "body"; // default to body
} else {
codegenParameter.baseName = bodyParameterName;
}
codegenParameter.isPrimitiveType = true;
codegenParameter.baseType = codegenProperty.baseType;
codegenParameter.dataType = codegenProperty.dataType;
codegenParameter.description = codegenProperty.description;
codegenParameter.paramName = toParamName(codegenParameter.baseName);
}
setParameterBooleanFlagWithCodegenProperty(codegenParameter, codegenProperty);
// set nullable
setParameterNullable(codegenParameter, codegenProperty);
} else if (ModelUtils.isObjectSchema(schema) || ModelUtils.isComposedSchema(schema)) {
CodegenModel codegenModel = null;
if (StringUtils.isNotBlank(name)) {

View File

@@ -37,7 +37,6 @@ import io.swagger.v3.oas.models.tags.Tag;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.config.GeneratorProperties;
import org.openapitools.codegen.ignore.CodegenIgnoreProcessor;
import org.openapitools.codegen.utils.ImplementationVersion;
import org.openapitools.codegen.utils.ModelUtils;
@@ -130,9 +129,9 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
private void configureGeneratorProperties() {
// allows generating only models by specifying a CSV of models to generate, or empty for all
// NOTE: Boolean.TRUE is required below rather than `true` because of JVM boxing constraints and type inference.
generateApis = GeneratorProperties.getProperty(CodegenConstants.APIS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.APIS, null);
generateModels = GeneratorProperties.getProperty(CodegenConstants.MODELS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODELS, null);
generateSupportingFiles = GeneratorProperties.getProperty(CodegenConstants.SUPPORTING_FILES) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.SUPPORTING_FILES, null);
generateApis = System.getProperty(CodegenConstants.APIS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.APIS, null);
generateModels = System.getProperty(CodegenConstants.MODELS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODELS, null);
generateSupportingFiles = System.getProperty(CodegenConstants.SUPPORTING_FILES) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.SUPPORTING_FILES, null);
if (generateApis == null && generateModels == null && generateSupportingFiles == null) {
// no specifics are set, generate everything
@@ -150,10 +149,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
// model/api tests and documentation options rely on parent generate options (api or model) and no other options.
// They default to true in all scenarios and can only be marked false explicitly
generateModelTests = GeneratorProperties.getProperty(CodegenConstants.MODEL_TESTS) != null ? Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.MODEL_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_TESTS, true);
generateModelDocumentation = GeneratorProperties.getProperty(CodegenConstants.MODEL_DOCS) != null ? Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.MODEL_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_DOCS, true);
generateApiTests = GeneratorProperties.getProperty(CodegenConstants.API_TESTS) != null ? Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.API_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_TESTS, true);
generateApiDocumentation = GeneratorProperties.getProperty(CodegenConstants.API_DOCS) != null ? Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.API_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_DOCS, true);
generateModelTests = System.getProperty(CodegenConstants.MODEL_TESTS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.MODEL_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_TESTS, true);
generateModelDocumentation = System.getProperty(CodegenConstants.MODEL_DOCS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.MODEL_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_DOCS, true);
generateApiTests = System.getProperty(CodegenConstants.API_TESTS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.API_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_TESTS, true);
generateApiDocumentation = System.getProperty(CodegenConstants.API_DOCS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.API_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_DOCS, true);
// Additional properties added for tests to exclude references in project related files
@@ -170,9 +169,9 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
config.additionalProperties().put(CodegenConstants.EXCLUDE_TESTS, true);
}
if (GeneratorProperties.getProperty("debugOpenAPI") != null) {
if (System.getProperty("debugOpenAPI") != null) {
Json.prettyPrint(openAPI);
} else if (GeneratorProperties.getProperty("debugSwagger") != null) {
} 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'.");
@@ -331,7 +330,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return;
}
String modelNames = GeneratorProperties.getProperty("models");
String modelNames = System.getProperty("models");
Set<String> modelsToGenerate = null;
if (modelNames != null && !modelNames.isEmpty()) {
modelsToGenerate = new HashSet<String>(Arrays.asList(modelNames.split(",")));
@@ -404,8 +403,8 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
} */
});
Boolean skipFormModel = GeneratorProperties.getProperty(CodegenConstants.SKIP_FORM_MODEL) != null ?
Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.SKIP_FORM_MODEL)) :
Boolean skipFormModel = System.getProperty(CodegenConstants.SKIP_FORM_MODEL) != null ?
Boolean.valueOf(System.getProperty(CodegenConstants.SKIP_FORM_MODEL)) :
getGeneratorPropertyDefaultSwitch(CodegenConstants.SKIP_FORM_MODEL, false);
// process models only
@@ -430,17 +429,18 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
Schema schema = schemas.get(name);
if (ModelUtils.isFreeFormObject(schema)) { // check to see if it'a a free-form object
LOGGER.info("Model " + name + " not generated since it's a free-form object");
continue;
} else if (ModelUtils.isMapSchema(schema)) { // check to see if it's a "map" model
if (!ModelUtils.isGenerateAliasAsModel() && (schema.getProperties() == null || schema.getProperties().isEmpty())) {
// check to see if it's a "map" model
if (ModelUtils.isMapSchema(schema)) {
if (schema.getProperties() == null || schema.getProperties().isEmpty()) {
// schema without property, i.e. alias to map
LOGGER.info("Model " + name + " not generated since it's an alias to map (without property)");
continue;
}
} else if (ModelUtils.isArraySchema(schema)) { // check to see if it's an "array" model
if (!ModelUtils.isGenerateAliasAsModel() && (schema.getProperties() == null || schema.getProperties().isEmpty())) {
}
// check to see if it's an "array" model
if (ModelUtils.isArraySchema(schema)) {
if (schema.getProperties() == null || schema.getProperties().isEmpty()) {
// schema without property, i.e. alias to array
LOGGER.info("Model " + name + " not generated since it's an alias to array (without property)");
continue;
@@ -458,9 +458,6 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
}
// loop through all models to update children models, isSelfReference, isCircularReference, etc
allProcessedModels = config.updateAllModels(allProcessedModels);
// post process all processed models
allProcessedModels = config.postProcessAllModels(allProcessedModels);
@@ -474,7 +471,6 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
continue;
}
// TODO revise below as we've already performed unaliasing so that the isAlias check may be removed
Map<String, Object> modelTemplate = (Map<String, Object>) ((List<Object>) models.get("models")).get(0);
// Special handling of aliases only applies to Java
if (modelTemplate != null && modelTemplate.containsKey("model")) {
@@ -501,7 +497,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
throw new RuntimeException("Could not generate model '" + modelName + "'", e);
}
}
if (GeneratorProperties.getProperty("debugModels") != null) {
if (System.getProperty("debugModels") != null) {
LOGGER.info("############ Model info ############");
Json.prettyPrint(allModels);
}
@@ -514,7 +510,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
Map<String, List<CodegenOperation>> paths = processPaths(this.openAPI.getPaths());
Set<String> apisToGenerate = null;
String apiNames = GeneratorProperties.getProperty("apis");
String apiNames = System.getProperty("apis");
if (apiNames != null && !apiNames.isEmpty()) {
apisToGenerate = new HashSet<String>(Arrays.asList(apiNames.split(",")));
}
@@ -537,9 +533,9 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
});
Map<String, Object> operation = processOperations(config, tag, ops, allModels);
URL url = URLPathUtils.getServerURL(openAPI);
operation.put("basePath", basePath);
operation.put("basePathWithoutHost", config.encodePath(url.getPath()).replaceAll("/$", ""));
operation.put("basePathWithoutHost", basePathWithoutHost);
operation.put("contextPath", contextPath);
operation.put("baseName", tag);
operation.put("apiPackage", config.apiPackage());
@@ -568,7 +564,8 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
@SuppressWarnings("unchecked")
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
for (CodegenOperation op : operations) {
if (isGroupParameters && !op.vendorExtensions.containsKey("x-group-parameters")) {
op.httpMethod = op.httpMethod.toLowerCase(Locale.ROOT);
if (!op.vendorExtensions.containsKey("x-group-parameters")) {
op.vendorExtensions.put("x-group-parameters", Boolean.TRUE);
}
}
@@ -654,7 +651,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
throw new RuntimeException("Could not generate api file for '" + tag + "'", e);
}
}
if (GeneratorProperties.getProperty("debugOperations") != null) {
if (System.getProperty("debugOperations") != null) {
LOGGER.info("############ Operation info ############");
Json.prettyPrint(allOperations);
}
@@ -666,7 +663,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return;
}
Set<String> supportingFilesToGenerate = null;
String supportingFiles = GeneratorProperties.getProperty(CodegenConstants.SUPPORTING_FILES);
String supportingFiles = System.getProperty(CodegenConstants.SUPPORTING_FILES);
if (supportingFiles != null && !supportingFiles.isEmpty()) {
supportingFilesToGenerate = new HashSet<String>(Arrays.asList(supportingFiles.split(",")));
}
@@ -839,11 +836,6 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
if (authMethods != null && !authMethods.isEmpty()) {
bundle.put("authMethods", authMethods);
bundle.put("hasAuthMethods", true);
if (hasOAuthMethods(authMethods)) {
bundle.put("hasOAuthMethods", true);
bundle.put("oauthMethods", getOAuthMethods(authMethods));
}
}
List<CodegenServer> servers = config.fromServers(openAPI.getServers());
@@ -864,7 +856,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
config.postProcessSupportingFileData(bundle);
if (GeneratorProperties.getProperty("debugSupportingFiles") != null) {
if (System.getProperty("debugSupportingFiles") != null) {
LOGGER.info("############ Supporting file info ############");
Json.prettyPrint(bundle);
}
@@ -882,13 +874,13 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
throw new RuntimeException("missing config!");
}
configureGeneratorProperties();
configureOpenAPIInfo();
// resolve inline models
InlineModelResolver inlineModelResolver = new InlineModelResolver();
inlineModelResolver.flatten(openAPI);
configureGeneratorProperties();
configureOpenAPIInfo();
List<File> files = new ArrayList<File>();
// models
List<String> filteredSchemas = ModelUtils.getSchemasUsedOnlyInFormParam(openAPI);
@@ -902,10 +894,6 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
Map<String, Object> bundle = buildSupportFileBundle(allOperations, allModels);
generateSupportingFiles(files, bundle);
config.processOpenAPI(openAPI);
// reset GeneratorProperties, so that the running thread can be reused for another generator-run
GeneratorProperties.reset();
return files;
}
@@ -955,7 +943,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return;
}
if (GeneratorProperties.getProperty("debugOperations") != null) {
if (System.getProperty("debugOperations") != null) {
LOGGER.info("processOperation: resourcePath= " + resourcePath + "\t;" + httpMethod + " " + operation + "\n");
}
@@ -1141,8 +1129,6 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
mo.put("importPath", config.toModelImport(cm.classname));
models.add(mo);
cm.removeSelfReferenceImport();
allImports.addAll(cm.imports);
}
objs.put("models", models);
@@ -1187,26 +1173,4 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
return authMethods;
}
private boolean hasOAuthMethods(List<CodegenSecurity> authMethods) {
for (CodegenSecurity cs : authMethods) {
if (cs.isOAuth) {
return true;
}
}
return false;
}
private List<CodegenSecurity> getOAuthMethods(List<CodegenSecurity> authMethods) {
List<CodegenSecurity> oauthMethods = new ArrayList<>();
for (CodegenSecurity cs : authMethods) {
if (cs.isOAuth) {
oauthMethods.add(cs);
}
}
return oauthMethods;
}
}

View File

@@ -17,16 +17,18 @@
package org.openapitools.codegen;
import io.swagger.v3.oas.models.*;
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 io.swagger.v3.oas.models.responses.ApiResponses;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,278 +42,275 @@ import io.swagger.v3.oas.models.media.XML;
public class InlineModelResolver {
private OpenAPI openapi;
private Map<String, Schema> addedModels = new HashMap<String, Schema>();
private Map<String, String> generatedSignature = new HashMap<String, String>();
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>();
void flatten(OpenAPI openapi) {
public void flatten(OpenAPI openapi) {
this.openapi = openapi;
if (openapi.getComponents() == null) {
openapi.setComponents(new Components());
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);
flattenPaths(openapi);
flattenComponents(openapi);
}
// 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);
/**
* Flatten inline models in Paths
*
* @param openAPI target spec
*/
private void flattenPaths(OpenAPI openAPI) {
Paths paths = openAPI.getPaths();
if (paths == null) {
return;
}
// get "consumes", e.g. application/xml, application/json
Set<String> consumes;
if (requestBody == null || requestBody.getContent() == null || requestBody.getContent().isEmpty()) {
consumes = new HashSet<>();
consumes.add("application/json"); // default to application/json
LOGGER.info("Default to application/json for inline body schema");
} else {
consumes = requestBody.getContent().keySet();
}
for (String pathname : paths.keySet()) {
PathItem path = paths.get(pathname);
for (Operation operation : path.readOperations()) {
flattenRequestBody(openAPI, pathname, operation);
flattenParameters(openAPI, pathname, operation);
flattenResponses(openAPI, pathname, operation);
}
}
}
for (String consume : consumes) {
content.addMediaType(consume, mt);
}
/**
* Flatten inline models in RequestBody
*
* @param openAPI target spec
* @param pathname target pathname
* @param operation target operation
*/
private void flattenRequestBody(OpenAPI openAPI, String pathname, Operation operation) {
RequestBody requestBody = operation.getRequestBody();
if (requestBody == null) {
return;
}
rb.setContent(content);
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);
// 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);
}
// 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);
// update requestBody to use $ref instead of inline def
requestBody.set$ref(modelName);
// get "consumes", e.g. application/xml, application/json
Set<String> consumes;
if (requestBody == null || requestBody.getContent() == null || requestBody.getContent().isEmpty()) {
consumes = new HashSet<>();
consumes.add("application/json"); // default to application/json
LOGGER.info("Default to application/json for inline body schema");
} else {
consumes = requestBody.getContent().keySet();
}
}
} 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);
}
}
}
}
}
for (String consume : consumes) {
content.addMediaType(consume, mt);
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);
}
}
}
}
}
}
}
rb.setContent(content);
// add to openapi "components"
if (openAPI.getComponents().getRequestBodies() == null) {
Map<String, RequestBody> requestBodies = new HashMap<String, RequestBody>();
requestBodies.put(modelName, rb);
openAPI.getComponents().setRequestBodies(requestBodies);
} else {
openAPI.getComponents().getRequestBodies().put(modelName, rb);
}
// update requestBody to use $ref instead of inline def
requestBody.set$ref(modelName);
}
}
} else if (model instanceof ArraySchema) {
ArraySchema am = (ArraySchema) model;
Schema inner = am.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(op.getProperties(), pathname);
String modelName = resolveModelName(op.getTitle(), null);
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
am.setItems(schema);
} else {
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
am.setItems(schema);
addGenerated(modelName, innerModel);
openAPI.getComponents().addSchemas(modelName, innerModel);
}
}
}
}
}
/**
* Flatten inline models in parameters
*
* @param openAPI target spec
* @param pathname target pathname
* @param operation target operation
*/
private void flattenParameters(OpenAPI openAPI, String pathname, Operation operation) {
List<Parameter> parameters = operation.getParameters();
if (parameters == null) {
return;
}
for (Parameter parameter : parameters) {
if (parameter.getSchema() == null) {
continue;
}
Schema model = parameter.getSchema();
if (model instanceof ObjectSchema) {
Schema obj = (Schema) model;
if (obj.getType() == null || "object".equals(obj.getType())) {
if (obj.getProperties() != null && obj.getProperties().size() > 0) {
flattenProperties(obj.getProperties(), pathname);
String modelName = resolveModelName(obj.getTitle(), parameter.getName());
parameter.$ref(modelName);
addGenerated(modelName, model);
openAPI.getComponents().addSchemas(modelName, model);
}
}
} else if (model instanceof ArraySchema) {
ArraySchema am = (ArraySchema) model;
Schema inner = am.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(op.getProperties(), pathname);
String modelName = resolveModelName(op.getTitle(), parameter.getName());
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
am.setItems(schema);
} else {
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
am.setItems(schema);
addGenerated(modelName, innerModel);
openAPI.getComponents().addSchemas(modelName, innerModel);
Map<String, ApiResponse> responses = operation.getResponses();
if (responses != null) {
for (String key : responses.keySet()) {
ApiResponse response = responses.get(key);
if (ModelUtils.getSchemaFromResponse(response) != null) {
Schema property = ModelUtils.getSchemaFromResponse(response);
if (property instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) property;
if (op.getProperties() != null && op.getProperties().size() > 0) {
String modelName = resolveModelName(op.getTitle(), "inline_response_" + key);
Schema model = modelFromProperty(op, modelName);
String existing = matchGenerated(model);
Content content = response.getContent();
for (MediaType mediaType : content.values()) {
if (existing != null) {
Schema schema = this.makeSchema(existing, property);
schema.setRequired(op.getRequired());
mediaType.setSchema(schema);
} else {
Schema schema = this.makeSchema(modelName, property);
schema.setRequired(op.getRequired());
mediaType.setSchema(schema);
addGenerated(modelName, model);
openapi.getComponents().addSchemas(modelName, model);
}
}
}
} else if (property instanceof ArraySchema) {
ArraySchema ap = (ArraySchema) property;
Schema inner = ap.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(op.getProperties(), pathname);
String modelName = resolveModelName(op.getTitle(),
"inline_response_" + key);
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = this.makeSchema(existing, op);
schema.setRequired(op.getRequired());
ap.setItems(schema);
} else {
Schema schema = this.makeSchema(modelName, op);
schema.setRequired(op.getRequired());
ap.setItems(schema);
addGenerated(modelName, innerModel);
openapi.getComponents().addSchemas(modelName, innerModel);
}
}
}
} else if (property instanceof MapSchema) {
MapSchema mp = (MapSchema) property;
Schema innerProperty = ModelUtils.getAdditionalProperties(mp);
if (innerProperty instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) innerProperty;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(op.getProperties(), pathname);
String modelName = resolveModelName(op.getTitle(),
"inline_response_" + key);
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
mp.setAdditionalProperties(schema);
} else {
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
mp.setAdditionalProperties(schema);
addGenerated(modelName, innerModel);
openapi.getComponents().addSchemas(modelName, innerModel);
}
}
}
}
}
}
}
}
}
}
}
/**
* Flatten inline models in ApiResponses
*
* @param openAPI target spec
* @param pathname target pathname
* @param operation target operation
*/
private void flattenResponses(OpenAPI openAPI, String pathname, Operation operation) {
ApiResponses responses = operation.getResponses();
if (responses == null) {
return;
}
for (String key : responses.keySet()) {
ApiResponse response = responses.get(key);
if (ModelUtils.getSchemaFromResponse(response) == null) {
continue;
}
Schema property = ModelUtils.getSchemaFromResponse(response);
if (property instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) property;
if (op.getProperties() != null && op.getProperties().size() > 0) {
String modelName = resolveModelName(op.getTitle(), "inline_response_" + key);
Schema model = modelFromProperty(op, modelName);
String existing = matchGenerated(model);
Content content = response.getContent();
for (MediaType mediaType : content.values()) {
if (existing != null) {
Schema schema = this.makeSchema(existing, property);
schema.setRequired(op.getRequired());
mediaType.setSchema(schema);
} else {
Schema schema = this.makeSchema(modelName, property);
schema.setRequired(op.getRequired());
mediaType.setSchema(schema);
addGenerated(modelName, model);
openAPI.getComponents().addSchemas(modelName, model);
// 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 (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 (ModelUtils.isComposedSchema(model)) {
ComposedSchema m = (ComposedSchema) model;
if (m.getAllOf() != null && !m.getAllOf().isEmpty()) {
Schema child = null;
for (Schema component : m.getAllOf()) {
if (component.get$ref() == null) {
child = component;
}
}
}
}
} else if (property instanceof MapSchema) {
MapSchema mp = (MapSchema) property;
Schema innerProperty = ModelUtils.getAdditionalProperties(mp);
if (innerProperty instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) innerProperty;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(op.getProperties(), pathname);
String modelName = resolveModelName(op.getTitle(),
"inline_response_" + key);
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
mp.setAdditionalProperties(schema);
} else {
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
mp.setAdditionalProperties(schema);
addGenerated(modelName, innerModel);
openAPI.getComponents().addSchemas(modelName, innerModel);
if (child != null) {
Map<String, Schema> properties = child.getProperties();
flattenProperties(properties, modelName);
}
}
}
@@ -319,65 +318,6 @@ public class InlineModelResolver {
}
}
/**
* Flatten inline models in components
*
* @param openAPI target spec
*/
private void flattenComponents(OpenAPI openAPI) {
Map<String, Schema> models = openAPI.getComponents().getSchemas();
if (models == null) {
return;
}
List<String> modelNames = new ArrayList<String>(models.keySet());
for (String modelName : modelNames) {
Schema model = models.get(modelName);
if (model instanceof Schema) {
Schema m = (Schema) model;
Map<String, Schema> properties = m.getProperties();
flattenProperties(properties, modelName);
fixStringModel(m);
} else if (ModelUtils.isArraySchema(model)) {
ArraySchema m = (ArraySchema) model;
Schema inner = m.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
String innerModelName = resolveModelName(op.getTitle(), modelName + "_inner");
Schema innerModel = modelFromProperty(op, innerModelName);
String existing = matchGenerated(innerModel);
if (existing == null) {
openAPI.getComponents().addSchemas(innerModelName, innerModel);
addGenerated(innerModelName, innerModel);
Schema schema = new Schema().$ref(innerModelName);
schema.setRequired(op.getRequired());
m.setItems(schema);
} else {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
m.setItems(schema);
}
}
}
} else if (ModelUtils.isComposedSchema(model)) {
ComposedSchema m = (ComposedSchema) model;
if (m.getAllOf() != null && !m.getAllOf().isEmpty()) {
Schema child = null;
for (Schema component : m.getAllOf()) {
if (component.get$ref() == null) {
child = component;
}
}
if (child != null) {
Map<String, Schema> properties = child.getProperties();
flattenProperties(properties, modelName);
}
}
}
}
}
/**
* This function fix models that are string (mostly enum). Before this fix, the
* example would look something like that in the doc: "\"example from def\""
@@ -401,7 +341,10 @@ public class InlineModelResolver {
}
}
private String matchGenerated(Schema model) {
public String matchGenerated(Schema model) {
if (this.skipMatches) {
return null;
}
String json = Json.pretty(model);
if (generatedSignature.containsKey(json)) {
return generatedSignature.get(json);
@@ -409,18 +352,17 @@ public class InlineModelResolver {
return null;
}
private void addGenerated(String name, Schema model) {
public void addGenerated(String name, Schema model) {
generatedSignature.put(Json.pretty(model), name);
}
private String uniqueName(String key) {
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("/", "_"); // e.g. /me/videos => _me_videos
key = key.replaceAll("[^a-z_\\.A-Z0-9 ]", ""); // FIXME: a parameter
// should not be assigned. Also declare the methods parameters as 'final'.
while (!done) {
@@ -438,7 +380,7 @@ public class InlineModelResolver {
return key;
}
private void flattenProperties(Map<String, Schema> properties, String path) {
public void flattenProperties(Map<String, Schema> properties, String path) {
if (properties == null) {
return;
}
@@ -523,7 +465,28 @@ public class InlineModelResolver {
}
}
private Schema modelFromProperty(ObjectSchema object, String path) {
@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();
@@ -545,6 +508,22 @@ public class InlineModelResolver {
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(ModelUtils.getAdditionalProperties(object));
return model;
}
/**
* Make a Schema
*
@@ -552,7 +531,7 @@ public class InlineModelResolver {
* @param property Schema
* @return {@link Schema} A constructed OpenAPI property
*/
private Schema makeSchema(String ref, Schema property) {
public Schema makeSchema(String ref, Schema property) {
Schema newProperty = new Schema().$ref(ref);
this.copyVendorExtensions(property, newProperty);
return newProperty;
@@ -565,7 +544,7 @@ public class InlineModelResolver {
* @param target target property
*/
private void copyVendorExtensions(Schema source, Schema target) {
public void copyVendorExtensions(Schema source, Schema target) {
Map<String, Object> vendorExtensions = source.getExtensions();
if (vendorExtensions == null) {
return;
@@ -574,4 +553,12 @@ public class InlineModelResolver {
target.addExtension(extName, vendorExtensions.get(extName));
}
}
public boolean isSkipMatches() {
return skipMatches;
}
public void setSkipMatches(boolean skipMatches) {
this.skipMatches = skipMatches;
}
}

View File

@@ -95,7 +95,6 @@ public class CodegenConfigurator implements Serializable {
private boolean verbose;
private boolean skipOverwrite;
private boolean removeOperationIdPrefix;
private boolean logToStderr;
private boolean validateSpec;
private boolean enablePostProcessFile;
private String templateDir;
@@ -221,24 +220,6 @@ public class CodegenConfigurator implements Serializable {
return this;
}
public boolean getLogToStderr() {
return logToStderr;
}
public CodegenConfigurator setLogToStderr(boolean logToStderrte) {
this.logToStderr = logToStderr;
return this;
}
public boolean isGenerateAliasAsModel() {
return ModelUtils.isGenerateAliasAsModel();
}
public CodegenConfigurator setGenerateAliasAsModel(boolean generateAliasAsModel) {
ModelUtils.setGenerateAliasAsModel(generateAliasAsModel);
return this;
}
public String getModelNameSuffix() {
return modelNameSuffix;
}
@@ -648,15 +629,15 @@ public class CodegenConfigurator implements Serializable {
"\n - [debugOperations] prints operations passed to the template engine" +
"\n - [debugSupportingFiles] prints additional data passed to the template engine");
GeneratorProperties.setProperty("debugOpenAPI", "");
GeneratorProperties.setProperty("debugModels", "");
GeneratorProperties.setProperty("debugOperations", "");
GeneratorProperties.setProperty("debugSupportingFiles", "");
System.setProperty("debugOpenAPI", "");
System.setProperty("debugModels", "");
System.setProperty("debugOperations", "");
System.setProperty("debugSupportingFiles", "");
}
private void setSystemProperties() {
for (Map.Entry<String, String> entry : systemProperties.entrySet()) {
GeneratorProperties.setProperty(entry.getKey(), entry.getValue());
System.setProperty(entry.getKey(), entry.getValue());
}
}

View File

@@ -1,57 +0,0 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.config;
import java.util.Properties;
/**
* GeneratorProperties encapsulates SystemProperties, since the codegen mechanism heavily relies on a stable,
* non-changing System Property Basis. Using plain System.(get|set|clear)Property raises Race-Conditions in combination
* with Code, that uses System.setProperties (e.g. maven-surefire-plugin).
*
* @author gndrm
* @since 2018
*/
public class GeneratorProperties {
private static ThreadLocal<Properties> properties = new InheritableThreadLocal<Properties>() {
@Override
protected Properties initialValue() {
return (Properties) System.getProperties().clone();
};
};
public static String getProperty(String key, String defaultValue) {
return properties.get().getProperty(key, defaultValue);
}
public static String getProperty(String key) {
return properties.get().getProperty(key);
}
public static void setProperty(String key, String value) {
properties.get().setProperty(key, value);
}
public static void clearProperty(String key) {
properties.get().remove(key);
}
public static void reset() {
properties.remove();
}
}

View File

@@ -75,12 +75,6 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
protected Set<String> collectionTypes;
protected Set<String> mapTypes;
// true if support nullable type
protected boolean supportNullable = Boolean.FALSE;
// nullable type
protected Set<String> nullableType = new HashSet<String>();
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractCSharpCodegen.class);
public AbstractCSharpCodegen() {
@@ -136,26 +130,19 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
"String",
"string",
"bool?",
"bool",
"double?",
"double",
"decimal?",
"decimal",
"int?",
"int",
"long?",
"long",
"float?",
"float",
"byte[]",
"ICollection",
"Collection",
"List",
"Dictionary",
"DateTime?",
"DateTime",
"DateTimeOffset?",
"DataTimeOffset",
"String",
"Boolean",
"Double",
"Int32",
@@ -170,7 +157,6 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
instantiationTypes.put("list", "List");
instantiationTypes.put("map", "Dictionary");
// Nullable types here assume C# 2 support is not part of base
typeMapping = new HashMap<String, String>();
typeMapping.put("string", "string");
@@ -190,11 +176,6 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
typeMapping.put("map", "Dictionary");
typeMapping.put("object", "Object");
typeMapping.put("UUID", "Guid?");
// nullable type
nullableType = new HashSet<String>(
Arrays.asList("decimal", "bool", "int", "float", "long", "double", "DateTime", "Guid")
);
}
public void setReturnICollection(boolean returnICollection) {
@@ -228,7 +209,8 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
this.useDateTimeOffsetFlag = flag;
if (flag) {
typeMapping.put("DateTime", "DateTimeOffset?");
} else {
}
else {
typeMapping.put("DateTime", "DateTime?");
}
}
@@ -439,8 +421,8 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
}
for (Map.Entry<String, Object> entry : models.entrySet()) {
String openAPIName = entry.getKey();
CodegenModel model = ModelUtils.getModelByName(openAPIName, models);
String swaggerName = entry.getKey();
CodegenModel model = ModelUtils.getModelByName(swaggerName, models);
if (model != null) {
for (CodegenProperty var : model.allVars) {
if (enumRefs.containsKey(var.dataType)) {
@@ -501,7 +483,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
}
}
} else {
LOGGER.warn("Expected to retrieve model %s by name, but no model was found. Check your -Dmodels inclusions.", openAPIName);
LOGGER.warn("Expected to retrieve model %s by name, but no model was found. Check your -Dmodels inclusions.", swaggerName);
}
}
}
@@ -591,30 +573,28 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
}
}
if (!isSupportNullable()) {
for (CodegenParameter parameter : operation.allParams) {
CodegenModel model = null;
for (Object modelHashMap : allModels) {
CodegenModel codegenModel = ((HashMap<String, CodegenModel>) modelHashMap).get("model");
if (codegenModel.getClassname().equals(parameter.dataType)) {
model = codegenModel;
break;
}
for (CodegenParameter parameter: operation.allParams) {
CodegenModel model = null;
for(Object modelHashMap: allModels) {
CodegenModel codegenModel = ((HashMap<String, CodegenModel>) modelHashMap).get("model");
if (codegenModel.getClassname().equals(parameter.dataType)) {
model = codegenModel;
break;
}
}
if (model == null) {
// Primitive data types all come already marked
parameter.isNullable = true;
if (model == null) {
// Primitive data types all come already marked
parameter.isNullable = true;
} else {
// Effectively mark enum models as enums and non-nullable
if (model.isEnum) {
parameter.isEnum = true;
parameter.allowableValues = model.allowableValues;
parameter.isPrimitiveType = true;
parameter.isNullable = false;
} else {
// Effectively mark enum models as enums and non-nullable
if (model.isEnum) {
parameter.isEnum = true;
parameter.allowableValues = model.allowableValues;
parameter.isPrimitiveType = true;
parameter.isNullable = false;
} else {
parameter.isNullable = true;
}
parameter.isNullable = true;
}
}
}
@@ -812,14 +792,6 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
return reservedWords.contains(word);
}
public String getNullableType(Schema p, String type) {
if (languageSpecificPrimitives.contains(type)) {
return type;
} else {
return null;
}
}
@Override
public String getSchemaType(Schema p) {
String openAPIType = super.getSchemaType(p);
@@ -832,9 +804,8 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
if (typeMapping.containsKey(openAPIType)) {
type = typeMapping.get(openAPIType);
String languageType = getNullableType(p, type);
if (languageType != null) {
return languageType;
if (languageSpecificPrimitives.contains(type)) {
return type;
}
} else {
type = openAPIType;
@@ -979,14 +950,6 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
this.interfacePrefix = interfacePrefix;
}
public boolean isSupportNullable() {
return supportNullable;
}
public void setSupportNullable(final boolean supportNullable) {
this.supportNullable = supportNullable;
}
@Override
public String toEnumValue(String value, String datatype) {
// C# only supports enums as literals for int, int?, long, long?, byte, and byte?. All else must be treated as strings.
@@ -1048,9 +1011,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
@Override
public boolean isDataTypeString(String dataType) {
// also treat double/decimal/float as "string" in enum so that the values (e.g. 2.8) get double-quoted
return "String".equalsIgnoreCase(dataType) ||
"double?".equals(dataType) || "decimal?".equals(dataType) || "float?".equals(dataType) ||
"double".equals(dataType) || "decimal".equals(dataType) || "float".equals(dataType);
return "String".equalsIgnoreCase(dataType) || "double?".equals(dataType) || "decimal?".equals(dataType) || "float?".equals(dataType);
}
@Override

View File

@@ -117,8 +117,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
setReservedWordsLowerCase(
Arrays.asList(
// special words
"object",
// used as internal variables, can collide with parameter names
"localVarPath", "localVarQueryParams", "localVarCollectionQueryParams",
"localVarHeaderParams", "localVarFormParams", "localVarPostBody",
@@ -536,22 +534,17 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
@Override
public String apiFileFolder() {
return (outputFolder + "/" + sourceFolder + "/" + apiPackage()).replace('.', File.separatorChar);
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', '/');
}
@Override
public String apiTestFileFolder() {
return (outputFolder + "/" + testFolder + "/" + apiPackage()).replace('.', File.separatorChar);
}
@Override
public String modelTestFileFolder() {
return (outputFolder + "/" + testFolder + "/" + modelPackage()).replace('.', File.separatorChar);
return outputFolder + "/" + testFolder + "/" + apiPackage().replace('.', '/');
}
@Override
public String modelFileFolder() {
return (outputFolder + "/" + sourceFolder + "/" + modelPackage()).replace('.', File.separatorChar);
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', '/');
}
@Override
@@ -579,11 +572,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
return toApiName(name) + "Test";
}
@Override
public String toModelTestFilename(String name) {
return toModelName(name) + "Test";
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
@@ -1438,13 +1426,4 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
public void setParentOverridden(final boolean parentOverridden) {
this.parentOverridden = parentOverridden;
}
@Override
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) {
super.addAdditionPropertiesToCodeGenModel(codegenModel, schema);
// See https://github.com/OpenAPITools/openapi-generator/pull/1729#issuecomment-449937728
codegenModel.additionalPropertiesType = getSchemaType(ModelUtils.getAdditionalProperties(schema));
addImport(codegenModel, codegenModel.additionalPropertiesType);
}
}

View File

@@ -54,9 +54,6 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
supportsInheritance = true;
// to support multiple inheritance e.g. export interface ModelC extends ModelA, ModelB
//supportsMultipleInheritance = true;
// NOTE: TypeScript uses camel cased reserved words, while models are title cased. We don't want lowercase comparisons.
reservedWords.addAll(Arrays.asList(
// local variable names used in API methods (endpoints)

View File

@@ -83,9 +83,6 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
// By default, generated code is considered public
protected boolean nonPublicApi = Boolean.FALSE;
// use KellermanSoftware.CompareNetObjects for deep recursive object comparision
protected boolean useCompareNetObjects = Boolean.FALSE;
public CSharpClientCodegen() {
super();
supportsInheritance = true;
@@ -199,10 +196,6 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
CodegenConstants.VALIDATABLE_DESC,
this.validatable);
addSwitch(CodegenConstants.USE_COMPARE_NET_OBJECTS,
CodegenConstants.USE_COMPARE_NET_OBJECTS_DESC,
this.useCompareNetObjects);
regexModifiers = new HashMap<Character, String>();
regexModifiers.put('i', "IgnoreCase");
regexModifiers.put('m', "Multiline");
@@ -776,6 +769,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
}
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
@@ -804,10 +798,6 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
this.generatePropertyChanged = generatePropertyChanged;
}
public void setUseCompareNetObjects(final Boolean useCompareNetObjects) {
this.useCompareNetObjects = useCompareNetObjects;
}
public boolean isNonPublicApi() {
return nonPublicApi;
}

View File

@@ -22,7 +22,6 @@ import static org.apache.commons.lang3.StringUtils.isEmpty;
import com.google.common.collect.ImmutableMap;
import com.samskivert.mustache.Mustache;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import org.openapitools.codegen.CliOption;
@@ -33,7 +32,6 @@ import org.openapitools.codegen.CodegenParameter;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,7 +49,7 @@ import static org.openapitools.codegen.utils.StringUtils.underscore;
public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
@SuppressWarnings({"hiding"})
private static final Logger LOGGER = LoggerFactory.getLogger(CSharpClientCodegen.class);
private static final String NET45 = "v4.5.2";
private static final String NET45 = "v4.5";
private static final String NET40 = "v4.0";
private static final String NET35 = "v3.5";
// TODO: v5.0 is PCL, not netstandard version 1.3, and not a specific .NET Framework. This needs to be updated,
@@ -86,39 +84,19 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
// By default, generated code is considered public
protected boolean nonPublicApi = Boolean.FALSE;
public CSharpRefactorClientCodegen() {
super();
// mapped non-nullable type without ?
typeMapping = new HashMap<String, String>();
typeMapping.put("string", "string");
typeMapping.put("binary", "byte[]");
typeMapping.put("ByteArray", "byte[]");
typeMapping.put("boolean", "bool");
typeMapping.put("integer", "int");
typeMapping.put("float", "float");
typeMapping.put("long", "long");
typeMapping.put("double", "double");
typeMapping.put("number", "decimal");
typeMapping.put("DateTime", "DateTime");
typeMapping.put("date", "DateTime");
typeMapping.put("file", "System.IO.Stream");
typeMapping.put("array", "List");
typeMapping.put("list", "List");
typeMapping.put("map", "Dictionary");
typeMapping.put("object", "Object");
typeMapping.put("UUID", "Guid");
setSupportNullable(Boolean.TRUE);
hideGenerationTimestamp = Boolean.TRUE;
supportsInheritance = true;
modelTemplateFiles.put("model.mustache", ".cs");
apiTemplateFiles.put("api.mustache", ".cs");
modelDocTemplateFiles.put("model_doc.mustache", ".md");
apiDocTemplateFiles.put("api_doc.mustache", ".md");
embeddedTemplateDir = templateDir = "csharp-refactor";
hideGenerationTimestamp = Boolean.TRUE;
cliOptions.clear();
// CLI options
@@ -149,7 +127,7 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
frameworks = new ImmutableMap.Builder<String, String>()
.put(NET35, ".NET Framework 3.5 compatible")
.put(NET40, ".NET Framework 4.0 compatible")
.put(NET45, ".NET Framework 4.5.2+ compatible")
.put(NET45, ".NET Framework 4.5+ compatible")
.put(NETSTANDARD, ".NET Standard 1.3 compatible")
.put(UWP, "Universal Windows Platform (IMPORTANT: this will be decommissioned and replaced by v5.0)")
.build();
@@ -245,6 +223,7 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
setModelPropertyNaming((String) additionalProperties.get(CodegenConstants.MODEL_PROPERTY_NAMING));
}
if (isEmpty(apiPackage)) {
setApiPackage("Api");
}
@@ -316,10 +295,8 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
setTargetFrameworkNuget("net40");
setSupportsAsync(Boolean.FALSE);
} else { // 4.5+
} else {
additionalProperties.put(MCS_NET_VERSION_KEY, "4.5.2-api");
// some libs need 452 isntead of 45 in the config
additionalProperties.put("isNet452", true);
setTargetFrameworkNuget("net45");
setSupportsAsync(Boolean.TRUE);
}
@@ -630,10 +607,6 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
public void postProcessParameter(CodegenParameter parameter) {
postProcessPattern(parameter.pattern, parameter.vendorExtensions);
super.postProcessParameter(parameter);
if (!parameter.required && nullableType.contains(parameter.dataType)) { //optional
parameter.dataType = parameter.dataType + "?";
}
}
@Override
@@ -877,17 +850,4 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
// To avoid unexpected behaviors when options are passed programmatically such as { "supportsAsync": "" }
return super.processCompiler(compiler).emptyStringIsFalse(true);
}
@Override
public String getNullableType(Schema p, String type) {
if (languageSpecificPrimitives.contains(type)) {
if (isSupportNullable() && ModelUtils.isNullable(p) && nullableType.contains(type)) {
return type + "?";
} else {
return type;
}
} else {
return null;
}
}
}

View File

@@ -447,7 +447,7 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
if (ElmVersion.ELM_018.equals(elmVersion)) {
String path = op.path;
for (CodegenParameter param : op.pathParams) {
final String var = paramToString("params", param, false, null);
final String var = paramToString(param, false, null);
path = path.replace("{" + param.paramName + "}", "\" ++ " + var + " ++ \"");
hasDateTime = hasDateTime || param.isDateTime;
hasDate = hasDate || param.isDate;
@@ -457,7 +457,7 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
final List<String> paths = Arrays.asList(op.path.substring(1).split("/"));
String path = paths.stream().map(str -> str.charAt(0) == '{' ? str : "\"" + str + "\"").collect(Collectors.joining(", "));
for (CodegenParameter param : op.pathParams) {
String str = paramToString("params", param, false, null);
String str = paramToString(param, false, null);
path = path.replace("{" + param.paramName + "}", str);
hasDateTime = hasDateTime || param.isDateTime;
hasDate = hasDate || param.isDate;
@@ -465,15 +465,10 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
op.path = path;
final String query = op.queryParams.stream()
.map(param -> paramToString("params", param, true, "Url.string \"" + param.baseName + "\""))
.map(param -> paramToString(param, true, "Url.string \"" + param.paramName + "\""))
.collect(Collectors.joining(", "));
op.vendorExtensions.put("query", query);
final String headers = op.headerParams.stream()
.map(param -> paramToString("headers", param, true, "Http.header \"" + param.baseName + "\""))
.collect(Collectors.joining(", "));
op.vendorExtensions.put("headers", headers);
// TODO cookies
// TODO headers
// TODO forms
}
@@ -568,8 +563,8 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
return "(Just " + value + ")";
}
private String paramToString(final String prefix, final CodegenParameter param, final boolean useMaybe, final String maybeMapResult) {
final String paramName = (ElmVersion.ELM_018.equals(elmVersion) ? "" : prefix + ".") + param.paramName;
private String paramToString(final CodegenParameter param, final boolean useMaybe, final String maybeMapResult) {
final String paramName = (ElmVersion.ELM_018.equals(elmVersion) ? "" : "params.") + param.paramName;
if (!useMaybe) {
param.required = true;
}
@@ -606,15 +601,11 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
}
String mapResult = "";
if (maybeMapResult != null) {
if (mapFn == "") {
mapResult = maybeMapResult;
} else {
mapResult = maybeMapResult + (param.required ? " <|" : " <<");
}
mapResult = maybeMapResult + (param.required ? " <|" : " <<");
}
final String just = useMaybe ? "Just (" : "";
final String justEnd = useMaybe ? ")" : "";
return (param.required ? just : "Maybe.map (") + mapResult + " " + mapFn + (param.required ? " " : ") ") + paramName + (param.required ? justEnd : "");
return (param.required ? just : "Maybe.map") + mapResult + " " + mapFn + " " + paramName + (param.required ? justEnd : "");
}
@Override

View File

@@ -64,7 +64,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
public static final String FEIGN_VERSION = "feignVersion";
public static final String PARCELABLE_MODEL = "parcelableModel";
public static final String USE_RUNTIME_EXCEPTION = "useRuntimeException";
public static final String USE_REFLECTION_EQUALS_HASHCODE = "useReflectionEqualsHashCode";
public static final String PLAY_24 = "play24";
public static final String PLAY_25 = "play25";
@@ -89,9 +88,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
protected String gradleWrapperPackage = "gradle.wrapper";
protected boolean useRxJava = false;
protected boolean useRxJava2 = false;
// backwards compatibility for openapi configs that specify neither rx1 nor rx2
// (mustache does not allow for boolean operators so we need this extra field)
protected boolean doNotUseRx = true;
protected boolean doNotUseRx = true; // backwards compatibility for swagger configs that specify neither rx1 nor rx2 (mustache does not allow for boolean operators so we need this extra field)
protected boolean usePlayWS = false;
protected String playVersion = PLAY_25;
protected String feignVersion = FEIGN_9;
@@ -100,7 +97,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
protected boolean performBeanValidation = false;
protected boolean useGzipFeature = false;
protected boolean useRuntimeException = false;
protected boolean useReflectionEqualsHashCode = false;
public JavaClientCodegen() {
super();
@@ -111,8 +108,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
apiPackage = "org.openapitools.client.api";
modelPackage = "org.openapitools.client.model";
modelTestTemplateFiles.put("model_test.mustache", ".java");
cliOptions.add(CliOption.newBoolean(USE_RX_JAVA, "Whether to use the RxJava adapter with the retrofit2 library."));
cliOptions.add(CliOption.newBoolean(USE_RX_JAVA2, "Whether to use the RxJava2 adapter with the retrofit2 library."));
cliOptions.add(CliOption.newBoolean(PARCELABLE_MODEL, "Whether to generate models for Android that implement Parcelable with the okhttp-gson library."));
@@ -124,7 +119,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
cliOptions.add(CliOption.newBoolean(USE_GZIP_FEATURE, "Send gzip-encoded requests"));
cliOptions.add(CliOption.newBoolean(USE_RUNTIME_EXCEPTION, "Use RuntimeException instead of Exception"));
cliOptions.add(CliOption.newBoolean(FEIGN_VERSION, "Version of OpenFeign: '10.x', '9.x' (default)"));
cliOptions.add(CliOption.newBoolean(USE_REFLECTION_EQUALS_HASHCODE, "Use org.apache.commons.lang3.builder for equals and hashCode in the models. WARNING: This will fail under a security manager, unless the appropriate permissions are set up correctly and also there's potential performance impact."));
supportedLibraries.put(JERSEY1, "HTTP client: Jersey client 1.19.4. JSON processing: Jackson 2.8.9. Enable Java6 support using '-DsupportJava6=true'. Enable gzip request encoding using '-DuseGzipFeature=true'.");
supportedLibraries.put(FEIGN, "HTTP client: OpenFeign 9.4.0. JSON processing: Jackson 2.8.9. To enable OpenFeign 10.x, set the 'feignVersion' option to '10.x'");
@@ -231,10 +225,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
this.setUseRuntimeException(convertPropertyToBooleanAndWriteBack(USE_RUNTIME_EXCEPTION));
}
if (additionalProperties.containsKey(USE_REFLECTION_EQUALS_HASHCODE)) {
this.setUseReflectionEqualsHashCode(convertPropertyToBooleanAndWriteBack(USE_REFLECTION_EQUALS_HASHCODE));
}
final String invokerFolder = (sourceFolder + '/' + invokerPackage).replace(".", "/");
final String authFolder = (sourceFolder + '/' + invokerPackage + ".auth").replace(".", "/");
final String apiFolder = (sourceFolder + '/' + apiPackage).replace(".", "/");
@@ -642,10 +632,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
this.useRuntimeException = useRuntimeException;
}
public void setUseReflectionEqualsHashCode(boolean useReflectionEqualsHashCode) {
this.useReflectionEqualsHashCode = useReflectionEqualsHashCode;
}
final private static Pattern JSON_MIME_PATTERN = Pattern.compile("(?i)application\\/json(;.*)?");
final private static Pattern JSON_VENDOR_MIME_PATTERN = Pattern.compile("(?i)application\\/vnd.(.*)+json(;.*)?");

View File

@@ -25,7 +25,6 @@ import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.config.GeneratorProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -61,8 +60,8 @@ public class JavaInflectorServerCodegen extends AbstractJavaCodegen {
apiDocTemplateFiles.remove("api_doc.mustache");
apiPackage = GeneratorProperties.getProperty("swagger.codegen.inflector.apipackage", "org.openapitools.controllers");
modelPackage = GeneratorProperties.getProperty("swagger.codegen.inflector.modelpackage", "org.openapitools.model");
apiPackage = System.getProperty("swagger.codegen.inflector.apipackage", "org.openapitools.controllers");
modelPackage = System.getProperty("swagger.codegen.inflector.modelpackage", "org.openapitools.model");
additionalProperties.put("title", title);
// java inflector uses the jackson lib

View File

@@ -23,7 +23,6 @@ import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.config.GeneratorProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,17 +55,17 @@ public class JavaUndertowServerCodegen extends AbstractJavaCodegen {
modelDocTemplateFiles.remove("model_doc.mustache");
apiDocTemplateFiles.remove("api_doc.mustache");
if(GeneratorProperties.getProperty("swagger.codegen.undertow.apipackage") != null && GeneratorProperties.getProperty("openapi.codegen.undertow.apipackage") == null) {
if(System.getProperty("swagger.codegen.undertow.apipackage") != null && System.getProperty("openapi.codegen.undertow.apipackage") == null) {
LOGGER.warn("System property 'swagger.codegen.undertow.apipackage' was renamed to 'swagger.codegen.undertow.apipackage'");
apiPackage = GeneratorProperties.getProperty("swagger.codegen.undertow.apipackage", "org.openapitools.handler");
apiPackage = System.getProperty("swagger.codegen.undertow.apipackage", "org.openapitools.handler");
} else {
apiPackage = GeneratorProperties.getProperty("openapi.codegen.undertow.apipackage", "org.openapitools.handler");
apiPackage = System.getProperty("openapi.codegen.undertow.apipackage", "org.openapitools.handler");
}
if(GeneratorProperties.getProperty("swagger.codegen.undertow.modelpackage") != null && GeneratorProperties.getProperty("openapi.codegen.undertow.modelpackage") == null) {
if(System.getProperty("swagger.codegen.undertow.modelpackage") != null && System.getProperty("openapi.codegen.undertow.modelpackage") == null) {
LOGGER.warn("System property 'swagger.codegen.undertow.modelpackage' was renamed to 'openapi.codegen.undertow.modelpackage'");
modelPackage = GeneratorProperties.getProperty("swagger.codegen.undertow.modelpackage", "org.openapitools.model");
modelPackage = System.getProperty("swagger.codegen.undertow.modelpackage", "org.openapitools.model");
} else {
modelPackage = GeneratorProperties.getProperty("openapi.codegen.undertow.modelpackage", "org.openapitools.model");
modelPackage = System.getProperty("openapi.codegen.undertow.modelpackage", "org.openapitools.model");
}
additionalProperties.put("title", title);

View File

@@ -103,7 +103,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
protected String modelDocPath = "docs/";
protected String apiTestPath = "api/";
protected String modelTestPath = "model/";
protected boolean useES6 = true; // default is ES5
protected boolean useES6 = false; // default is ES5
private String modelPropertyNaming = "camelCase";
public JavascriptClientCodegen() {
@@ -207,8 +207,8 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC)
.defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(USE_ES6,
"use JavaScript ES6 (ECMAScript 6) (beta). Default is ES6.")
.defaultValue(Boolean.TRUE.toString()));
"use JavaScript ES6 (ECMAScript 6) (beta). Default is ES5.")
.defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(CodegenConstants.MODEL_PROPERTY_NAMING, CodegenConstants.MODEL_PROPERTY_NAMING_DESC).defaultValue("camelCase"));
}
@@ -1046,16 +1046,6 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
}
}
for (CodegenProperty var : cm.allVars) {
// Add JSDoc @type value for this property.
String jsDocType = getJSDocType(cm, var);
var.vendorExtensions.put("x-jsdoc-type", jsDocType);
if (Boolean.TRUE.equals(var.required)) {
required.add(var);
}
}
if (supportsInheritance || supportsMixins) {
for (CodegenProperty var : cm.allVars) {
if (Boolean.TRUE.equals(var.required)) {

View File

@@ -101,14 +101,6 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
typeMapping.put("object", "Any");
typeMapping.put("binary", "Array<kotlin.Byte>");
typeMapping.put("date", "java.time.LocalDate");
typeMapping.put("date-time", "java.time.OffsetDateTime");
typeMapping.put("Date", "java.time.LocalDate");
typeMapping.put("DateTime", "java.time.OffsetDateTime");
importMapping.put("Date", "java.time.LocalDate");
importMapping.put("DateTime", "java.time.OffsetDateTime");
languageSpecificPrimitives.addAll(Arrays.asList(
"Any",
"Byte",
@@ -251,6 +243,14 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
public void processOpts() {
super.processOpts();
typeMapping.put("date", "java.time.LocalDate");
typeMapping.put("date-time", "java.time.OffsetDateTime");
typeMapping.put("Date", "java.time.LocalDate");
typeMapping.put("DateTime", "java.time.OffsetDateTime");
importMapping.put("Date", "java.time.LocalDate");
importMapping.put("DateTime", "java.time.OffsetDateTime");
// optional jackson mappings for BigDecimal support
importMapping.put("ToStringSerializer", "com.fasterxml.jackson.databind.ser.std.ToStringSerializer");
importMapping.put("JsonSerialize", "com.fasterxml.jackson.databind.annotation.JsonSerialize");

View File

@@ -34,7 +34,6 @@ import org.openapitools.codegen.CodegenResponse;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.DefaultCodegen;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.config.GeneratorProperties;
import org.openapitools.codegen.utils.URLPathUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -352,7 +351,7 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
}
writeOptional(outputFolder, new SupportingFile("package.mustache", "", "package.json"));
writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md"));
if (GeneratorProperties.getProperty("noservice") == null) {
if (System.getProperty("noservice") == null) {
apiTemplateFiles.put(
"service.mustache", // the template to use
"Service.js"); // the extension for each file to write

View File

@@ -53,9 +53,6 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
public PerlClientCodegen() {
super();
// add multiple inheritance support (beta)
supportsMultipleInheritance = true;
// clear import mapping (from default generator) as perl does not use it
// at the moment
importMapping.clear();

View File

@@ -22,10 +22,8 @@ import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.CodegenSecurity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.swagger.v3.oas.models.security.SecurityScheme;
import java.io.File;
import java.util.Collections;
@@ -33,23 +31,15 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.net.URLEncoder;
import org.apache.commons.lang3.StringEscapeUtils;
import java.io.UnsupportedEncodingException;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.Schema;
public class PhpSlimServerCodegen extends AbstractPhpCodegen {
private static final Logger LOGGER = LoggerFactory.getLogger(PhpSlimServerCodegen.class);
public static final String USER_CLASSNAME_KEY = "userClassname";
public static final String PHPCS_STANDARD = "phpcsStandard";
protected String groupId = "org.openapitools";
protected String artifactId = "openapi-server";
protected String authDirName = "Auth";
protected String authPackage = "";
protected String phpcsStandard = "PSR12";
public PhpSlimServerCodegen() {
super();
@@ -63,7 +53,6 @@ public class PhpSlimServerCodegen extends AbstractPhpCodegen {
setInvokerPackage("OpenAPIServer");
apiPackage = invokerPackage + "\\" + apiDirName;
modelPackage = invokerPackage + "\\" + modelDirName;
authPackage = invokerPackage + "\\" + authDirName;
outputFolder = "generated-code" + File.separator + "slim";
modelTestTemplateFiles.put("model_test.mustache", ".php");
@@ -84,6 +73,9 @@ public class PhpSlimServerCodegen extends AbstractPhpCodegen {
break;
}
}
cliOptions.add(new CliOption(PHPCS_STANDARD, "PHP CodeSniffer <standard> option. Accepts name or path of the coding standard to use.")
.defaultValue("PSR12"));
}
@Override
@@ -123,29 +115,25 @@ public class PhpSlimServerCodegen extends AbstractPhpCodegen {
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
// Update the invokerPackage for the default authPackage
authPackage = invokerPackage + "\\" + authDirName;
if (additionalProperties.containsKey(PHPCS_STANDARD)) {
this.setPhpcsStandard((String) additionalProperties.get(PHPCS_STANDARD));
} else {
additionalProperties.put(PHPCS_STANDARD, phpcsStandard);
}
// make auth src path available in mustache template
additionalProperties.put("authPackage", authPackage);
additionalProperties.put("authSrcPath", "./" + toSrcPath(authPackage, srcBasePath));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("composer.mustache", "", "composer.json"));
supportingFiles.add(new SupportingFile("index.mustache", "", "index.php"));
supportingFiles.add(new SupportingFile(".htaccess", "", ".htaccess"));
supportingFiles.add(new SupportingFile("AbstractApiController.mustache", toSrcPath(invokerPackage, srcBasePath), toAbstractName("ApiController") + ".php"));
supportingFiles.add(new SupportingFile("SlimRouter.mustache", toSrcPath(invokerPackage, srcBasePath), "SlimRouter.php"));
supportingFiles.add(new SupportingFile("phpunit.xml.mustache", "", "phpunit.xml.dist"));
supportingFiles.add(new SupportingFile("phpcs.xml.mustache", "", "phpcs.xml.dist"));
}
@Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
addUserClassnameToOperations(operations);
escapeMediaType(operationList);
return objs;
}
@@ -172,94 +160,8 @@ public class PhpSlimServerCodegen extends AbstractPhpCodegen {
return objs;
}
@Override
public List<CodegenSecurity> fromSecurity(Map<String, SecurityScheme> securitySchemeMap) {
List<CodegenSecurity> codegenSecurities = super.fromSecurity(securitySchemeMap);
if (Boolean.FALSE.equals(codegenSecurities.isEmpty())) {
supportingFiles.add(new SupportingFile("abstract_authenticator.mustache", toSrcPath(authPackage, srcBasePath), toAbstractName("Authenticator") + ".php"));
}
return codegenSecurities;
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return toAbstractName("DefaultApi");
}
return toAbstractName(initialCaps(name) + "Api");
}
@Override
public String toApiTestFilename(String name) {
if (name.length() == 0) {
return "DefaultApiTest";
}
return initialCaps(name) + "ApiTest";
}
/**
* Strips out abstract prefix and suffix from classname and puts it in "userClassname" property of operations object.
*
* @param operations codegen object with operations
*/
private void addUserClassnameToOperations(Map<String, Object> operations) {
String classname = (String) operations.get("classname");
classname = classname.replaceAll("^" + abstractNamePrefix, "");
classname = classname.replaceAll(abstractNameSuffix + "$", "");
operations.put(USER_CLASSNAME_KEY, classname);
}
@Override
public String encodePath(String input) {
if (input == null) {
return input;
}
// from DefaultCodegen.java
// remove \t, \n, \r
// replace \ with \\
// replace " with \"
// outter unescape to retain the original multi-byte characters
// finally escalate characters avoiding code injection
input = super.escapeUnsafeCharacters(
StringEscapeUtils.unescapeJava(
StringEscapeUtils.escapeJava(input)
.replace("\\/", "/"))
.replaceAll("[\\t\\n\\r]", " ")
.replace("\\", "\\\\"));
// .replace("\"", "\\\""));
// from AbstractPhpCodegen.java
// Trim the string to avoid leading and trailing spaces.
input = input.trim();
try {
input = URLEncoder.encode(input, "UTF-8")
.replaceAll("\\+", "%20")
.replaceAll("\\%2F", "/")
.replaceAll("\\%7B", "{") // keep { part of complex placeholders
.replaceAll("\\%7D", "}") // } part
.replaceAll("\\%5B", "[") // [ part
.replaceAll("\\%5D", "]") // ] part
.replaceAll("\\%3A", ":") // : part
.replaceAll("\\%2B", "+") // + part
.replaceAll("\\%5C\\%5Cd", "\\\\d"); // \d part
} catch (UnsupportedEncodingException e) {
// continue
LOGGER.error(e.getMessage(), e);
}
return input;
}
@Override
public CodegenOperation fromOperation(String path,
String httpMethod,
Operation operation,
Map<String, Schema> schemas,
OpenAPI openAPI) {
CodegenOperation op = super.fromOperation(path, httpMethod, operation, schemas, openAPI);
op.path = encodePath(path);
return op;
public void setPhpcsStandard(String phpcsStandard) {
this.phpcsStandard = phpcsStandard;
}
}

View File

@@ -29,7 +29,6 @@ import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.DefaultCodegen;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.ProcessUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -426,16 +425,6 @@ public class PowerShellClientCodegen extends DefaultCodegen implements CodegenCo
index++;
}
}
return objs;
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
List<Object> models = (List<Object>) objs.get("models");
// add x-index to properties
ProcessUtils.addIndexToProperties(models);
return objs;
}
}

View File

@@ -619,15 +619,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
public String toDefaultValue(Schema p) {
if (ModelUtils.isBooleanSchema(p)) {
if (p.getDefault() != null) {
if (Boolean.valueOf(p.getDefault().toString()) == false)
return "False";
else
return "True";
}
// include fallback to example, default defined as server only
// example is not defined as server only
if (p.getExample() != null) {
if (Boolean.valueOf(p.getExample().toString()) == false)
if (p.getDefault().toString().equalsIgnoreCase("false"))
return "False";
else
return "True";
@@ -640,24 +632,10 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
if (p.getDefault() != null) {
return p.getDefault().toString();
}
// default numbers are not yet returned by v2 spec openAPI results
// https://github.com/swagger-api/swagger-parser/issues/971
// include fallback to example, default defined as server only
// example is not defined as server only
if (p.getExample() != null) {
return p.getExample().toString();
}
} else if (ModelUtils.isIntegerSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString();
}
// default integers are not yet returned by v2 spec openAPI results
// https://github.com/swagger-api/swagger-parser/issues/971
// include fallback to example, default defined as server only
// example is not defined as server only
if (p.getExample() != null) {
return p.getExample().toString();
}
} else if (ModelUtils.isStringSchema(p)) {
if (p.getDefault() != null) {
if (Pattern.compile("\r\n|\r|\n").matcher((String) p.getDefault()).find())
@@ -665,23 +643,6 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
else
return "'" + p.getDefault() + "'";
}
// include fallback to example, default defined as server only
// example is not defined as server only
if (p.getExample() != null) {
if (Pattern.compile("\r\n|\r|\n").matcher((String) p.getExample()).find())
return "'''" + p.getExample() + "'''";
else
return "'" + p.getExample() + "'";
}
} else if (ModelUtils.isArraySchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString();
}
// include fallback to example, default defined as server only
// example is not defined as server only
if (p.getExample() != null) {
return p.getExample().toString();
}
}
return null;
@@ -801,4 +762,5 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
}
}
}
}

View File

@@ -68,8 +68,6 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
public RubyClientCodegen() {
super();
supportsInheritance = true;
// clear import mapping (from default generator) as ruby does not use it
// at the moment
importMapping.clear();
@@ -114,7 +112,6 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
itr.remove();
}
}
cliOptions.add(new CliOption(GEM_NAME, "gem name (convention: underscore_case).").
defaultValue("openapi_client"));
cliOptions.add(new CliOption(MODULE_NAME, "top module name (convention: CamelCase, usually corresponding" +

View File

@@ -222,12 +222,12 @@ public class Swift3Codegen extends DefaultCodegen implements CodegenConfig {
@Override
public String getName() {
return "swift3-deprecated";
return "swift3";
}
@Override
public String getHelp() {
return "Generates a Swift 3.x client library. IMPORTANT NOTE: this generator (swfit 3.x) is no longer actively maintained so please use 'swift4' generator instead.";
return "Generates a Swift 3.x client library.";
}
@Override

View File

@@ -82,7 +82,7 @@ public class SwiftClientCodegen extends DefaultCodegen implements CodegenConfig
@Override
public String getHelp() {
return "Generates a Swift (2.x) client library. IMPORTANT NOTE: this generator (swfit 2.x) is no longer actively maintained so please use 'swift4' generator instead.";
return "Generates a Swift (2.x) client library. IMPORTANT NOTE: this generator (swfit 2.x) is no longer actively maintained so please use 'swift3' or 'swift4' generator instead.";
}
public SwiftClientCodegen() {

View File

@@ -61,16 +61,6 @@ import java.util.stream.Collectors;
public class ModelUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(ModelUtils.class);
private static boolean generateAliasAsModel = false;
public static void setGenerateAliasAsModel(boolean value) {
generateAliasAsModel = value;
}
public static boolean isGenerateAliasAsModel() {
return generateAliasAsModel;
}
/**
* Searches for the model by name in the map of models and returns it
@@ -779,23 +769,15 @@ public class ModelUtils {
// top-level enum class
return schema;
} else if (isArraySchema(ref)) {
if (generateAliasAsModel) {
return schema; // generate a model extending array
} else {
return unaliasSchema(allSchemas, allSchemas.get(ModelUtils.getSimpleRef(schema.get$ref())));
}
return unaliasSchema(allSchemas, allSchemas.get(ModelUtils.getSimpleRef(schema.get$ref())));
} else if (isComposedSchema(ref)) {
return schema;
} else if (isMapSchema(ref)) {
if (ref.getProperties() != null && !ref.getProperties().isEmpty()) // has at least one property
return schema; // treat it as model
else {
if (generateAliasAsModel) {
return schema; // generate a model extending map
} else {
// treat it as a typical map
return unaliasSchema(allSchemas, allSchemas.get(ModelUtils.getSimpleRef(schema.get$ref())));
}
// treat it as a typical map
return unaliasSchema(allSchemas, allSchemas.get(ModelUtils.getSimpleRef(schema.get$ref())));
}
} else if (isObjectSchema(ref)) { // model
if (ref.getProperties() != null && !ref.getProperties().isEmpty()) { // has at least one property
@@ -895,35 +877,6 @@ public class ModelUtils {
return null;
}
public static List<String> getAllParentsName(ComposedSchema composedSchema, Map<String, Schema> allSchemas) {
List<Schema> interfaces = getInterfaces(composedSchema);
List<String> names = new ArrayList<String>();
if (interfaces != null && !interfaces.isEmpty()) {
for (Schema schema : interfaces) {
// get the actual schema
if (StringUtils.isNotEmpty(schema.get$ref())) {
String parentName = getSimpleRef(schema.get$ref());
Schema s = allSchemas.get(parentName);
if (s == null) {
LOGGER.error("Failed to obtain schema from {}", parentName);
names.add("UNKNOWN_PARENT_NAME");
} else if (s.getDiscriminator() != null && StringUtils.isNotEmpty(s.getDiscriminator().getPropertyName())) {
// discriminator.propertyName is used
names.add(parentName);
} else {
LOGGER.debug("Not a parent since discriminator.propertyName is not set {}", s.get$ref());
// not a parent since discriminator.propertyName is not set
}
} else {
// not a ref, doing nothing
}
}
}
return names;
}
public static boolean isNullable(Schema schema) {
if (schema == null) {
return false;

View File

@@ -1,37 +0,0 @@
package org.openapitools.codegen.utils;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenProperty;
import java.util.List;
import java.util.Map;
public class ProcessUtils {
/**
* Add x-index extension to the model's properties
*
* @param models List of models
*/
public static void addIndexToProperties(List<Object> models) {
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
int i = 0;
for (CodegenProperty var : cm.vars) {
var.vendorExtensions.put("x-index", i);
i++;
}
int j = 0;
for (CodegenProperty var : cm.allVars) {
var.vendorExtensions.put("x-index", j);
j++;
}
}
}
}

View File

@@ -310,9 +310,7 @@
{{/returnContainer}}
//return type
{{/returnTypeIsPrimitive}}
if (apiClient->dataReceived) {
free(apiClient->dataReceived);
}
apiClient_free(apiClient);
{{#hasQueryParams}}list_free(localVarQueryParameters);{{/hasQueryParams}}
{{#hasHeaderParams}}list_free(localVarHeaderParameters);{{/hasHeaderParams}}
{{#hasFormParams}}list_free(localVarFormParameters);{{/hasFormParams}}
@@ -382,10 +380,7 @@ end:
{{/returnType}}
{{^returnType}}
//No return type
end:
if (apiClient->dataReceived) {
free(apiClient->dataReceived);
}
end: apiClient_free(apiClient);
{{#hasQueryParams}}list_free(localVarQueryParameters);{{/hasQueryParams}}
{{#hasHeaderParams}}list_free(localVarHeaderParameters);{{/hasHeaderParams}}
{{#hasFormParams}}list_free(localVarFormParameters);{{/hasFormParams}}

View File

@@ -12,48 +12,20 @@ apiClient_t *apiClient_create() {
apiClient->basePath = "{{{basePath}}}";
apiClient->dataReceived = NULL;
apiClient->response_code = 0;
{{#hasAuthMethods}}
{{#authMethods}}
{{#isBasic}}
#ifdef BASIC_AUTH
apiClient->username = NULL;
apiClient->password = NULL;
{{/isBasic}}
{{#isOAuth}}
#endif // BASIC_AUTH
#ifdef OAUTH2
apiClient->accessToken = NULL;
{{/isOAuth}}
{{#isApiKey}}
apiClient->apiKeys = NULL;
{{/isApiKey}}
{{/authMethods}}
{{/hasAuthMethods}}
#endif // OAUTH2
return apiClient;
}
void apiClient_free(apiClient_t *apiClient) {
if(apiClient->basePath) {
free(apiClient->basePath);
if(apiClient->dataReceived) {
free(apiClient->dataReceived);
}
{{#hasAuthMethods}}
{{#authMethods}}
{{#isBasic}}
if(apiClient->username) {
free(apiClient->username);
}
if(apiClient->password) {
free(apiClient->password);
}
{{/isBasic}}
{{#isOAuth}}
if(apiClient->accessToken) {
free(apiClient->accessToken);
}
{{/isOAuth}}
{{#isApiKey}}
list_free(apiClient->apiKeys);
{{/isApiKey}}
{{/authMethods}}
{{/hasAuthMethods}}
free(apiClient);
curl_global_cleanup();
}
@@ -282,9 +254,11 @@ void apiClient_invoke(apiClient_t *apiClient,
if(strcmp(keyValuePair->key,
"file") == 0)
{
printf("Size of fileVar - %p\n",fileVar);
memcpy(&fileVar,
keyValuePair->value,
sizeof(fileVar));
printf("Size of fileVar1 - %p\n",fileVar);
curl_mime_data(part,
fileVar->fileData,
fileVar->fileSize);
@@ -313,12 +287,8 @@ void apiClient_invoke(apiClient_t *apiClient,
free(headerValueToWrite);
}
}
{{#hasAuthMethods}}
{{#authMethods}}
{{#isApiKey}}
// this would only be generated for apiKey authentication
if (apiClient->apiKeys != NULL)
{
#ifdef API_KEY
list_ForEach(listEntry, apiClient->apiKeys) {
keyValuePair_t *apiKey = listEntry->data;
if((apiKey->key != NULL) &&
@@ -330,10 +300,7 @@ void apiClient_invoke(apiClient_t *apiClient,
free(headerValueToWrite);
}
}
}
{{/isApiKey}}
{{/authMethods}}
{{/hasAuthMethods}}
#endif // API_KEY
char *targetUrl =
assembleTargetUrl(apiClient->basePath,
@@ -349,11 +316,19 @@ void apiClient_invoke(apiClient_t *apiClient,
&apiClient->dataReceived);
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(handle, CURLOPT_VERBOSE, 0); // to get curl debug msg 0: to disable, 1L:to enable
// this would only be generated for OAuth2 authentication
#ifdef OAUTH2
if(apiClient->accessToken != NULL) {
// curl_easy_setopt(handle, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);
curl_easy_setopt(handle,
CURLOPT_XOAUTH2_BEARER,
apiClient->accessToken);
}
#endif
{{#hasAuthMethods}}
{{#authMethods}}
{{#isBasic}}
// this would only be generated for basic authentication:
#ifdef BASIC_AUTH
char *authenticationToken;
if((apiClient->username != NULL) &&
@@ -376,18 +351,8 @@ void apiClient_invoke(apiClient_t *apiClient,
CURLOPT_USERPWD,
authenticationToken);
}
{{/isBasic}}
{{#isOAuth}}
// this would only be generated for OAuth2 authentication
if(apiClient->accessToken != NULL) {
// curl_easy_setopt(handle, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);
curl_easy_setopt(handle,
CURLOPT_XOAUTH2_BEARER,
apiClient->accessToken);
}
{{/isOAuth}}
{{/authMethods}}
{{/hasAuthMethods}}
#endif // BASIC_AUTH
if(bodyParameters != NULL) {
postData(handle, bodyParameters);
@@ -406,27 +371,16 @@ void apiClient_invoke(apiClient_t *apiClient,
if(res == CURLE_OK) {
curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &apiClient->response_code);
} else {
char *url,*ip,*scheme;
long port;
curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &url);
curl_easy_getinfo(handle, CURLINFO_PRIMARY_IP, &ip);
curl_easy_getinfo(handle, CURLINFO_PRIMARY_PORT, &port);
curl_easy_getinfo(handle, CURLINFO_SCHEME, &scheme);
fprintf(stderr, "curl_easy_perform() failed\n\nURL: %s\nIP: %s\nPORT: %li\nSCHEME: %s\nStrERROR: %s\n",url,ip,port,scheme,
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
{{#hasAuthMethods}}
{{#authMethods}}
{{#isBasic}}
#ifdef BASIC_AUTH
if((apiClient->username != NULL) &&
(apiClient->password != NULL) )
{
free(authenticationToken);
}
{{/isBasic}}
{{/authMethods}}
{{/hasAuthMethods}}
#endif // BASIC_AUTH
curl_easy_cleanup(handle);
if(formParameters != NULL) {
free(formString);

View File

@@ -12,20 +12,19 @@ typedef struct apiClient_t {
char *basePath;
void *dataReceived;
long response_code;
{{#hasAuthMethods}}
{{#authMethods}}
{{#isBasic}}
// this would only be generated for basic authentication
#ifdef BASIC_AUTH
char *username;
char *password;
{{/isBasic}}
{{#isOAuth}}
#endif // BASIC_AUTH
// this would only be generated for OAUTH2 authentication
#ifdef OAUTH2
char *accessToken;
{{/isOAuth}}
{{#isApiKey}}
#endif // OAUTH2
#ifdef API_KEY
//this would only be generated for apiKey authentication
list_t *apiKeys;
{{/isApiKey}}
{{/authMethods}}
{{/hasAuthMethods}}
#endif // API_KEY
} apiClient_t;
typedef struct FileStruct

View File

@@ -6,7 +6,6 @@ version = '{{artifactVersion}}'
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
@@ -16,7 +15,6 @@ buildscript {
}
repositories {
mavenCentral()
jcenter()
}

View File

@@ -6,7 +6,6 @@ version = '{{artifactVersion}}'
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
@@ -121,7 +120,7 @@ if(hasProperty('target') && target == 'android') {
ext {
swagger_annotations_version = "1.5.21"
jackson_version = "2.8.11"
jackson_databind_version = "2.8.11.3"
jackson_databind_version = "2.8.11.2"
{{#threetenbp}}
threepane_version = "2.6.4"
{{/threetenbp}}

View File

@@ -16,7 +16,7 @@ lazy val root = (project in file(".")).
"io.github.openfeign.form" % "feign-form" % "2.1.0" % "compile",
"com.fasterxml.jackson.core" % "jackson-core" % "2.8.11" % "compile",
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.8.11" % "compile",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.11.3" % "compile",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.11.2" % "compile",
"com.fasterxml.jackson.datatype" % "jackson-datatype-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}}" % "2.8.7" % "compile",
"com.github.joschi.jackson" % "jackson-datatype-threetenbp" % "2.6.4" % "compile",
"org.apache.oltu.oauth2" % "org.apache.oltu.oauth2.client" % "1.0.1" % "compile",

View File

@@ -303,7 +303,7 @@
<feign-version>{{#useFeign10}}10.0.1{{/useFeign10}}{{^useFeign10}}9.4.0{{/useFeign10}}</feign-version>
<feign-form-version>2.1.0</feign-form-version>
<jackson-version>2.8.11</jackson-version>
<jackson-databind-version>2.8.11.3</jackson-databind-version>
<jackson-databind-version>2.8.11.2</jackson-databind-version>
{{#threetenbp}}
<jackson-threetenbp-version>2.6.4</jackson-threetenbp-version>
{{/threetenbp}}

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