Permalink
Browse files

Better OpenAPI spec v3 support: allOf, anyOf, oneOf (#1360)

* add oneOf support to Ruby

* add anyOf support to ruby client

* add discriminator support to ruby client

* fix typo

* update samples, fix NPE

* better format in ruby generator

* fix test cases, disable mapping test

* fix update script, update samples

* add test, fix mapping

* update exit code

* reenabled discriminator test

* remove duplicated properties

* add test for duplicated properties

* update samples, add new spec

* fix ruby test cases

* fix hasMore after removing duplicates

* refactor method, comment out haskell client test

* fix hasMore and update samples

* fix parent detection

* fix discriminator check

* [haskell-http-client] need to use {{vars}}{{required}} instead of {{requiredVars}}

* remove deprecated methods in default codegen (#1031)

* regenerate samples

* remove commented code
  • Loading branch information...
wing328 committed Dec 6, 2018
1 parent c0634ac commit 774013c7e19bdd9cc7ff02d5abdf9453c7838d1f
Showing with 1,108 additions and 327 deletions.
  1. +3 −0 .gitignore
  2. +11 −0 modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenDiscriminator.java
  3. +76 −15 modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenModel.java
  4. +4 −5 modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java
  5. +106 −68 modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
  6. +10 −1 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RubyClientCodegen.java
  7. +56 −1 modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java
  8. +4 −4 modules/openapi-generator/src/main/resources/haskell-http-client/Model.mustache
  9. +5 −2 modules/openapi-generator/src/main/resources/ruby-client/base_object.mustache
  10. +96 −5 modules/openapi-generator/src/main/resources/ruby-client/partial_model_generic.mustache
  11. +21 −21 modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java
  12. +7 −5 modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaInheritanceTest.java
  13. +7 −5 modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaModelEnumTest.java
  14. +1 −3 modules/openapi-generator/src/test/java/org/openapitools/codegen/objc/ObjcModelTest.java
  15. +108 −1 modules/openapi-generator/src/test/java/org/openapitools/codegen/ruby/RubyClientCodegenTest.java
  16. +47 −0 modules/openapi-generator/src/test/resources/3_0/allOfDuplicatedProperties.yaml
  17. +84 −0 modules/openapi-generator/src/test/resources/3_0/allOfMappingDuplicatedProperties.yaml
  18. +64 −0 modules/openapi-generator/src/test/resources/3_0/anyOf.yaml
  19. +64 −0 modules/openapi-generator/src/test/resources/3_0/oneOf.yaml
  20. +1 −1 samples/client/petstore/csharp/OpenAPIClient/docs/EnumTest.md
  21. +6 −6 samples/client/petstore/csharp/OpenAPIClient/src/Org.OpenAPITools/Model/EnumTest.cs
  22. +1 −1 samples/client/petstore/go/go-petstore/docs/Cat.md
  23. +1 −1 samples/client/petstore/go/go-petstore/docs/Dog.md
  24. +1 −1 samples/client/petstore/go/go-petstore/model_cat.go
  25. +1 −1 samples/client/petstore/go/go-petstore/model_dog.go
  26. +17 −16 samples/client/petstore/haskell-http-client/lib/OpenAPIPetstore/Model.hs
  27. +10 −10 samples/client/petstore/haskell-http-client/lib/OpenAPIPetstore/ModelLens.hs
  28. +4 −4 samples/client/petstore/haskell-http-client/tests/Instances.hs
  29. +0 −2 samples/client/petstore/java/google-api-client/docs/MapTest.md
  30. +0 −2 samples/client/petstore/java/jersey1/docs/MapTest.md
  31. +0 −2 samples/client/petstore/java/jersey2-java6/docs/MapTest.md
  32. +0 −2 samples/client/petstore/java/jersey2-java8/docs/MapTest.md
  33. +0 −2 samples/client/petstore/java/jersey2/docs/MapTest.md
  34. +0 −2 samples/client/petstore/java/okhttp-gson-parcelableModel/docs/MapTest.md
  35. +0 −2 samples/client/petstore/java/okhttp-gson/docs/MapTest.md
  36. +0 −2 samples/client/petstore/java/rest-assured/docs/MapTest.md
  37. +0 −2 samples/client/petstore/java/resteasy/docs/MapTest.md
  38. +0 −2 samples/client/petstore/java/resttemplate-withXml/docs/MapTest.md
  39. +0 −2 samples/client/petstore/java/resttemplate/docs/MapTest.md
  40. +0 −2 samples/client/petstore/java/retrofit2-play24/docs/MapTest.md
  41. +0 −2 samples/client/petstore/java/retrofit2-play25/docs/MapTest.md
  42. +0 −2 samples/client/petstore/java/retrofit2-play26/docs/MapTest.md
  43. +0 −2 samples/client/petstore/java/retrofit2/docs/MapTest.md
  44. +0 −2 samples/client/petstore/java/retrofit2rx/docs/MapTest.md
  45. +0 −2 samples/client/petstore/java/retrofit2rx2/docs/MapTest.md
  46. +0 −2 samples/client/petstore/java/vertx/docs/MapTest.md
  47. +0 −2 samples/client/petstore/java/webclient/docs/MapTest.md
  48. +1 −4 samples/client/petstore/php/OpenAPIClient-php/lib/Model/MapTest.php
  49. +1 −1 samples/client/petstore/ruby/docs/Cat.md
  50. +1 −1 samples/client/petstore/ruby/docs/Dog.md
  51. +2 −0 samples/client/petstore/ruby/lib/petstore/models/additional_properties_class.rb
  52. +7 −0 samples/client/petstore/ruby/lib/petstore/models/animal.rb
  53. +2 −0 samples/client/petstore/ruby/lib/petstore/models/api_response.rb
  54. +2 −0 samples/client/petstore/ruby/lib/petstore/models/array_of_array_of_number_only.rb
  55. +2 −0 samples/client/petstore/ruby/lib/petstore/models/array_of_number_only.rb
  56. +2 −0 samples/client/petstore/ruby/lib/petstore/models/array_test.rb
  57. +2 −0 samples/client/petstore/ruby/lib/petstore/models/capitalization.rb
  58. +30 −17 samples/client/petstore/ruby/lib/petstore/models/cat.rb
  59. +2 −0 samples/client/petstore/ruby/lib/petstore/models/category.rb
  60. +2 −0 samples/client/petstore/ruby/lib/petstore/models/class_model.rb
  61. +2 −0 samples/client/petstore/ruby/lib/petstore/models/client.rb
  62. +30 −17 samples/client/petstore/ruby/lib/petstore/models/dog.rb
  63. +2 −0 samples/client/petstore/ruby/lib/petstore/models/enum_arrays.rb
  64. +2 −0 samples/client/petstore/ruby/lib/petstore/models/enum_test.rb
  65. +2 −0 samples/client/petstore/ruby/lib/petstore/models/file.rb
  66. +2 −0 samples/client/petstore/ruby/lib/petstore/models/file_schema_test_class.rb
  67. +2 −0 samples/client/petstore/ruby/lib/petstore/models/format_test.rb
  68. +2 −0 samples/client/petstore/ruby/lib/petstore/models/has_only_read_only.rb
  69. +2 −0 samples/client/petstore/ruby/lib/petstore/models/list.rb
  70. +2 −0 samples/client/petstore/ruby/lib/petstore/models/map_test.rb
  71. +2 −0 samples/client/petstore/ruby/lib/petstore/models/mixed_properties_and_additional_properties_class.rb
  72. +2 −0 samples/client/petstore/ruby/lib/petstore/models/model200_response.rb
  73. +2 −0 samples/client/petstore/ruby/lib/petstore/models/model_return.rb
  74. +2 −0 samples/client/petstore/ruby/lib/petstore/models/name.rb
  75. +2 −0 samples/client/petstore/ruby/lib/petstore/models/number_only.rb
  76. +2 −0 samples/client/petstore/ruby/lib/petstore/models/order.rb
  77. +2 −0 samples/client/petstore/ruby/lib/petstore/models/outer_composite.rb
  78. +2 −0 samples/client/petstore/ruby/lib/petstore/models/pet.rb
  79. +2 −0 samples/client/petstore/ruby/lib/petstore/models/read_only_first.rb
  80. +2 −0 samples/client/petstore/ruby/lib/petstore/models/special_model_name.rb
  81. +2 −0 samples/client/petstore/ruby/lib/petstore/models/tag.rb
  82. +2 −0 samples/client/petstore/ruby/lib/petstore/models/user.rb
  83. +1 −4 samples/openapi3/client/petstore/php/OpenAPIClient-php/lib/Model/MapTest.php
  84. +1 −1 samples/openapi3/client/petstore/ruby/docs/Cat.md
  85. +1 −1 samples/openapi3/client/petstore/ruby/docs/Dog.md
  86. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/additional_properties_class.rb
  87. +7 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/animal.rb
  88. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/api_response.rb
  89. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/array_of_array_of_number_only.rb
  90. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/array_of_number_only.rb
  91. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/array_test.rb
  92. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/capitalization.rb
  93. +30 −17 samples/openapi3/client/petstore/ruby/lib/petstore/models/cat.rb
  94. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/category.rb
  95. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/class_model.rb
  96. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/client.rb
  97. +30 −17 samples/openapi3/client/petstore/ruby/lib/petstore/models/dog.rb
  98. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/enum_arrays.rb
  99. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/enum_test.rb
  100. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/file.rb
  101. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/file_schema_test_class.rb
  102. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/foo.rb
  103. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/format_test.rb
  104. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/has_only_read_only.rb
  105. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/inline_response_default.rb
  106. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/list.rb
  107. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/map_test.rb
  108. +2 −0 ...api3/client/petstore/ruby/lib/petstore/models/mixed_properties_and_additional_properties_class.rb
  109. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/model200_response.rb
  110. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/model_return.rb
  111. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/name.rb
  112. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/number_only.rb
  113. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/order.rb
  114. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/outer_composite.rb
  115. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/pet.rb
  116. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/read_only_first.rb
  117. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/special_model_name.rb
  118. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/tag.rb
  119. +2 −0 samples/openapi3/client/petstore/ruby/lib/petstore/models/user.rb
  120. +4 −4 samples/schema/petstore/mysql/mysql_schema.sql
  121. +3 −3 samples/server/petstore/php-slim/lib/Model/Cat.php
  122. +3 −3 samples/server/petstore/php-slim/lib/Model/Dog.php
  123. +6 −6 samples/server/petstore/php-ze-ph/src/App/DTO/Cat.php
  124. +6 −6 samples/server/petstore/php-ze-ph/src/App/DTO/Dog.php
  125. +10 −10 .../server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/models.rs
@@ -184,6 +184,9 @@ samples/server/petstore/kotlin-server/ktor/build
.stack-work
.cabal-sandbox
cabal.project.local
samples/client/petstore/haskell-http-client/docs/haddock-bundle.min.js
samples/client/petstore/haskell-http-client/docs/meta.json
samples/client/petstore/haskell-http-client/docs/quick-jump.css
# R
.Rproj.user
@@ -1,5 +1,7 @@
package org.openapitools.codegen;
import org.apache.commons.lang3.builder.ToStringBuilder;
import java.util.*;
public class CodegenDiscriminator {
@@ -85,4 +87,13 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hash(propertyName, mapping, mappedModels);
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("propertyName", propertyName)
.append("mapping", mapping)
.append("mappedModels", mappedModels)
.toString();
}
}
@@ -19,14 +19,7 @@
import io.swagger.v3.oas.models.ExternalDocumentation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.*;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@@ -40,6 +33,11 @@
public List<CodegenModel> interfaceModels;
public List<CodegenModel> children;
// anyOf, oneOf, allOf
public Set<String> anyOf = new TreeSet<String>();
public Set<String> oneOf = new TreeSet<String>();
public Set<String> allOf = new TreeSet<String>();
public String name, classname, title, description, classVarName, modelJson, dataType, xmlPrefix, xmlNamespace, xmlName;
public String classFilename; // store the class file name, mainly used for import
public String unescapedDescription;
@@ -53,8 +51,8 @@
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;
public List<CodegenProperty> parentVars = new ArrayList<>();
public List<CodegenProperty> allVars = new ArrayList<CodegenProperty>();
public List<CodegenProperty> parentVars = new ArrayList<CodegenProperty>();
public Map<String, Object> allowableValues;
// Sorted sets of required parameters.
@@ -195,11 +193,11 @@ public int hashCode() {
result = 31 * result + (mandatory != null ? mandatory.hashCode() : 0);
result = 31 * result + (allMandatory != null ? allMandatory.hashCode() : 0);
result = 31 * result + (imports != null ? imports.hashCode() : 0);
result = 31 * result + (hasVars ? 13:31);
result = 31 * result + (emptyVars ? 13:31);
result = 31 * result + (hasMoreModels ? 13:31);
result = 31 * result + (hasEnums ? 13:31);
result = 31 * result + (isEnum ? 13:31);
result = 31 * result + (hasVars ? 13 : 31);
result = 31 * result + (emptyVars ? 13 : 31);
result = 31 * result + (hasMoreModels ? 13 : 31);
result = 31 * result + (hasEnums ? 13 : 31);
result = 31 * result + (isEnum ? 13 : 31);
result = 31 * result + (externalDocumentation != null ? externalDocumentation.hashCode() : 0);
result = 31 * result + (vendorExtensions != null ? vendorExtensions.hashCode() : 0);
result = 31 * result + Objects.hash(hasOnlyReadOnly);
@@ -499,4 +497,67 @@ public String getAdditionalPropertiesType() {
public void setAdditionalPropertiesType(String additionalPropertiesType) {
this.additionalPropertiesType = additionalPropertiesType;
}
/**
* Remove duplicated properties in all variable list and update "hasMore"
*/
public void removeAllDuplicatedProperty() {
// remove duplicated properties
vars = removeDuplicatedProperty(vars);
optionalVars = removeDuplicatedProperty(optionalVars);
requiredVars = removeDuplicatedProperty(requiredVars);
parentVars = removeDuplicatedProperty(parentVars);
allVars = removeDuplicatedProperty(allVars);
readOnlyVars = removeDuplicatedProperty(readOnlyVars);
readWriteVars = removeDuplicatedProperty(readWriteVars);
// update property list's "hasMore"
updatePropertyListHasMore(vars);
updatePropertyListHasMore(optionalVars);
updatePropertyListHasMore(requiredVars);
updatePropertyListHasMore(parentVars);
updatePropertyListHasMore(allVars);
updatePropertyListHasMore(readOnlyVars);
updatePropertyListHasMore(readWriteVars);
}
private List<CodegenProperty> removeDuplicatedProperty(List<CodegenProperty> vars) {
// clone the list first
List<CodegenProperty> newList = new ArrayList<CodegenProperty>();
for (CodegenProperty cp : vars) {
newList.add(cp.clone());
}
Set<String> propertyNames = new TreeSet<String>();
Set<String> duplicatedNames = new TreeSet<String>();
ListIterator<CodegenProperty> iterator = newList.listIterator();
while (iterator.hasNext()) {
CodegenProperty element = iterator.next();
if (propertyNames.contains(element.baseName)) {
duplicatedNames.add(element.baseName);
iterator.remove();
} else {
propertyNames.add(element.baseName);
}
}
return newList;
}
/**
* Clone the element and update "hasMore" in the list of codegen properties
*/
private void updatePropertyListHasMore(List<CodegenProperty> vars) {
if (vars != null) {
for (int i = 0; i < vars.size(); i++) {
if (i < vars.size() - 1) {
vars.get(i).hasMore = true;
} else { // last element
vars.get(i).hasMore = false;
}
}
}
}
}
@@ -17,11 +17,7 @@
package org.openapitools.codegen;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
public class CodegenProperty implements Cloneable {
public String baseName, complexType, getter, setter, description, dataType,
@@ -733,6 +729,7 @@ public CodegenProperty clone() {
if (this.vendorExtensions != null) {
cp.vendorExtensions = new HashMap<String, Object>(this.vendorExtensions);
}
return cp;
} catch (CloneNotSupportedException e) {
throw new IllegalStateException(e);
@@ -817,4 +814,6 @@ public CodegenProperty clone() {
", isXmlWrapped=" + isXmlWrapped +
'}';
}
}
Oops, something went wrong.

0 comments on commit 774013c

Please sign in to comment.