diff --git a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ConfigHelp.java b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ConfigHelp.java index 29247f4256d..57734c781d4 100644 --- a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ConfigHelp.java +++ b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ConfigHelp.java @@ -71,6 +71,9 @@ public class ConfigHelp extends OpenApiGeneratorCommand { @Option(name = {"--import-mappings"}, title = "import mappings", description = "displays the default import mappings (types and aliases, and what imports they will pull into the template)") private Boolean importMappings; + @Option(name = {"--inline-schema-name-mappings"}, title = "inline schema name mappings", description = "displays the inline schema name mappings (none)") + private Boolean inlineSchemaNameMappings; + @Option(name = {"--metadata"}, title = "metadata", description = "displays the generator metadata like the help txt for the generator and generator type etc") private Boolean metadata; @@ -449,6 +452,18 @@ public class ConfigHelp extends OpenApiGeneratorCommand { sb.append(newline); } + if (Boolean.TRUE.equals(inlineSchemaNameMappings)) { + sb.append(newline).append("INLINE SCHEMA NAME MAPPING").append(newline).append(newline); + Map map = config.inlineSchemaNameMapping() + .entrySet() + .stream() + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> { + throw new IllegalStateException(String.format(Locale.ROOT, "Duplicated options! %s and %s", a, b)); + }, TreeMap::new)); + writePlainTextFromMap(sb, map, optIndent, optNestedIndent, "Inline scheme name", "Mapped to"); + sb.append(newline); + } + if (Boolean.TRUE.equals(instantiationTypes)) { sb.append(newline).append("INSTANTIATION TYPES").append(newline).append(newline); Map map = config.instantiationTypes() diff --git a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java index 27447fad78a..1a7495cf26f 100644 --- a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java +++ b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java @@ -159,6 +159,13 @@ public class Generate extends OpenApiGeneratorCommand { + " You can also have multiple occurrences of this option.") private List importMappings = new ArrayList<>(); + @Option( + name = {"--inline-schema-name-mappings"}, + title = "inline schema name mappings", + description = "specifies mappings between the inline schema name and the new name in the format of inline_object_2=Cat,inline_object_5=Bird." + + " You can also have multiple occurrences of this option.") + private List inlineSchemaNameMappings = new ArrayList<>(); + @Option( name = {"--server-variables"}, title = "server variables", @@ -423,6 +430,7 @@ public class Generate extends OpenApiGeneratorCommand { } applyInstantiationTypesKvpList(instantiationTypes, configurator); applyImportMappingsKvpList(importMappings, configurator); + applyInlineSchemaNameMappingsKvpList(inlineSchemaNameMappings, configurator); applyTypeMappingsKvpList(typeMappings, configurator); applyAdditionalPropertiesKvpList(additionalProperties, configurator); applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator); diff --git a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java index 8bbece6784a..0b852dfc886 100644 --- a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java +++ b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java @@ -50,6 +50,7 @@ public final class GeneratorSettings implements Serializable { private final Map typeMappings; private final Map additionalProperties; private final Map importMappings; + private final Map inlineSchemaNameMappings; private final Set languageSpecificPrimitives; private final Map reservedWordMappings; private final Map serverVariables; @@ -234,6 +235,15 @@ public final class GeneratorSettings implements Serializable { return importMappings; } + /** + * Gets inline schema name mappings between an inline schema name and the new name. + * + * @return the inline schema name mappings + */ + public Map getInlineSchemaNameMappings() { + return inlineSchemaNameMappings; + } + /** * Gets language specific primitives. These are in addition to the "base" primitives defined in a generator. *

@@ -349,6 +359,7 @@ public final class GeneratorSettings implements Serializable { instantiationTypes = Collections.unmodifiableMap(builder.instantiationTypes); typeMappings = Collections.unmodifiableMap(builder.typeMappings); importMappings = Collections.unmodifiableMap(builder.importMappings); + inlineSchemaNameMappings = Collections.unmodifiableMap(builder.inlineSchemaNameMappings); languageSpecificPrimitives = Collections.unmodifiableSet(builder.languageSpecificPrimitives); reservedWordMappings = Collections.unmodifiableMap(builder.reservedWordMappings); serverVariables = Collections.unmodifiableMap(builder.serverVariables); @@ -419,6 +430,7 @@ public final class GeneratorSettings implements Serializable { typeMappings = Collections.unmodifiableMap(new HashMap<>(0)); additionalProperties = Collections.unmodifiableMap(new HashMap<>(0)); importMappings = Collections.unmodifiableMap(new HashMap<>(0)); + inlineSchemaNameMappings = Collections.unmodifiableMap(new HashMap<>(0)); languageSpecificPrimitives = Collections.unmodifiableSet(new HashSet<>(0)); reservedWordMappings = Collections.unmodifiableMap(new HashMap<>(0)); serverVariables = Collections.unmodifiableMap(new HashMap<>(0)); @@ -470,6 +482,9 @@ public final class GeneratorSettings implements Serializable { if (copy.getImportMappings() != null) { builder.importMappings.putAll(copy.getImportMappings()); } + if (copy.getInlineSchemaNameMappings() != null) { + builder.inlineSchemaNameMappings.putAll(copy.getInlineSchemaNameMappings()); + } if (copy.getLanguageSpecificPrimitives() != null) { builder.languageSpecificPrimitives.addAll(copy.getLanguageSpecificPrimitives()); } @@ -509,6 +524,7 @@ public final class GeneratorSettings implements Serializable { private Map typeMappings; private Map additionalProperties; private Map importMappings; + private Map inlineSchemaNameMappings; private Set languageSpecificPrimitives; private Map reservedWordMappings; private Map serverVariables; @@ -526,6 +542,7 @@ public final class GeneratorSettings implements Serializable { typeMappings = new HashMap<>(); additionalProperties = new HashMap<>(); importMappings = new HashMap<>(); + inlineSchemaNameMappings = new HashMap<>(); languageSpecificPrimitives = new HashSet<>(); reservedWordMappings = new HashMap<>(); serverVariables = new HashMap<>(); @@ -768,6 +785,32 @@ public final class GeneratorSettings implements Serializable { return this; } + /** + * Sets the {@code inlineSchemaNameMappings} and returns a reference to this Builder so that the methods can be chained together. + * + * @param inlineSchemaNameMappings the {@code inlineSchemaNameMappings} to set + * @return a reference to this Builder + */ + public Builder withInlineSchemaNameMappings(Map inlineSchemaNameMappings) { + this.inlineSchemaNameMappings = inlineSchemaNameMappings; + return this; + } + + /** + * Sets a single {@code inlineSchemaNameMappings} and returns a reference to this Builder so that the methods can be chained together. + * + * @param key A key for some import mapping + * @param value The value of some import mapping + * @return a reference to this Builder + */ + public Builder withInlineSchemaNameMapping(String key, String value) { + if (this.inlineSchemaNameMappings == null) { + this.inlineSchemaNameMappings = new HashMap<>(); + } + this.inlineSchemaNameMappings.put(key, value); + return this; + } + /** * Sets the {@code languageSpecificPrimitives} and returns a reference to this Builder so that the methods can be chained together. * @@ -953,6 +996,7 @@ public final class GeneratorSettings implements Serializable { Objects.equals(getTypeMappings(), that.getTypeMappings()) && Objects.equals(getAdditionalProperties(), that.getAdditionalProperties()) && Objects.equals(getImportMappings(), that.getImportMappings()) && + Objects.equals(getInlineSchemaNameMappings(), that.getInlineSchemaNameMappings()) && Objects.equals(getLanguageSpecificPrimitives(), that.getLanguageSpecificPrimitives()) && Objects.equals(getReservedWordMappings(), that.getReservedWordMappings()) && Objects.equals(getGitHost(), that.getGitHost()) && @@ -981,6 +1025,7 @@ public final class GeneratorSettings implements Serializable { getTypeMappings(), getAdditionalProperties(), getImportMappings(), + getInlineSchemaNameMappings(), getLanguageSpecificPrimitives(), getReservedWordMappings(), getGitHost(), diff --git a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/OpenApiGeneratorPlugin.kt b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/OpenApiGeneratorPlugin.kt index 21436595abd..210fd17678c 100644 --- a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/OpenApiGeneratorPlugin.kt +++ b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/OpenApiGeneratorPlugin.kt @@ -113,6 +113,7 @@ class OpenApiGeneratorPlugin : Plugin { serverVariables.set(generate.serverVariables) languageSpecificPrimitives.set(generate.languageSpecificPrimitives) importMappings.set(generate.importMappings) + inlineSchemaNameMappings.set(generate.inlineSchemaNameMappings) invokerPackage.set(generate.invokerPackage) groupId.set(generate.groupId) id.set(generate.id) diff --git a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorGenerateExtension.kt b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorGenerateExtension.kt index 69002705d11..557f6386dc0 100644 --- a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorGenerateExtension.kt +++ b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorGenerateExtension.kt @@ -141,6 +141,11 @@ open class OpenApiGeneratorGenerateExtension(project: Project) { */ val importMappings = project.objects.mapProperty() + /** + * Specifies mappings between an inline schema name and the new name + */ + val inlineSchemaNameMappings = project.objects.mapProperty() + /** * Root package for generated code. */ diff --git a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt index cd693b17136..69cb92e4bd3 100644 --- a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt +++ b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt @@ -219,6 +219,13 @@ open class GenerateTask : DefaultTask() { @Input val importMappings = project.objects.mapProperty() + /** + * Specifies mappings between the inline scheme name and the new name + */ + @Optional + @Input + val inlineSchemaNameMappings = project.objects.mapProperty() + /** * Root package for generated code. */ @@ -678,6 +685,12 @@ open class GenerateTask : DefaultTask() { } } + if (inlineSchemaNameMappings.isPresent) { + inlineSchemaNameMappings.get().forEach { entry -> + configurator.addInlineSchemaNameMapping(entry.key, entry.value) + } + } + if (typeMappings.isPresent) { typeMappings.get().forEach { entry -> configurator.addTypeMapping(entry.key, entry.value) diff --git a/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java b/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java index 2435aab27f3..6a2234be06e 100644 --- a/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java +++ b/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java @@ -298,6 +298,12 @@ public class CodeGenMojo extends AbstractMojo { @Parameter(name = "importMappings", property = "openapi.generator.maven.plugin.importMappings") private List importMappings; + /** + * A map of inline scheme names and the new names + */ + @Parameter(name = "inlineSchemaNameMappings", property = "openapi.generator.maven.plugin.inlineSchemaNameMappings") + private List inlineSchemaNameMappings; + /** * A map of swagger spec types and the generated code types to use for them */ @@ -659,6 +665,12 @@ public class CodeGenMojo extends AbstractMojo { configurator); } + // Retained for backwards-compatibility with configOptions -> inline-schema-name-mappings + if (importMappings == null && configOptions.containsKey("inline-schema-name-mappings")) { + applyInlineSchemaNameMappingsKvp(configOptions.get("inline-schema-name-mappings").toString(), + configurator); + } + // Retained for backwards-compatibility with configOptions -> type-mappings if (typeMappings == null && configOptions.containsKey("type-mappings")) { applyTypeMappingsKvp(configOptions.get("type-mappings").toString(), configurator); @@ -697,6 +709,11 @@ public class CodeGenMojo extends AbstractMojo { applyImportMappingsKvpList(importMappings, configurator); } + // Apply Inline Schema Name Mappings + if (inlineSchemaNameMappings != null && (configOptions == null || !configOptions.containsKey("inline-schema-name-mappings"))) { + applyInlineSchemaNameMappingsKvpList(inlineSchemaNameMappings, configurator); + } + // Apply Type Mappings if (typeMappings != null && (configOptions == null || !configOptions.containsKey("type-mappings"))) { applyTypeMappingsKvpList(typeMappings, configurator); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConfig.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConfig.java index f0a7b3a5cc2..9894f49595c 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConfig.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConfig.java @@ -141,6 +141,8 @@ public interface CodegenConfig { Map importMapping(); + Map inlineSchemaNameMapping(); + Map apiTemplateFiles(); Map modelTemplateFiles(); @@ -181,7 +183,7 @@ public interface CodegenConfig { String toModelImport(String name); - Map toModelImportMap(String name); + Map toModelImportMap(String name); String toApiImport(String name); @@ -284,6 +286,7 @@ public interface CodegenConfig { /** * Set the OpenAPI instance. This method needs to be called right after the instantiation of the Codegen class. + * * @param openAPI specification being generated */ void setOpenAPI(OpenAPI openAPI); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index fdf55a2b837..8aecaeab586 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -152,6 +152,8 @@ public class DefaultCodegen implements CodegenConfig { protected Set reservedWords; protected Set languageSpecificPrimitives = new HashSet<>(); protected Map importMapping = new HashMap<>(); + // a map to store the mappping between inline schema and the name provided by the user + protected Map inlineSchemaNameMapping = new HashMap<>(); protected String modelPackage = "", apiPackage = "", fileSuffix; protected String modelNamePrefix = "", modelNameSuffix = ""; protected String apiNamePrefix = "", apiNameSuffix = "Api"; @@ -1055,6 +1057,11 @@ public class DefaultCodegen implements CodegenConfig { return importMapping; } + @Override + public Map inlineSchemaNameMapping() { + return inlineSchemaNameMapping; + } + @Override public String testPackage() { return testPackage; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java index 7030c75c1a1..c4adb5adc8f 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java @@ -874,6 +874,7 @@ public class DefaultGenerator implements Generator { // resolve inline models if (config.getUseInlineModelResolver()) { InlineModelResolver inlineModelResolver = new InlineModelResolver(); + inlineModelResolver.setInlineSchemaNameMapping(config.inlineSchemaNameMapping()); inlineModelResolver.flatten(openAPI); } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java index 5267336ed02..d74ffdd59b2 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java @@ -39,14 +39,19 @@ import java.util.stream.Collectors; public class InlineModelResolver { private OpenAPI openAPI; - private Map addedModels = new HashMap(); - private Map generatedSignature = new HashMap(); + private Map addedModels = new HashMap<>(); + private Map generatedSignature = new HashMap<>(); + private Map inlineSchemaNameMapping = new HashMap<>(); + private Set inlineSchemaNameMappingValues = new HashSet<>(); public boolean resolveInlineEnums = false; // structure mapper sorts properties alphabetically on write to ensure models are // serialized consistently for lookup of existing models private static ObjectMapper structureMapper; + // a set to keep track of names generated for inline schemas + private Set uniqueNames = new HashSet<>(); + static { structureMapper = Json.mapper().copy(); structureMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true); @@ -55,6 +60,11 @@ public class InlineModelResolver { final Logger LOGGER = LoggerFactory.getLogger(InlineModelResolver.class); + public void setInlineSchemaNameMapping(Map inlineSchemaNameMapping) { + this.inlineSchemaNameMapping = inlineSchemaNameMapping; + this.inlineSchemaNameMappingValues = new HashSet<>(inlineSchemaNameMapping.values()); + } + void flatten(OpenAPI openAPI) { this.openAPI = openAPI; @@ -326,9 +336,7 @@ public class InlineModelResolver { flattenProperties(openAPI, 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); - + modelName = addSchemas(modelName, model); // create request body RequestBody rb = new RequestBody(); rb.setRequired(requestBody.getRequired()); @@ -384,11 +392,10 @@ public class InlineModelResolver { schema.setRequired(op.getRequired()); am.setItems(schema); } else { + modelName = addSchemas(modelName, innerModel); Schema schema = new Schema().$ref(modelName); schema.setRequired(op.getRequired()); am.setItems(schema); - addGenerated(modelName, innerModel); - openAPI.getComponents().addSchemas(modelName, innerModel); } } } @@ -419,10 +426,8 @@ public class InlineModelResolver { if (obj.getProperties() != null && obj.getProperties().size() > 0) { flattenProperties(openAPI, obj.getProperties(), pathname); String modelName = resolveModelName(obj.getTitle(), parameter.getName()); - + modelName = addSchemas(modelName, model); parameter.$ref(modelName); - addGenerated(modelName, model); - openAPI.getComponents().addSchemas(modelName, model); } } } else if (model instanceof ArraySchema) { @@ -440,11 +445,10 @@ public class InlineModelResolver { schema.setRequired(op.getRequired()); am.setItems(schema); } else { + modelName = addSchemas(modelName, innerModel); Schema schema = new Schema().$ref(modelName); schema.setRequired(op.getRequired()); am.setItems(schema); - addGenerated(modelName, innerModel); - openAPI.getComponents().addSchemas(modelName, innerModel); } } } @@ -485,11 +489,10 @@ public class InlineModelResolver { schema.setRequired(op.getRequired()); mediaType.setSchema(schema); } else { + modelName = addSchemas(modelName, model); Schema schema = this.makeSchema(modelName, property); schema.setRequired(op.getRequired()); mediaType.setSchema(schema); - addGenerated(modelName, model); - openAPI.getComponents().addSchemas(modelName, model); } } } @@ -509,11 +512,10 @@ public class InlineModelResolver { schema.setRequired(op.getRequired()); ap.setItems(schema); } else { + modelName = addSchemas(modelName, innerModel); Schema schema = this.makeSchema(modelName, op); schema.setRequired(op.getRequired()); ap.setItems(schema); - addGenerated(modelName, innerModel); - openAPI.getComponents().addSchemas(modelName, innerModel); } } } @@ -533,11 +535,10 @@ public class InlineModelResolver { schema.setRequired(op.getRequired()); mp.setAdditionalProperties(schema); } else { + modelName = addSchemas(modelName, innerModel); Schema schema = new Schema().$ref(modelName); schema.setRequired(op.getRequired()); mp.setAdditionalProperties(schema); - addGenerated(modelName, innerModel); - openAPI.getComponents().addSchemas(modelName, innerModel); } } } @@ -596,8 +597,7 @@ public class InlineModelResolver { Schema innerModel = modelFromProperty(openAPI, component, innerModelName); String existing = matchGenerated(innerModel); if (existing == null) { - openAPI.getComponents().addSchemas(innerModelName, innerModel); - addGenerated(innerModelName, innerModel); + innerModelName = addSchemas(innerModelName, innerModel); Schema schema = new Schema().$ref(innerModelName); schema.setRequired(component.getRequired()); listIterator.set(schema); @@ -697,8 +697,7 @@ public class InlineModelResolver { private String resolveModelName(String title, String key) { if (title == null) { if (key == null) { - LOGGER.warn("Found an inline schema without the `title` attribute. Default the model name to InlineObject instead. To have better control of the model naming, define the model separately so that it can be reused throughout the spec."); - return uniqueName("InlineObject"); + return uniqueName("inline_object"); } return uniqueName(sanitizeName(key)); } else { @@ -740,19 +739,20 @@ public class InlineModelResolver { } private String uniqueName(final String name) { - if (openAPI.getComponents().getSchemas() == null) { + if (openAPI.getComponents().getSchemas() == null) { // no schema has been created + uniqueNames.add(name); return name; } String uniqueName = name; int count = 0; while (true) { - if (!openAPI.getComponents().getSchemas().containsKey(uniqueName)) { + if (!openAPI.getComponents().getSchemas().containsKey(uniqueName) && !uniqueNames.contains(uniqueName)) { + uniqueNames.add(uniqueName); return uniqueName; } uniqueName = name + "_" + ++count; } - // TODO it would probably be a good idea to check against a list of used uniqueNames to make sure there are no collisions } private void flattenProperties(OpenAPI openAPI, Map properties, String path) { @@ -775,12 +775,11 @@ public class InlineModelResolver { schema.setRequired(op.getRequired()); propsToUpdate.put(key, schema); } else { + modelName = addSchemas(modelName, model); Schema schema = new Schema().$ref(modelName); schema.setRequired(op.getRequired()); propsToUpdate.put(key, schema); modelsToAdd.put(modelName, model); - addGenerated(modelName, model); - openAPI.getComponents().addSchemas(modelName, model); } } else if (property instanceof ArraySchema) { ArraySchema ap = (ArraySchema) property; @@ -797,11 +796,10 @@ public class InlineModelResolver { schema.setRequired(op.getRequired()); ap.setItems(schema); } else { + modelName = addSchemas(modelName, innerModel); Schema schema = new Schema().$ref(modelName); schema.setRequired(op.getRequired()); ap.setItems(schema); - addGenerated(modelName, innerModel); - openAPI.getComponents().addSchemas(modelName, innerModel); } } } @@ -820,11 +818,10 @@ public class InlineModelResolver { schema.setRequired(op.getRequired()); property.setAdditionalProperties(schema); } else { + modelName = addSchemas(modelName, innerModel); Schema schema = new Schema().$ref(modelName); schema.setRequired(op.getRequired()); property.setAdditionalProperties(schema); - addGenerated(modelName, innerModel); - openAPI.getComponents().addSchemas(modelName, innerModel); } } } @@ -934,9 +931,8 @@ public class InlineModelResolver { if (resolveInlineEnums && schema.getEnum() != null && schema.getEnum().size() > 0) { LOGGER.warn("Model " + name + " promoted to its own schema due to resolveInlineEnums=true"); } + name = addSchemas(name, schema); refSchema = new Schema().$ref(name); - addGenerated(name, schema); - openAPI.getComponents().addSchemas(name, schema); } this.copyVendorExtensions(schema, refSchema); return refSchema; @@ -961,7 +957,6 @@ public class InlineModelResolver { * @param source source property * @param target target property */ - private void copyVendorExtensions(Schema source, Schema target) { Map vendorExtensions = source.getExtensions(); if (vendorExtensions == null) { @@ -971,4 +966,28 @@ public class InlineModelResolver { target.addExtension(extName, vendorExtensions.get(extName)); } } + + /** + * Add the schemas to the components + * + * @param name name of the inline schema + * @param schema inilne schema + * @return the actual model name (based on inlineSchemaNameMapping if provied) + */ + private String addSchemas(String name, Schema schema) { + //check inlineSchemaNameMapping + if (inlineSchemaNameMapping.containsKey(name)) { + name = inlineSchemaNameMapping.get(name); + } + + addGenerated(name, schema); + openAPI.getComponents().addSchemas(name, schema); + if (!name.equals(schema.getTitle()) && !inlineSchemaNameMappingValues.contains(name)) { + LOGGER.info("Inline schema created as {}. To have complete control of the model name, set the `title` field or use the inlineSchemaNameMapping option (--inline-schema-name-mapping in CLI).", name); + } + + return name; + } + + } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java index 2bb65a47865..b12c19a1499 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java @@ -68,6 +68,7 @@ public class CodegenConfigurator { private Map typeMappings = new HashMap<>(); private Map additionalProperties = new HashMap<>(); private Map importMappings = new HashMap<>(); + private Map inlineSchemaNameMappings = new HashMap<>(); private Set languageSpecificPrimitives = new HashSet<>(); private Map reservedWordMappings = new HashMap<>(); private Map serverVariables = new HashMap<>(); @@ -111,6 +112,9 @@ public class CodegenConfigurator { if(generatorSettings.getImportMappings() != null) { configurator.importMappings.putAll(generatorSettings.getImportMappings()); } + if(generatorSettings.getInlineSchemaNameMappings() != null) { + configurator.inlineSchemaNameMappings.putAll(generatorSettings.getInlineSchemaNameMappings()); + } if(generatorSettings.getLanguageSpecificPrimitives() != null) { configurator.languageSpecificPrimitives.addAll(generatorSettings.getLanguageSpecificPrimitives()); } @@ -180,6 +184,12 @@ public class CodegenConfigurator { return this; } + public CodegenConfigurator addInlineSchemaNameMapping(String key, String value) { + this.inlineSchemaNameMappings.put(key, value); + generatorSettingsBuilder.withInlineSchemaNameMapping(key, value); + return this; + } + public CodegenConfigurator addInstantiationType(String key, String value) { this.instantiationTypes.put(key, value); generatorSettingsBuilder.withInstantiationType(key, value); @@ -334,6 +344,12 @@ public class CodegenConfigurator { return this; } + public CodegenConfigurator setInlineSchemaNameMappings(Map inlineSchemaNameMappings) { + this.inlineSchemaNameMappings = inlineSchemaNameMappings; + generatorSettingsBuilder.withInlineSchemaNameMappings(inlineSchemaNameMappings); + return this; + } + public CodegenConfigurator setInputSpec(String inputSpec) { this.inputSpec = inputSpec; workflowSettingsBuilder.withInputSpec(inputSpec); @@ -610,6 +626,7 @@ public class CodegenConfigurator { config.instantiationTypes().putAll(generatorSettings.getInstantiationTypes()); config.typeMapping().putAll(generatorSettings.getTypeMappings()); config.importMapping().putAll(generatorSettings.getImportMappings()); + config.inlineSchemaNameMapping().putAll(generatorSettings.getInlineSchemaNameMappings()); config.languageSpecificPrimitives().addAll(generatorSettings.getLanguageSpecificPrimitives()); config.reservedWordsMappings().putAll(generatorSettings.getReservedWordMappings()); config.additionalProperties().putAll(generatorSettings.getAdditionalProperties()); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfiguratorUtils.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfiguratorUtils.java index 9d992c17701..b3b7a8e950a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfiguratorUtils.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfiguratorUtils.java @@ -27,8 +27,8 @@ import java.util.*; * to specific settings in CodegenConfigurator. * *

- * This class exists to facilitate testing. These methods could be applied - * to CodegenConfigurator, but this complicates things when mocking CodegenConfigurator. + * This class exists to facilitate testing. These methods could be applied + * to CodegenConfigurator, but this complicates things when mocking CodegenConfigurator. *

*
    *
  • The methods named {@code apply...Kvp} take a string of comma-separated key-value pairs.
  • @@ -43,7 +43,7 @@ import java.util.*; public final class CodegenConfiguratorUtils { public static void applyGlobalPropertiesKvpList(List globalProperties, CodegenConfigurator configurator) { - for(String propString : globalProperties) { + for (String propString : globalProperties) { applyGlobalPropertiesKvp(propString, configurator); } } @@ -51,12 +51,12 @@ public final class CodegenConfiguratorUtils { public static void applyGlobalPropertiesKvp(String globalProperties, CodegenConfigurator configurator) { final Map map = createMapFromKeyValuePairs(globalProperties); for (Map.Entry entry : map.entrySet()) { - configurator.addGlobalProperty(entry.getKey(), entry.getValue().replace(":",",")); + configurator.addGlobalProperty(entry.getKey(), entry.getValue().replace(":", ",")); } } public static void applyInstantiationTypesKvpList(List instantiationTypes, CodegenConfigurator configurator) { - for(String propString : instantiationTypes) { + for (String propString : instantiationTypes) { applyInstantiationTypesKvp(propString, configurator); } } @@ -69,7 +69,7 @@ public final class CodegenConfiguratorUtils { } public static void applyImportMappingsKvpList(List importMappings, CodegenConfigurator configurator) { - for(String propString : importMappings) { + for (String propString : importMappings) { applyImportMappingsKvp(propString, configurator); } } @@ -81,8 +81,21 @@ public final class CodegenConfiguratorUtils { } } + public static void applyInlineSchemaNameMappingsKvpList(List inlineSchemaNameMappings, CodegenConfigurator configurator) { + for (String propString : inlineSchemaNameMappings) { + applyInlineSchemaNameMappingsKvp(propString, configurator); + } + } + + public static void applyInlineSchemaNameMappingsKvp(String inlineSchemaNameMappings, CodegenConfigurator configurator) { + final Map map = createMapFromKeyValuePairs(inlineSchemaNameMappings); + for (Map.Entry entry : map.entrySet()) { + configurator.addInlineSchemaNameMapping(entry.getKey().trim(), entry.getValue().trim()); + } + } + public static void applyTypeMappingsKvpList(List typeMappings, CodegenConfigurator configurator) { - for(String propString : typeMappings) { + for (String propString : typeMappings) { applyTypeMappingsKvp(propString, configurator); } } @@ -95,7 +108,7 @@ public final class CodegenConfiguratorUtils { } public static void applyAdditionalPropertiesKvpList(List additionalProperties, CodegenConfigurator configurator) { - for(String propString : additionalProperties) { + for (String propString : additionalProperties) { applyAdditionalPropertiesKvp(propString, configurator); } } @@ -108,7 +121,7 @@ public final class CodegenConfiguratorUtils { } public static void applyServerVariablesKvpList(List values, CodegenConfigurator configurator) { - for(String value : values) { + for (String value : values) { applyServerVariablesKvp(value, configurator); } } @@ -121,7 +134,7 @@ public final class CodegenConfiguratorUtils { } public static void applyLanguageSpecificPrimitivesCsvList(List languageSpecificPrimitives, CodegenConfigurator configurator) { - for(String propString : languageSpecificPrimitives) { + for (String propString : languageSpecificPrimitives) { applyLanguageSpecificPrimitivesCsv(propString, configurator); } } @@ -134,7 +147,7 @@ public final class CodegenConfiguratorUtils { } public static void applyReservedWordsMappingsKvpList(List reservedWordMappings, CodegenConfigurator configurator) { - for(String propString : reservedWordMappings) { + for (String propString : reservedWordMappings) { applyReservedWordsMappingsKvp(propString, configurator); } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java index c9c354643b9..11a445f7b26 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java @@ -246,7 +246,7 @@ public class DefaultCodegenTest { Schema requestBodySchema = ModelUtils.getSchemaFromRequestBody(openAPI.getPaths().get("/thingy/{date}").getPost().getRequestBody()); CodegenParameter codegenParameter = codegen.fromFormProperty("visitDate", (Schema) requestBodySchema.getProperties().get("visitDate"), - new HashSet<>()); + new HashSet<>()); Assert.assertEquals(codegenParameter.defaultValue, "1971-12-19T03:39:57-08:00"); Assert.assertEquals(codegenParameter.getSchema(), null); @@ -297,7 +297,7 @@ public class DefaultCodegenTest { Schema map_without_additional_properties_sc = modelPropSchemas.get("map_without_additional_properties"); CodegenProperty map_without_additional_properties_cp = null; - for(CodegenProperty cp: cm.vars) { + for (CodegenProperty cp : cm.vars) { if ("map_string".equals(cp.baseName)) { map_string_cp = cp; } else if ("map_with_additional_properties".equals(cp.baseName)) { @@ -386,7 +386,7 @@ public class DefaultCodegenTest { Schema map_without_additional_properties_sc = modelPropSchemas.get("map_without_additional_properties"); CodegenProperty map_without_additional_properties_cp = null; - for(CodegenProperty cp: cm.vars) { + for (CodegenProperty cp : cm.vars) { if ("map_string".equals(cp.baseName)) { map_string_cp = cp; } else if ("map_with_additional_properties".equals(cp.baseName)) { @@ -466,7 +466,7 @@ public class DefaultCodegenTest { Schema empty_map_sc = modelPropSchemas.get("empty_map"); CodegenProperty empty_map_cp = null; - for(CodegenProperty cp: cm.vars) { + for (CodegenProperty cp : cm.vars) { if ("map_with_undeclared_properties_string".equals(cp.baseName)) { map_with_undeclared_properties_string_cp = cp; } else if ("map_with_undeclared_properties_anytype_1".equals(cp.baseName)) { @@ -1016,7 +1016,7 @@ public class DefaultCodegenTest { // all leaf Schemas have discriminators with PropertyName/BaseName + empty discriminator maps List leafModelNames = Arrays.asList("Cat", "Dog", "Lizard", "Snake"); - for (String leafModelName: leafModelNames) { + for (String leafModelName : leafModelNames) { Schema leafSc = openAPI.getComponents().getSchemas().get(leafModelName); CodegenModel leafCm = codegen.fromModel(leafModelName, leafSc); Assert.assertEquals(leafCm.discriminator, emptyMapDisc); @@ -1028,7 +1028,7 @@ public class DefaultCodegenTest { petDisc.setPropertyName(propertyName); petDisc.setPropertyBaseName(propertyBaseName); java.util.LinkedHashSet hs = new LinkedHashSet<>(); - for (String leafModelName: leafModelNames) { + for (String leafModelName : leafModelNames) { hs.add(new CodegenDiscriminator.MappedModel(leafModelName, codegen.toModelName(leafModelName))); } hs.add(new CodegenDiscriminator.MappedModel("Reptile", codegen.toModelName("Reptile"))); @@ -1045,7 +1045,7 @@ public class DefaultCodegenTest { reptileDisc.setPropertyName(propertyName); reptileDisc.setPropertyBaseName(propertyBaseName); hs.clear(); - for (String reptileModelName: reptileModelNames) { + for (String reptileModelName : reptileModelNames) { hs.add(new CodegenDiscriminator.MappedModel(reptileModelName, codegen.toModelName(reptileModelName))); } reptileDisc.setMappedModels(hs); @@ -1061,7 +1061,7 @@ public class DefaultCodegenTest { myPetDisc.setPropertyName(propertyName); myPetDisc.setPropertyBaseName(propertyBaseName); hs.clear(); - for (String myPetName: myPetNames) { + for (String myPetName : myPetNames) { hs.add(new CodegenDiscriminator.MappedModel(myPetName, codegen.toModelName(myPetName))); } myPetDisc.setMappedModels(hs); @@ -1128,7 +1128,7 @@ public class DefaultCodegenTest { // all leaf Schemas have discriminators with PropertyName/BaseName + empty discriminator maps List leafModelNames = Arrays.asList("Cat", "Dog", "Lizard", "Snake"); - for (String leafModelName: leafModelNames) { + for (String leafModelName : leafModelNames) { Schema leafSc = openAPI.getComponents().getSchemas().get(leafModelName); CodegenModel leafCm = codegen.fromModel(leafModelName, leafSc); Assert.assertNull(leafCm.discriminator); @@ -1139,7 +1139,7 @@ public class DefaultCodegenTest { petDisc.setPropertyName(propertyName); petDisc.setPropertyBaseName(propertyBaseName); java.util.LinkedHashSet hs = new LinkedHashSet<>(); - for (String leafModelName: leafModelNames) { + for (String leafModelName : leafModelNames) { hs.add(new CodegenDiscriminator.MappedModel(leafModelName, codegen.toModelName(leafModelName))); } hs.add(new CodegenDiscriminator.MappedModel("Reptile", codegen.toModelName("Reptile"))); @@ -1155,7 +1155,7 @@ public class DefaultCodegenTest { reptileDisc.setPropertyName(propertyName); reptileDisc.setPropertyBaseName(propertyBaseName); hs.clear(); - for (String reptileModelName: reptileModelNames) { + for (String reptileModelName : reptileModelNames) { hs.add(new CodegenDiscriminator.MappedModel(reptileModelName, codegen.toModelName(reptileModelName))); } reptileDisc.setMappedModels(hs); @@ -1220,7 +1220,7 @@ public class DefaultCodegenTest { hm.put("ComposedDiscTypeInconsistent", "'ComposedDiscTypeInconsistent' defines discriminator 'fruitType', but the referenced schema 'DiscTypeIncorrect' is incorrect. invalid type for fruitType, set it to string"); hm.put("ComposedDiscRequiredInconsistent", "'ComposedDiscRequiredInconsistent' defines discriminator 'fruitType', but the referenced schema 'DiscOptionalTypeCorrect' is incorrect. invalid optional definition of fruitType, include it in required"); - for(Map.Entry entry : hm.entrySet()) { + for (Map.Entry entry : hm.entrySet()) { String modelName = entry.getKey(); String errorMessageExpected = entry.getValue(); @@ -1255,7 +1255,7 @@ public class DefaultCodegenTest { hm.put("ComposedDiscTypeInconsistent", "'ComposedDiscTypeInconsistent' defines discriminator 'fruitType', but the referenced schema 'DiscTypeIncorrect' is incorrect. invalid type for fruitType, set it to string"); hm.put("ComposedDiscRequiredInconsistent", "'ComposedDiscRequiredInconsistent' defines discriminator 'fruitType', but the referenced schema 'DiscOptionalTypeCorrect' is incorrect. invalid optional definition of fruitType, include it in required"); - for(Map.Entry entry : hm.entrySet()) { + for (Map.Entry entry : hm.entrySet()) { String modelName = entry.getKey(); String errorMessageExpected = entry.getValue(); @@ -1465,7 +1465,7 @@ public class DefaultCodegenTest { } @Test - public void testComposedSchemaAllOfHierarchy(){ + public void testComposedSchemaAllOfHierarchy() { final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/allOf_composition_discriminator.yaml"); DefaultCodegen codegen = new DefaultCodegen(); @@ -1497,7 +1497,7 @@ public class DefaultCodegenTest { test.setPropertyName(prop); test.setPropertyBaseName(prop); test.setMapping(null); - test.setMappedModels(new HashSet(){{ + test.setMappedModels(new HashSet() {{ add(new CodegenDiscriminator.MappedModel("Snake", "Snake")); add(new CodegenDiscriminator.MappedModel("Lizard", "Lizard")); }}); @@ -1510,7 +1510,7 @@ public class DefaultCodegenTest { test.setPropertyName(prop); test.setPropertyBaseName(prop); test.setMapping(null); - test.setMappedModels(new HashSet(){{ + test.setMappedModels(new HashSet() {{ add(new CodegenDiscriminator.MappedModel("Cat", "Cat")); add(new CodegenDiscriminator.MappedModel("Lizard", "Lizard")); }}); @@ -1518,7 +1518,7 @@ public class DefaultCodegenTest { } public CodegenModel getModel(List allModels, String modelName) { - for (ModelMap obj: allModels) { + for (ModelMap obj : allModels) { CodegenModel cm = obj.getModel(); if (modelName.equals(cm.name)) { return cm; @@ -1558,7 +1558,7 @@ public class DefaultCodegenTest { Assert.assertNotNull(cm.children); List expectedDiscriminatorValues = new ArrayList<>(Arrays.asList("daily", "sub-obj")); ArrayList xDiscriminatorValues = new ArrayList<>(); - for (CodegenModel child: cm.children) { + for (CodegenModel child : cm.children) { xDiscriminatorValues.add((String) child.vendorExtensions.get("x-discriminator-value")); } assertEquals(xDiscriminatorValues, expectedDiscriminatorValues); @@ -1569,7 +1569,7 @@ public class DefaultCodegenTest { discriminator.setPropertyName(config.toVarName(prop)); discriminator.setPropertyBaseName(prop); discriminator.setMapping(null); - discriminator.setMappedModels(new HashSet(){{ + discriminator.setMappedModels(new HashSet() {{ add(new CodegenDiscriminator.MappedModel("DailySubObj", "DailySubObj")); add(new CodegenDiscriminator.MappedModel("SubObj", "SubObj")); add(new CodegenDiscriminator.MappedModel("daily", "DailySubObj")); @@ -1587,7 +1587,7 @@ public class DefaultCodegenTest { Schema schema = openAPI.getComponents().getSchemas().get("NewMessageEventCoreNoOwnProps"); codegen.setOpenAPI(openAPI); CodegenModel model = codegen.fromModel("NewMessageEventCoreNoOwnProps", schema); - Assert.assertEquals(getNames(model.getVars()), Arrays.asList("id","message")); + Assert.assertEquals(getNames(model.getVars()), Arrays.asList("id", "message")); Assert.assertNull(model.parent); Assert.assertNull(model.allParents); } @@ -1624,7 +1624,7 @@ public class DefaultCodegenTest { } private List getNames(List props) { - if(props == null) return null; + if (props == null) return null; return props.stream().map(v -> v.name).collect(Collectors.toList()); } @@ -1767,10 +1767,10 @@ public class DefaultCodegenTest { final Map responseProperties = Collections.unmodifiableMap(openAPI.getComponents().getSchemas().get("Response").getProperties()); final Map requestProperties = Collections.unmodifiableMap(openAPI.getComponents().getSchemas().get("Response").getProperties()); - Assert.assertTrue(codegen.fromProperty("firstName",(Schema) responseProperties.get("firstName")).deprecated); - Assert.assertFalse(codegen.fromProperty("customerCode",(Schema) responseProperties.get("customerCode")).deprecated); - Assert.assertTrue(codegen.fromProperty("firstName",(Schema) requestProperties.get("firstName")).deprecated); - Assert.assertFalse(codegen.fromProperty("customerCode",(Schema) requestProperties.get("customerCode")).deprecated); + Assert.assertTrue(codegen.fromProperty("firstName", (Schema) responseProperties.get("firstName")).deprecated); + Assert.assertFalse(codegen.fromProperty("customerCode", (Schema) responseProperties.get("customerCode")).deprecated); + Assert.assertTrue(codegen.fromProperty("firstName", (Schema) requestProperties.get("firstName")).deprecated); + Assert.assertFalse(codegen.fromProperty("customerCode", (Schema) requestProperties.get("customerCode")).deprecated); } @Test @@ -1782,8 +1782,8 @@ public class DefaultCodegenTest { final Map requestProperties = Collections.unmodifiableMap(openAPI.getComponents().getSchemas().get("complex").getProperties()); - Assert.assertTrue(codegen.fromProperty("deprecated", (Schema)requestProperties.get("deprecated")).deprecated); - Assert.assertFalse(codegen.fromProperty("current", (Schema)requestProperties.get("current")).deprecated); + Assert.assertTrue(codegen.fromProperty("deprecated", (Schema) requestProperties.get("deprecated")).deprecated); + Assert.assertFalse(codegen.fromProperty("current", (Schema) requestProperties.get("current")).deprecated); } @Test @@ -3115,7 +3115,7 @@ public class DefaultCodegenTest { CodegenOperation co; for (String modelName : modelNames) { - path = "/"+modelName; + path = "/" + modelName; operation = openAPI.getPaths().get(path).getPost(); co = codegen.fromOperation(path, "POST", operation, null); assertTrue(co.bodyParam.getHasValidation()); @@ -3244,7 +3244,7 @@ public class DefaultCodegenTest { modelName = "ArrayWithObjectWithPropsInItems"; ArraySchema as = (ArraySchema) openAPI.getComponents().getSchemas().get(modelName); assertEquals("#/components/schemas/ArrayWithObjectWithPropsInItems_inner", as.getItems().get$ref()); - sc = openAPI.getComponents().getSchemas().get("ArrayWithObjectWithPropsInItems_inner"); + sc = openAPI.getComponents().getSchemas().get("ArrayWithObjectWithPropsInItems_inner"); cm = codegen.fromModel(modelName, sc); assertTrue(cm.getHasVars()); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/InlineModelResolverTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/InlineModelResolverTest.java index 3ac23d849ef..f98fc097233 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/InlineModelResolverTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/InlineModelResolverTest.java @@ -234,11 +234,11 @@ public class InlineModelResolverTest { responseExt.put("x-foo", "bar"); openapi.path("/foo/bar", new PathItem() - .get(new Operation().responses(new ApiResponses().addApiResponse("200", new ApiResponse() - .description("it works!") - .content(new Content().addMediaType("application/json", - new MediaType().schema(new ObjectSchema().title("inline_response_200") - .addProperties("name", new StringSchema()).extensions(propExt)))))))) + .get(new Operation().responses(new ApiResponses().addApiResponse("200", new ApiResponse() + .description("it works!") + .content(new Content().addMediaType("application/json", + new MediaType().schema(new ObjectSchema().title("inline_response_200") + .addProperties("name", new StringSchema()).extensions(propExt)))))))) .path("/foo/baz", new PathItem() .get(new Operation().responses(new ApiResponses().addApiResponse("200", new ApiResponse() .description("it works!") @@ -293,11 +293,11 @@ public class InlineModelResolverTest { responseExt.put("x-foo", "bar"); openapi.path("/foo/bar", new PathItem() - .get(new Operation().responses(new ApiResponses().addApiResponse("200", new ApiResponse() - .description("it works!") - .content(new Content().addMediaType("application/json", - new MediaType().schema(new ObjectSchema().title("GetBarResponse") - .addProperties("name", new StringSchema()).extensions(propExt)))))))) + .get(new Operation().responses(new ApiResponses().addApiResponse("200", new ApiResponse() + .description("it works!") + .content(new Content().addMediaType("application/json", + new MediaType().schema(new ObjectSchema().title("GetBarResponse") + .addProperties("name", new StringSchema()).extensions(propExt)))))))) .path("/foo/baz", new PathItem() .get(new Operation().responses(new ApiResponses().addApiResponse("200", new ApiResponse() .description("it works!") @@ -429,7 +429,7 @@ public class InlineModelResolverTest { ArraySchema requestBody = (ArraySchema) mediaType.getSchema(); assertNotNull(requestBody.getItems().get$ref()); - assertEquals("#/components/schemas/InlineObject", requestBody.getItems().get$ref()); + assertEquals("#/components/schemas/inline_object_2", requestBody.getItems().get$ref()); Schema items = ModelUtils.getReferencedSchema(openAPI, ((ArraySchema) mediaType.getSchema()).getItems()); assertTrue(items.getProperties().get("street") instanceof StringSchema); @@ -513,7 +513,7 @@ public class InlineModelResolverTest { Object additionalPropertiesObject = mediaType.getSchema().getAdditionalProperties(); assertTrue(additionalPropertiesObject instanceof Schema); - Schema additionalProperties = ModelUtils.getReferencedSchema(openAPI, (Schema)additionalPropertiesObject); + Schema additionalProperties = ModelUtils.getReferencedSchema(openAPI, (Schema) additionalPropertiesObject); assertNotNull(additionalProperties); assertTrue(additionalProperties.getProperties().get("resolve_inline_object_response_with_additional_properties") instanceof StringSchema); } @@ -522,42 +522,42 @@ public class InlineModelResolverTest { public void resolveInlineMapSchemaInResponse() { OpenAPI openAPI = new OpenAPIParser().readLocation("src/test/resources/3_0/inline_model_resolver.yaml", null, new ParseOptions()).getOpenAPI(); ApiResponse apiResponse = openAPI - .getPaths() - .get("/resolve_inline_map_schema_in_response") - .getGet() - .getResponses() - .get("200"); + .getPaths() + .get("/resolve_inline_map_schema_in_response") + .getGet() + .getResponses() + .get("200"); // NOTE: Swagger parser doesn't use MapSchema currently, // so we need to set a MapSchema instance as the schema manually for testing. // @see https://github.com/swagger-api/swagger-parser/blob/master/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/SchemaTypeUtil.java apiResponse.content( - new Content().addMediaType( - "application/json", - new MediaType().schema( - new MapSchema().additionalProperties( - new ObjectSchema().addProperties( - "resolve_inline_map_schema_in_response_property", - new ObjectSchema().addProperties( - "resolve_inline_map_schema_in_response_property_string", - new StringSchema().example("example") - ) + new Content().addMediaType( + "application/json", + new MediaType().schema( + new MapSchema().additionalProperties( + new ObjectSchema().addProperties( + "resolve_inline_map_schema_in_response_property", + new ObjectSchema().addProperties( + "resolve_inline_map_schema_in_response_property_string", + new StringSchema().example("example") + ) + ) + ) ) - ) ) - ) ); new InlineModelResolver().flatten(openAPI); MediaType mediaType = openAPI - .getPaths() - .get("/resolve_inline_map_schema_in_response") - .getGet() - .getResponses() - .get("200") - .getContent() - .get("application/json"); + .getPaths() + .get("/resolve_inline_map_schema_in_response") + .getGet() + .getResponses() + .get("200") + .getContent() + .get("application/json"); assertTrue(mediaType.getSchema() instanceof MapSchema); Schema additionalProperties = (Schema) mediaType.getSchema().getAdditionalProperties(); @@ -568,8 +568,8 @@ public class InlineModelResolverTest { Schema referencedSchemaProperty = (Schema) referencedSchema.getProperties().get("resolve_inline_map_schema_in_response_property"); assertEquals( - "#/components/schemas/_resolve_inline_map_schema_in_response_resolve_inline_map_schema_in_response_property", - referencedSchemaProperty.get$ref() + "#/components/schemas/_resolve_inline_map_schema_in_response_resolve_inline_map_schema_in_response_property", + referencedSchemaProperty.get$ref() ); assertNotNull(ModelUtils.getReferencedSchema(openAPI, referencedSchemaProperty)); } @@ -995,7 +995,20 @@ public class InlineModelResolverTest { } @Test - public void regression_6905() { + public void testInlineSchemaNameMapping() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/inline_model_resolver.yaml"); + InlineModelResolver resolver = new InlineModelResolver(); + Map inlineSchemaNames = new HashMap<>(); + inlineSchemaNames.put("inline_object_2", "SomethingMapped"); + inlineSchemaNames.put("inline_object_4", "nothing_new"); + resolver.setInlineSchemaNameMapping(inlineSchemaNames); + resolver.flatten(openAPI); + Schema schema = openAPI.getComponents().getSchemas().get("SomethingMapped"); + assertTrue(schema.getProperties().get("street") instanceof StringSchema); + assertTrue(schema.getProperties().get("city") instanceof StringSchema); + + Schema nothingNew = openAPI.getComponents().getSchemas().get("nothing_new"); + assertTrue(nothingNew.getProperties().get("arbitrary_request_body_array_property") instanceof ObjectSchema); } } \ No newline at end of file diff --git a/samples/client/petstore/java/okhttp-gson/.openapi-generator/FILES b/samples/client/petstore/java/okhttp-gson/.openapi-generator/FILES index 617697215b8..002737f5499 100644 --- a/samples/client/petstore/java/okhttp-gson/.openapi-generator/FILES +++ b/samples/client/petstore/java/okhttp-gson/.openapi-generator/FILES @@ -12,7 +12,7 @@ docs/Apple.md docs/AppleReq.md docs/ArrayOfArrayOfNumberOnly.md docs/ArrayOfInlineAllOf.md -docs/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf.md +docs/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.md docs/ArrayOfNumberOnly.md docs/ArrayTest.md docs/Banana.md @@ -133,7 +133,7 @@ src/main/java/org/openapitools/client/model/Apple.java src/main/java/org/openapitools/client/model/AppleReq.java src/main/java/org/openapitools/client/model/ArrayOfArrayOfNumberOnly.java src/main/java/org/openapitools/client/model/ArrayOfInlineAllOf.java -src/main/java/org/openapitools/client/model/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf.java +src/main/java/org/openapitools/client/model/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.java src/main/java/org/openapitools/client/model/ArrayOfNumberOnly.java src/main/java/org/openapitools/client/model/ArrayTest.java src/main/java/org/openapitools/client/model/Banana.java diff --git a/samples/client/petstore/java/okhttp-gson/README.md b/samples/client/petstore/java/okhttp-gson/README.md index 73e815f1208..d1dbd67d76e 100644 --- a/samples/client/petstore/java/okhttp-gson/README.md +++ b/samples/client/petstore/java/okhttp-gson/README.md @@ -162,7 +162,7 @@ Class | Method | HTTP request | Description - [AppleReq](docs/AppleReq.md) - [ArrayOfArrayOfNumberOnly](docs/ArrayOfArrayOfNumberOnly.md) - [ArrayOfInlineAllOf](docs/ArrayOfInlineAllOf.md) - - [ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf](docs/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf.md) + - [ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1](docs/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.md) - [ArrayOfNumberOnly](docs/ArrayOfNumberOnly.md) - [ArrayTest](docs/ArrayTest.md) - [Banana](docs/Banana.md) diff --git a/samples/client/petstore/java/okhttp-gson/api/openapi.yaml b/samples/client/petstore/java/okhttp-gson/api/openapi.yaml index 0a6baa9fb94..fbdf8afb60c 100644 --- a/samples/client/petstore/java/okhttp-gson/api/openapi.yaml +++ b/samples/client/petstore/java/okhttp-gson/api/openapi.yaml @@ -2344,7 +2344,7 @@ components: items: allOf: - $ref: '#/components/schemas/Dog_allOf' - - $ref: '#/components/schemas/ArrayOfInlineAllOf_array_allof_dog_propertyItems_allOf' + - $ref: '#/components/schemas/ArrayOfInlineAllOf_array_allof_dog_propertyItems_allOf_1' type: array required: - name @@ -2504,7 +2504,7 @@ components: declawed: type: boolean type: object - ArrayOfInlineAllOf_array_allof_dog_propertyItems_allOf: + ArrayOfInlineAllOf_array_allof_dog_propertyItems_allOf_1: properties: color: type: string diff --git a/samples/client/petstore/java/okhttp-gson/docs/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.md b/samples/client/petstore/java/okhttp-gson/docs/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.md new file mode 100644 index 00000000000..37e513bbc8b --- /dev/null +++ b/samples/client/petstore/java/okhttp-gson/docs/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.md @@ -0,0 +1,13 @@ + + +# ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**color** | **String** | | [optional] | + + + diff --git a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/JSON.java b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/JSON.java index ac8397eb12b..be47795aa72 100644 --- a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/JSON.java +++ b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/JSON.java @@ -225,7 +225,7 @@ public class JSON { .registerTypeAdapterFactory(new org.openapitools.client.model.AppleReq.CustomTypeAdapterFactory()) .registerTypeAdapterFactory(new org.openapitools.client.model.ArrayOfArrayOfNumberOnly.CustomTypeAdapterFactory()) .registerTypeAdapterFactory(new org.openapitools.client.model.ArrayOfInlineAllOf.CustomTypeAdapterFactory()) - .registerTypeAdapterFactory(new org.openapitools.client.model.ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf.CustomTypeAdapterFactory()) + .registerTypeAdapterFactory(new org.openapitools.client.model.ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.CustomTypeAdapterFactory()) .registerTypeAdapterFactory(new org.openapitools.client.model.ArrayOfNumberOnly.CustomTypeAdapterFactory()) .registerTypeAdapterFactory(new org.openapitools.client.model.ArrayTest.CustomTypeAdapterFactory()) .registerTypeAdapterFactory(new org.openapitools.client.model.Banana.CustomTypeAdapterFactory()) diff --git a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ArrayOfInlineAllOf.java b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ArrayOfInlineAllOf.java index bb02f3676a0..48fb48ddeb4 100644 --- a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ArrayOfInlineAllOf.java +++ b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ArrayOfInlineAllOf.java @@ -25,7 +25,7 @@ import io.swagger.annotations.ApiModelProperty; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.openapitools.client.model.ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf; +import org.openapitools.client.model.ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1; import org.openapitools.client.model.DogAllOf; import com.google.gson.Gson; diff --git a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.java b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.java new file mode 100644 index 00000000000..8e156c9d119 --- /dev/null +++ b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.java @@ -0,0 +1,273 @@ +/* + * 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: \" \\ + * + * The version of the OpenAPI document: 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 java.util.Objects; +import java.util.Arrays; +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 com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.openapitools.client.JSON; + +/** + * ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 + */ +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 { + public static final String SERIALIZED_NAME_COLOR = "color"; + @SerializedName(SERIALIZED_NAME_COLOR) + private String color; + + public ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1() { + } + + public ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 color(String color) { + + this.color = color; + return this; + } + + /** + * Get color + * @return color + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + + public String getColor() { + return color; + } + + + public void setColor(String color) { + this.color = color; + } + + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + private Map additionalProperties; + + /** + * Set the additional (undeclared) property with the specified name and value. + * If the property does not already exist, create it otherwise replace it. + */ + public ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 putAdditionalProperty(String key, Object value) { + if (this.additionalProperties == null) { + this.additionalProperties = new HashMap(); + } + this.additionalProperties.put(key, value); + return this; + } + + /** + * Return the additional (undeclared) property. + */ + public Map getAdditionalProperties() { + return additionalProperties; + } + + /** + * Return the additional (undeclared) property with the specified name. + */ + public Object getAdditionalProperty(String key) { + if (this.additionalProperties == null) { + return null; + } + return this.additionalProperties.get(key); + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 arrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 = (ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1) o; + return Objects.equals(this.color, arrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.color)&& + Objects.equals(this.additionalProperties, arrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.additionalProperties); + } + + @Override + public int hashCode() { + return Objects.hash(color, additionalProperties); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 {\n"); + sb.append(" color: ").append(toIndentedString(color)).append("\n"); + sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + + public static HashSet openapiFields; + public static HashSet openapiRequiredFields; + + static { + // a set of all properties/fields (JSON key names) + openapiFields = new HashSet(); + openapiFields.add("color"); + + // a set of required properties/fields (JSON key names) + openapiRequiredFields = new HashSet(); + } + + /** + * Validates the JSON Object and throws an exception if issues found + * + * @param jsonObj JSON Object + * @throws IOException if the JSON Object is invalid with respect to ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 + */ + public static void validateJsonObject(JsonObject jsonObj) throws IOException { + if (jsonObj == null) { + if (ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.openapiRequiredFields.isEmpty()) { + return; + } else { // has required fields + throw new IllegalArgumentException(String.format("The required field(s) %s in ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 is not found in the empty JSON string", ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.openapiRequiredFields.toString())); + } + } + if (jsonObj.get("color") != null && !jsonObj.get("color").isJsonPrimitive()) { + throw new IllegalArgumentException(String.format("Expected the field `color` to be a primitive type in the JSON string but got `%s`", jsonObj.get("color").toString())); + } + } + + public static class CustomTypeAdapterFactory implements TypeAdapterFactory { + @SuppressWarnings("unchecked") + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + if (!ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.class.isAssignableFrom(type.getRawType())) { + return null; // this class only serializes 'ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1' and its subtypes + } + final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); + final TypeAdapter thisAdapter + = gson.getDelegateAdapter(this, TypeToken.get(ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.class)); + + return (TypeAdapter) new TypeAdapter() { + @Override + public void write(JsonWriter out, ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 value) throws IOException { + JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); + obj.remove("additionalProperties"); + // serialize additonal properties + if (value.getAdditionalProperties() != null) { + for (Map.Entry entry : value.getAdditionalProperties().entrySet()) { + if (entry.getValue() instanceof String) + obj.addProperty(entry.getKey(), (String) entry.getValue()); + else if (entry.getValue() instanceof Number) + obj.addProperty(entry.getKey(), (Number) entry.getValue()); + else if (entry.getValue() instanceof Boolean) + obj.addProperty(entry.getKey(), (Boolean) entry.getValue()); + else if (entry.getValue() instanceof Character) + obj.addProperty(entry.getKey(), (Character) entry.getValue()); + else { + obj.add(entry.getKey(), gson.toJsonTree(entry.getValue()).getAsJsonObject()); + } + } + } + elementAdapter.write(out, obj); + } + + @Override + public ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 read(JsonReader in) throws IOException { + JsonObject jsonObj = elementAdapter.read(in).getAsJsonObject(); + validateJsonObject(jsonObj); + // store additional fields in the deserialized instance + ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 instance = thisAdapter.fromJsonTree(jsonObj); + for (Map.Entry entry : jsonObj.entrySet()) { + if (!openapiFields.contains(entry.getKey())) { + if (entry.getValue().isJsonPrimitive()) { // primitive type + if (entry.getValue().getAsJsonPrimitive().isString()) + instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsString()); + else if (entry.getValue().getAsJsonPrimitive().isNumber()) + instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsNumber()); + else if (entry.getValue().getAsJsonPrimitive().isBoolean()) + instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsBoolean()); + else + throw new IllegalArgumentException(String.format("The field `%s` has unknown primitive type. Value: %s", entry.getKey(), entry.getValue().toString())); + } else { // non-primitive type + instance.putAdditionalProperty(entry.getKey(), gson.fromJson(entry.getValue(), HashMap.class)); + } + } + } + return instance; + } + + }.nullSafe(); + } + } + + /** + * Create an instance of ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 given an JSON string + * + * @param jsonString JSON string + * @return An instance of ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 + * @throws IOException if the JSON string is invalid with respect to ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 + */ + public static ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 fromJson(String jsonString) throws IOException { + return JSON.getGson().fromJson(jsonString, ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1.class); + } + + /** + * Convert an instance of ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 to an JSON string + * + * @return JSON string + */ + public String toJson() { + return JSON.getGson().toJson(this); + } +} + diff --git a/samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/model/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1Test.java b/samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/model/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1Test.java new file mode 100644 index 00000000000..2716e8181df --- /dev/null +++ b/samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/model/ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1Test.java @@ -0,0 +1,50 @@ +/* + * 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: \" \\ + * + * The version of the OpenAPI document: 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 org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + + +/** + * Model tests for ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 + */ +public class ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1Test { + private final ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 model = new ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1(); + + /** + * Model tests for ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 + */ + @Test + public void testArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1() { + // TODO: test ArrayOfInlineAllOfArrayAllofDogPropertyItemsAllOf1 + } + + /** + * Test the property 'color' + */ + @Test + public void colorTest() { + // TODO: test color + } + +}