Skip to content

Commit edf153e

Browse files
authored
[Java][Native] Support oneOf/anyOf schemas (#7263)
* Java-native add models of oneOf/anyOf * Java-native refresh samples * Java-native add a sample project for openapi3
1 parent f76d72e commit edf153e

File tree

494 files changed

+39916
-759
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

494 files changed

+39916
-759
lines changed

bin/configs/java-native-openapi3.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
generatorName: java
2+
outputDir: samples/openapi3/client/petstore/java/native
3+
library: native
4+
inputSpec: modules/openapi-generator/src/test/resources/3_0/java/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml
5+
templateDir: modules/openapi-generator/src/main/resources/Java
6+
additionalProperties:
7+
artifactId: petstore-openapi3-native
8+
hideGenerationTimestamp: true
9+
serverPort: "8082"
10+
useOneOfDiscriminatorLookup: true
11+
disallowAdditionalPropertiesIfNotPresent: false

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,8 @@ public void processOpts() {
418418
setJava8Mode(true);
419419
additionalProperties.put("java8", "true");
420420
supportingFiles.add(new SupportingFile("ApiResponse.mustache", invokerFolder, "ApiResponse.java"));
421+
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
422+
supportingFiles.add(new SupportingFile("AbstractOpenApiSchema.mustache", (sourceFolder + File.separator + modelPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar), "AbstractOpenApiSchema.java"));
421423
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
422424
} else if (RESTEASY.equals(getLibrary())) {
423425
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
@@ -536,8 +538,8 @@ public void processOpts() {
536538
if (SERIALIZATION_LIBRARY_JACKSON.equals(getSerializationLibrary())) {
537539
additionalProperties.put(SERIALIZATION_LIBRARY_JACKSON, "true");
538540
additionalProperties.remove(SERIALIZATION_LIBRARY_GSON);
541+
supportingFiles.add(new SupportingFile("RFC3339DateFormat.mustache", invokerFolder, "RFC3339DateFormat.java"));
539542
if (!NATIVE.equals(getLibrary())) {
540-
supportingFiles.add(new SupportingFile("RFC3339DateFormat.mustache", invokerFolder, "RFC3339DateFormat.java"));
541543
if ("threetenbp".equals(dateLibrary) && !usePlayWS) {
542544
supportingFiles.add(new SupportingFile("CustomInstantDeserializer.mustache", invokerFolder, "CustomInstantDeserializer.java"));
543545
}
@@ -822,7 +824,6 @@ public Map<String, Object> postProcessModels(Map<String, Object> objs) {
822824
imports2Classnames.put("JsonNullable", "org.openapitools.jackson.nullable.JsonNullable");
823825
imports2Classnames.put("NoSuchElementException", "java.util.NoSuchElementException");
824826
imports2Classnames.put("JsonIgnore", "com.fasterxml.jackson.annotation.JsonIgnore");
825-
826827
for (Map.Entry<String, String> entry : imports2Classnames.entrySet()) {
827828
cm.imports.add(entry.getKey());
828829
Map<String, String> importsItem = new HashMap<String, String>();
@@ -838,7 +839,7 @@ public Map<String, Object> postProcessModels(Map<String, Object> objs) {
838839
CodegenModel cm = (CodegenModel) mo.get("model");
839840

840841
cm.getVendorExtensions().putIfAbsent("x-implements", new ArrayList<String>());
841-
if (JERSEY2.equals(getLibrary())) {
842+
if (JERSEY2.equals(getLibrary()) || NATIVE.equals(getLibrary())) {
842843
cm.getVendorExtensions().put("x-implements", new ArrayList<String>());
843844

844845
if (cm.oneOf != null && !cm.oneOf.isEmpty() && cm.oneOf.contains("ModelNull")) {
@@ -978,7 +979,6 @@ public void addImportsToOneOfInterface(List<Map<String, String>> imports) {
978979
for (String i : Arrays.asList("JsonSubTypes", "JsonTypeInfo")) {
979980
Map<String, String> oneImport = new HashMap<>();
980981
oneImport.put("import", importMapping.get(i));
981-
982982
if (!imports.contains(oneImport)) {
983983
imports.add(oneImport);
984984
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
{{>licenseInfo}}
2+
3+
package {{invokerPackage}}.model;
4+
5+
import {{invokerPackage}}.ApiException;
6+
import java.util.Objects;
7+
import java.lang.reflect.Type;
8+
import java.util.Map;
9+
import javax.ws.rs.core.GenericType;
10+
11+
import com.fasterxml.jackson.annotation.JsonValue;
12+
13+
/**
14+
* Abstract class for oneOf,anyOf schemas defined in OpenAPI spec
15+
*/
16+
{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}
17+
public abstract class AbstractOpenApiSchema {
18+
19+
// store the actual instance of the schema/object
20+
private Object instance;
21+
22+
// is nullable
23+
private Boolean isNullable;
24+
25+
// schema type (e.g. oneOf, anyOf)
26+
private final String schemaType;
27+
28+
public AbstractOpenApiSchema(String schemaType, Boolean isNullable) {
29+
this.schemaType = schemaType;
30+
this.isNullable = isNullable;
31+
}
32+
33+
/**
34+
* Get the list of oneOf/anyOf composed schemas allowed to be stored in this object
35+
*
36+
* @return an instance of the actual schema/object
37+
*/
38+
public abstract Map<String, GenericType> getSchemas();
39+
40+
/**
41+
* Get the actual instance
42+
*
43+
* @return an instance of the actual schema/object
44+
*/
45+
@JsonValue
46+
public Object getActualInstance() {return instance;}
47+
48+
/**
49+
* Set the actual instance
50+
*
51+
* @param instance the actual instance of the schema/object
52+
*/
53+
public void setActualInstance(Object instance) {this.instance = instance;}
54+
55+
/**
56+
* Get the instant recursively when the schemas defined in oneOf/anyof happen to be oneOf/anyOf schema as well
57+
*
58+
* @return an instance of the actual schema/object
59+
*/
60+
public Object getActualInstanceRecursively() {
61+
return getActualInstanceRecursively(this);
62+
}
63+
64+
private Object getActualInstanceRecursively(AbstractOpenApiSchema object) {
65+
if (object.getActualInstance() == null) {
66+
return null;
67+
} else if (object.getActualInstance() instanceof AbstractOpenApiSchema) {
68+
return getActualInstanceRecursively((AbstractOpenApiSchema)object.getActualInstance());
69+
} else {
70+
return object.getActualInstance();
71+
}
72+
}
73+
74+
/**
75+
* Get the schema type (e.g. anyOf, oneOf)
76+
*
77+
* @return the schema type
78+
*/
79+
public String getSchemaType() {
80+
return schemaType;
81+
}
82+
83+
@Override
84+
public String toString() {
85+
StringBuilder sb = new StringBuilder();
86+
sb.append("class ").append(getClass()).append(" {\n");
87+
sb.append(" instance: ").append(toIndentedString(instance)).append("\n");
88+
sb.append(" isNullable: ").append(toIndentedString(isNullable)).append("\n");
89+
sb.append(" schemaType: ").append(toIndentedString(schemaType)).append("\n");
90+
sb.append("}");
91+
return sb.toString();
92+
}
93+
94+
/**
95+
* Convert the given object to string with each line indented by 4 spaces
96+
* (except the first line).
97+
*/
98+
private String toIndentedString(Object o) {
99+
if (o == null) {
100+
return "null";
101+
}
102+
return o.toString().replace("\n", "\n ");
103+
}
104+
105+
public boolean equals(Object o) {
106+
if (this == o) {
107+
return true;
108+
}
109+
if (o == null || getClass() != o.getClass()) {
110+
return false;
111+
}
112+
AbstractOpenApiSchema a = (AbstractOpenApiSchema) o;
113+
return Objects.equals(this.instance, a.instance) &&
114+
Objects.equals(this.isNullable, a.isNullable) &&
115+
Objects.equals(this.schemaType, a.schemaType);
116+
}
117+
118+
@Override
119+
public int hashCode() {
120+
return Objects.hash(instance, isNullable, schemaType);
121+
}
122+
123+
/**
124+
* Is nullalble
125+
*
126+
* @return true if it's nullable
127+
*/
128+
public Boolean isNullable() {
129+
if (Boolean.TRUE.equals(isNullable)) {
130+
return Boolean.TRUE;
131+
} else {
132+
return Boolean.FALSE;
133+
}
134+
}
135+
136+
{{>libraries/native/additional_properties}}
137+
138+
}

modules/openapi-generator/src/main/resources/Java/libraries/native/ApiResponse.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ package {{invokerPackage}};
55
import java.util.List;
66
import java.util.Map;
77
{{#caseInsensitiveResponseHeaders}}
8-
import java.util.Map.Entry;
8+
import java.util.Map.Entry;
99
import java.util.TreeMap;
1010
{{/caseInsensitiveResponseHeaders}}
1111

0 commit comments

Comments
 (0)