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 b17b449893f8..7d2b74bd137b 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 @@ -142,10 +142,10 @@ public class DefaultCodegen implements CodegenConfig { protected GeneratorMetadata generatorMetadata; protected String inputSpec; protected String outputFolder = ""; - protected Set defaultIncludes; - protected Map typeMapping; - protected Map instantiationTypes; - protected Set reservedWords; + protected Set defaultIncludes = new HashSet(); + protected Map typeMapping = new HashMap(); + protected Map instantiationTypes = new HashMap(); + protected Set reservedWords = new HashSet(); protected Set languageSpecificPrimitives = new HashSet(); protected Map importMapping = new HashMap(); protected String modelPackage = "", apiPackage = "", fileSuffix; @@ -177,13 +177,6 @@ apiTemplateFiles are for API outputs only (controllers/handlers). protected List cliOptions = new ArrayList(); protected boolean skipOverwrite; protected boolean removeOperationIdPrefix; - protected String removeOperationIdPrefixDelimiter = "_"; - protected int removeOperationIdPrefixCount = 1; - protected boolean skipOperationExample; - - protected final static Pattern JSON_MIME_PATTERN = Pattern.compile("(?i)application\\/json(;.*)?"); - protected final static Pattern JSON_VENDOR_MIME_PATTERN = Pattern.compile("(?i)application\\/vnd.(.*)+json(;.*)?"); - private static final Pattern COMMON_PREFIX_ENUM_NAME = Pattern.compile("[a-zA-Z0-9]+\\z"); /** * True if the code generator supports multiple class inheritance. @@ -256,12 +249,10 @@ apiTemplateFiles are for API outputs only (controllers/handlers). // A cache to efficiently lookup a Schema instance based on the return value of `toModelName()`. private Map modelNameToSchemaCache; - @Override public List cliOptions() { return cliOptions; } - @Override public void processOpts() { if (additionalProperties.containsKey(CodegenConstants.TEMPLATE_DIR)) { this.setTemplateDir((String) additionalProperties.get(CodegenConstants.TEMPLATE_DIR)); @@ -323,51 +314,36 @@ public void processOpts() { } if (additionalProperties.containsKey(CodegenConstants.REMOVE_OPERATION_ID_PREFIX)) { - this.setRemoveOperationIdPrefix(Boolean.parseBoolean(additionalProperties + this.setRemoveOperationIdPrefix(Boolean.valueOf(additionalProperties .get(CodegenConstants.REMOVE_OPERATION_ID_PREFIX).toString())); } - if (additionalProperties.containsKey(CodegenConstants.REMOVE_OPERATION_ID_PREFIX_DELIMITER)) { - this.setRemoveOperationIdPrefixDelimiter(additionalProperties - .get(CodegenConstants.REMOVE_OPERATION_ID_PREFIX_DELIMITER).toString()); - } - - if (additionalProperties.containsKey(CodegenConstants.REMOVE_OPERATION_ID_PREFIX_COUNT)) { - this.setRemoveOperationIdPrefixCount(Integer.parseInt(additionalProperties - .get(CodegenConstants.REMOVE_OPERATION_ID_PREFIX_COUNT).toString())); - } - - if (additionalProperties.containsKey(CodegenConstants.SKIP_OPERATION_EXAMPLE)) { - this.setSkipOperationExample(Boolean.parseBoolean(additionalProperties - .get(CodegenConstants.SKIP_OPERATION_EXAMPLE).toString())); - } - if (additionalProperties.containsKey(CodegenConstants.DOCEXTENSION)) { this.setDocExtension(String.valueOf(additionalProperties .get(CodegenConstants.DOCEXTENSION).toString())); } if (additionalProperties.containsKey(CodegenConstants.ENABLE_POST_PROCESS_FILE)) { - this.setEnablePostProcessFile(Boolean.parseBoolean(additionalProperties + this.setEnablePostProcessFile(Boolean.valueOf(additionalProperties .get(CodegenConstants.ENABLE_POST_PROCESS_FILE).toString())); } if (additionalProperties.containsKey(CodegenConstants.GENERATE_ALIAS_AS_MODEL)) { - ModelUtils.setGenerateAliasAsModel(Boolean.parseBoolean(additionalProperties + ModelUtils.setGenerateAliasAsModel(Boolean.valueOf(additionalProperties .get(CodegenConstants.GENERATE_ALIAS_AS_MODEL).toString())); } if (additionalProperties.containsKey(CodegenConstants.REMOVE_ENUM_VALUE_PREFIX)) { - this.setRemoveEnumValuePrefix(Boolean.parseBoolean(additionalProperties + this.setRemoveEnumValuePrefix(Boolean.valueOf(additionalProperties .get(CodegenConstants.REMOVE_ENUM_VALUE_PREFIX).toString())); } if (additionalProperties.containsKey(CodegenConstants.LEGACY_DISCRIMINATOR_BEHAVIOR)) { - this.setLegacyDiscriminatorBehavior(Boolean.parseBoolean(additionalProperties + this.setLegacyDiscriminatorBehavior(Boolean.valueOf(additionalProperties .get(CodegenConstants.LEGACY_DISCRIMINATOR_BEHAVIOR).toString())); } if (additionalProperties.containsKey(CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT)) { - this.setDisallowAdditionalPropertiesIfNotPresent(Boolean.parseBoolean(additionalProperties + this.setDisallowAdditionalPropertiesIfNotPresent(Boolean.valueOf(additionalProperties .get(CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT).toString())); } } @@ -412,7 +388,6 @@ private void registerMustacheLambdas() { } // override with any special post-processing for all models - @Override @SuppressWarnings({"static-method", "unchecked"}) public Map postProcessAllModels(Map objs) { if (this.useOneOfInterfaces) { @@ -421,9 +396,10 @@ public Map postProcessAllModels(Map objs) { Map modelValue = new HashMap<>(additionalProperties()); modelValue.put("model", cm); - List> importsValue = new ArrayList<>(); + List modelsValue = Arrays.asList(modelValue); + List> importsValue = new ArrayList>(); Map objsValue = new HashMap<>(); - objsValue.put("models", Collections.singletonList(modelValue)); + objsValue.put("models", modelsValue); objsValue.put("package", modelPackage()); objsValue.put("imports", importsValue); objsValue.put("classname", cm.classname); @@ -434,7 +410,7 @@ public Map postProcessAllModels(Map objs) { // Gather data from all the models that contain oneOf into OneOfImplementorAdditionalData classes // (see docstring of that class to find out what information is gathered and why) Map additionalDataMap = new HashMap(); - for (Map.Entry modelsEntry : objs.entrySet()) { + for (Map.Entry modelsEntry : objs.entrySet()) { Map modelsAttrs = (Map) modelsEntry.getValue(); List models = (List) modelsAttrs.get("models"); List> modelsImports = (List>) modelsAttrs.getOrDefault("imports", new ArrayList>()); @@ -456,7 +432,7 @@ public Map postProcessAllModels(Map objs) { } // Add all the data from OneOfImplementorAdditionalData classes to the implementing models - for (Map.Entry modelsEntry : objs.entrySet()) { + for (Map.Entry modelsEntry : objs.entrySet()) { Map modelsAttrs = (Map) modelsEntry.getValue(); List models = (List) modelsAttrs.get("models"); List> imports = (List>) modelsAttrs.get("imports"); @@ -476,14 +452,16 @@ public Map postProcessAllModels(Map objs) { /** * Return a map from model name to Schema for efficient lookup. - * + * * @return map from model name to Schema. */ protected Map getModelNameToSchemaCache() { if (modelNameToSchemaCache == null) { // Create a cache to efficiently lookup schema based on model name. - Map m = new HashMap<>(); - ModelUtils.getSchemas(openAPI).forEach((key, schema) -> m.put(toModelName(key), schema)); + Map m = new HashMap(); + ModelUtils.getSchemas(openAPI).forEach((key, schema) -> { + m.put(toModelName(key), schema); + }); modelNameToSchemaCache = Collections.unmodifiableMap(m); } return modelNameToSchemaCache; @@ -515,7 +493,6 @@ public Map getAllModels(Map objs) { * @param objs Map of models * @return maps of models with various updates */ - @Override public Map updateAllModels(Map objs) { Map allModels = getAllModels(objs); @@ -525,7 +502,7 @@ public Map updateAllModels(Map objs) { cm.setParentModel(allModels.get(cm.getParent())); } if (cm.getInterfaces() != null && !cm.getInterfaces().isEmpty()) { - cm.setInterfaceModels(new ArrayList<>(cm.getInterfaces().size())); + cm.setInterfaceModels(new ArrayList(cm.getInterfaces().size())); for (String intf : cm.getInterfaces()) { CodegenModel intfModel = allModels.get(intf); if (intfModel != null) { @@ -543,7 +520,7 @@ public Map updateAllModels(Map objs) { // TODO Determine what to do if the parent discriminator name == the grandparent discriminator name while (parent != null) { if (parent.getChildren() == null) { - parent.setChildren(new ArrayList<>()); + parent.setChildren(new ArrayList()); } parent.getChildren().add(cm); parent.hasChildren = true; @@ -592,13 +569,13 @@ private List getModelDependencies(CodegenModel model) { } return prop.dataType == null ? null : prop; }) - .filter(Objects::nonNull) + .filter(prop -> prop != null) .collect(Collectors.toList()); } private void setCircularReferencesOnProperties(final String root, final Map> dependencyMap) { - dependencyMap.getOrDefault(root, new ArrayList<>()) + dependencyMap.getOrDefault(root, new ArrayList<>()).stream() .forEach(prop -> { final List unvisited = Collections.singletonList(prop.isContainer ? prop.items.dataType : prop.dataType); @@ -628,7 +605,6 @@ private boolean isCircularReference(final String root, } // override with any special post-processing - @Override @SuppressWarnings("static-method") public Map postProcessModels(Map objs) { return objs; @@ -704,8 +680,7 @@ public String findCommonPrefixOfVars(List vars) { String prefix = StringUtils.getCommonPrefix(listStr); // exclude trailing characters that should be part of a valid variable // e.g. ["status-on", "status-off"] => "status-" (not "status-o") - final Matcher matcher = COMMON_PREFIX_ENUM_NAME.matcher(prefix); - return matcher.replaceAll(""); + return prefix.replaceAll("[a-zA-Z0-9]+\\z", ""); } catch (ArrayStoreException e) { // do nothing, just return default value } @@ -733,7 +708,7 @@ public String toEnumDefaultValue(String value, String datatype) { * @return the sanitized value for enum */ public String toEnumValue(String value, String datatype) { - if ("number".equalsIgnoreCase(datatype) || "boolean".equalsIgnoreCase(datatype)) { + if ("number".equalsIgnoreCase(datatype)) { return value; } else { return "\"" + escapeText(value) + "\""; @@ -773,7 +748,6 @@ public void setOpenAPI(OpenAPI openAPI) { } // override with any message to be shown right before the process finishes - @Override @SuppressWarnings("static-method") public void postProcess() { System.out.println("################################################################################"); @@ -784,33 +758,28 @@ public void postProcess() { } // override with any special post-processing - @Override @SuppressWarnings("static-method") public Map postProcessOperationsWithModels(Map objs, List allModels) { return objs; } // override with any special post-processing - @Override @SuppressWarnings("static-method") public Map postProcessSupportingFileData(Map objs) { return objs; } // override to post-process any model properties - @Override @SuppressWarnings("unused") public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { } // override to post-process any parameters - @Override @SuppressWarnings("unused") public void postProcessParameter(CodegenParameter parameter) { } //override with any special handling of the entire OpenAPI spec document - @Override @SuppressWarnings("unused") public void preprocessOpenAPI(OpenAPI openAPI) { if (useOneOfInterfaces) { @@ -895,27 +864,23 @@ public void preprocessOpenAPI(OpenAPI openAPI) { } // override with any special handling of the entire OpenAPI spec document - @Override @SuppressWarnings("unused") public void processOpenAPI(OpenAPI openAPI) { } // override with any special handling of the JMustache compiler - @Override @SuppressWarnings("unused") public Compiler processCompiler(Compiler compiler) { return compiler; } // override with any special handling for the templating engine - @Override @SuppressWarnings("unused") public TemplatingEngineAdapter processTemplatingEngine(TemplatingEngineAdapter templatingEngine) { return templatingEngine; } // override with any special text escaping logic - @Override @SuppressWarnings("static-method") public String escapeText(String input) { if (input == null) { @@ -942,7 +907,6 @@ public String escapeText(String input) { * @param input String to be escaped * @return escaped string */ - @Override public String escapeTextWhileAllowingNewLines(String input) { if (input == null) { return input; @@ -963,7 +927,6 @@ public String escapeTextWhileAllowingNewLines(String input) { } // override with any special encoding and escaping logic - @Override @SuppressWarnings("static-method") public String encodePath(String input) { return escapeText(input); @@ -976,7 +939,6 @@ public String encodePath(String input) { * @param input String to be cleaned up * @return string with unsafe characters removed or escaped */ - @Override public String escapeUnsafeCharacters(String input) { LOGGER.warn("escapeUnsafeCharacters should be overridden in the code generator with proper logic to escape " + "unsafe characters"); @@ -993,69 +955,56 @@ public String escapeUnsafeCharacters(String input) { * @param input String to be cleaned up * @return string with quotation mark removed or escaped */ - @Override public String escapeQuotationMark(String input) { LOGGER.warn("escapeQuotationMark should be overridden in the code generator with proper logic to escape " + "single/double quote"); return input.replace("\"", "\\\""); } - @Override public Set defaultIncludes() { return defaultIncludes; } - @Override public Map typeMapping() { return typeMapping; } - @Override public Map instantiationTypes() { return instantiationTypes; } - @Override public Set reservedWords() { return reservedWords; } - @Override public Set languageSpecificPrimitives() { return languageSpecificPrimitives; } - @Override public Map importMapping() { return importMapping; } - @Override public String testPackage() { return testPackage; } - @Override public String modelPackage() { return modelPackage; } - @Override public String apiPackage() { return apiPackage; } - @Override public String fileSuffix() { return fileSuffix; } - @Override public String templateDir() { return templateDir; } - @Override public String embeddedTemplateDir() { if (embeddedTemplateDir != null) { return embeddedTemplateDir; @@ -1064,112 +1013,90 @@ public String embeddedTemplateDir() { } } - @Override public Map apiDocTemplateFiles() { return apiDocTemplateFiles; } - @Override public Map modelDocTemplateFiles() { return modelDocTemplateFiles; } - @Override public Map reservedWordsMappings() { return reservedWordsMappings; } - @Override public Map apiTestTemplateFiles() { return apiTestTemplateFiles; } - @Override public Map modelTestTemplateFiles() { return modelTestTemplateFiles; } - @Override public Map apiTemplateFiles() { return apiTemplateFiles; } - @Override public Map modelTemplateFiles() { return modelTemplateFiles; } - @Override public String apiFileFolder() { return outputFolder + File.separator + apiPackage().replace('.', File.separatorChar); } - @Override public String modelFileFolder() { return outputFolder + File.separator + modelPackage().replace('.', File.separatorChar); } - @Override public String apiTestFileFolder() { return outputFolder + File.separator + testPackage().replace('.', File.separatorChar); } - @Override public String modelTestFileFolder() { return outputFolder + File.separator + testPackage().replace('.', File.separatorChar); } - @Override public String apiDocFileFolder() { return outputFolder; } - @Override public String modelDocFileFolder() { return outputFolder; } - @Override public Map additionalProperties() { return additionalProperties; } - @Override public Map serverVariableOverrides() { return serverVariables; } - @Override public Map vendorExtensions() { return vendorExtensions; } - @Override public List supportingFiles() { return supportingFiles; } - @Override public String outputFolder() { return outputFolder; } - @Override public void setOutputDir(String dir) { this.outputFolder = dir; } - @Override public String getOutputDir() { return outputFolder(); } - @Override public String getInputSpec() { return inputSpec; } - @Override public void setInputSpec(String inputSpec) { this.inputSpec = inputSpec; } @@ -1298,7 +1225,6 @@ public String toRegularExpression(String pattern) { * @param name the file name of the Api * @return the file name of the Api */ - @Override public String toApiFilename(String name) { return toApiName(name); } @@ -1309,7 +1235,6 @@ public String toApiFilename(String name) { * @param name the file name of the Api * @return the file name of the Api */ - @Override public String toApiDocFilename(String name) { return toApiName(name); } @@ -1320,7 +1245,6 @@ public String toApiDocFilename(String name) { * @param name the file name of the Api * @return the file name of the Api */ - @Override public String toApiTestFilename(String name) { return toApiName(name) + "Test"; } @@ -1331,7 +1255,6 @@ public String toApiTestFilename(String name) { * @param name the varible name of the Api * @return the snake-cased variable name */ - @Override public String toApiVarName(String name) { return lowerCamelCase(name); } @@ -1342,7 +1265,6 @@ public String toApiVarName(String name) { * @param name the model name * @return the file name of the model */ - @Override public String toModelFilename(String name) { return camelize(name); } @@ -1353,7 +1275,6 @@ public String toModelFilename(String name) { * @param name the model name * @return the file name of the model */ - @Override public String toModelTestFilename(String name) { return camelize(name) + "Test"; } @@ -1364,7 +1285,6 @@ public String toModelTestFilename(String name) { * @param name the model name * @return the file name of the model */ - @Override public String toModelDocFilename(String name) { return camelize(name); } @@ -1418,7 +1338,6 @@ public String toVarName(final String name) { * @param name Codegen property object * @return the sanitized parameter name */ - @Override public String toParamName(String name) { name = removeNonNameElementToCamelCase(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. if (reservedWords.contains(name)) { @@ -1459,7 +1378,6 @@ public String toEnumName(CodegenProperty property) { *

* throws Runtime exception as reserved word is not allowed (default behavior) */ - @Override @SuppressWarnings("static-method") public String escapeReservedWord(String name) { throw new RuntimeException("reserved word " + name + " not allowed"); @@ -1471,7 +1389,6 @@ public String escapeReservedWord(String name) { * @param name the name of the "Model" * @return the fully-qualified "Model" name for import */ - @Override public String toModelImport(String name) { if ("".equals(modelPackage())) { return name; @@ -1486,7 +1403,6 @@ public String toModelImport(String name) { * @param name the name of the "Model" * @return Map of fully-qualified models. */ - @Override public Map toModelImportMap(String name){ return Collections.singletonMap(this.toModelImport(name),name); } @@ -1497,7 +1413,6 @@ public Map toModelImportMap(String name){ * @param name the name of the "Api" * @return the fully-qualified "Api" name for import */ - @Override public String toApiImport(String name) { return apiPackage() + "." + name; } @@ -1669,7 +1584,6 @@ protected String getSymbolName(String input) { * @param operation OAS operation object * @return string presentation of the example path */ - @Override @SuppressWarnings("static-method") public String generateExamplePath(String path, Operation operation) { StringBuilder sb = new StringBuilder(); @@ -1710,7 +1624,7 @@ public String generateExamplePath(String path, Operation operation) { } else if (Parameter.StyleEnum.SPACEDELIMITED.equals(qp.getStyle())) { paramPart.append("%20"); } else { - LOGGER.warn("query parameter '{}' style not support: {}", param.getName(), qp.getStyle()); + LOGGER.warn("query parameter '" + param.getName() + "style not support: " + qp.getStyle()); } } else { paramPart.append(param.getName()); @@ -1909,20 +1823,6 @@ public String toDefaultValue(Schema schema) { return getPropertyDefaultValue(schema); } - /** - * Return the default value of the parameter - * - * Return null if you do NOT want a default value. - * Any non-null value will cause {{#defaultValue} check to pass. - * - * @param schema Parameter schema - * @return string presentation of the default value of the parameter - */ - public String toDefaultParameterValue(Schema schema) { - // by default works as original method to be backward compatible - return toDefaultValue(schema); - } - /** * Return property value depending on property type. * @@ -2078,7 +1978,6 @@ public String toOneOfName(List names, ComposedSchema composedSchema) { return "oneOf<" + String.join(",", names) + ">"; } - @Override public Schema unaliasSchema(Schema schema, Map usedImportMappings) { return ModelUtils.unaliasSchema(this.openAPI, schema, usedImportMappings); } @@ -2101,7 +2000,7 @@ protected String getSingleSchemaType(Schema schema) { } return getAlias(schemaName); } else { - LOGGER.warn("Error obtaining the datatype from ref: {}. Default to 'object'", unaliasSchema.get$ref()); + LOGGER.warn("Error obtaining the datatype from ref:" + unaliasSchema.get$ref() + ". Default to 'object'"); return "object"; } } else { // primitive type or model @@ -2122,10 +2021,6 @@ protected String getSingleSchemaType(Schema schema) { private String getPrimitiveType(Schema schema) { if (schema == null) { throw new RuntimeException("schema cannot be null in getPrimitiveType"); - } else if (typeMapping.containsKey(schema.getType() + "+" + schema.getFormat())) { - // allows custom type_format mapping. - // use {type}+{format} - return typeMapping.get(schema.getType() + "+" + schema.getFormat()); } else if (ModelUtils.isNullType(schema)) { // The 'null' type is allowed in OAS 3.1 and above. It is not supported by OAS 3.0.x, // though this tooling supports it. @@ -2193,7 +2088,7 @@ private String getPrimitiveType(Schema schema) { return "AnyType"; } else if (StringUtils.isNotEmpty(schema.getType())) { if (!importMapping.containsKey(schema.getType())) { - LOGGER.warn("Unknown type found in the schema: {}", schema.getType()); + LOGGER.warn("Unknown type found in the schema: " + schema.getType()); } return schema.getType(); } @@ -2221,7 +2116,6 @@ public String lowerCamelCase(String name) { * @param name name * @return a string presentation of the type */ - @Override @SuppressWarnings("static-method") public String getTypeDeclaration(String name) { return name; @@ -2233,7 +2127,6 @@ public String getTypeDeclaration(String name) { * @param schema property schema * @return a string presentation of the property type */ - @Override public String getTypeDeclaration(Schema schema) { if (schema == null) { LOGGER.warn("Null schema found. Default type to `NULL_SCHEMA_ERR`"); @@ -2270,7 +2163,6 @@ public String getAlias(String name) { * @param name the name of the property * @return getter name based on naming convention */ - @Override public String toBooleanGetter(String name) { return "get" + getterAndSetterCapitalize(name); } @@ -2281,7 +2173,6 @@ public String toBooleanGetter(String name) { * @param name the name of the property * @return getter name based on naming convention */ - @Override public String toGetter(String name) { return "get" + getterAndSetterCapitalize(name); } @@ -2292,7 +2183,6 @@ public String toGetter(String name) { * @param name the name of the property * @return setter name based on naming convention */ - @Override public String toSetter(String name) { return "set" + getterAndSetterCapitalize(name); } @@ -2304,7 +2194,6 @@ public String toSetter(String name) { * @param name the name of the Api * @return capitalized Api name */ - @Override public String toApiName(String name) { if (name.length() == 0) { return "DefaultApi"; @@ -2320,7 +2209,6 @@ public String toApiName(String name) { * @param name the name of the model * @return capitalized model name */ - @Override public String toModelName(final String name) { return camelize(modelNamePrefix + "_" + name + "_" + modelNameSuffix); } @@ -2357,7 +2245,6 @@ public int hashCode() { * @param schema OAS Model object * @return Codegen Model object */ - @Override public CodegenModel fromModel(String name, Schema schema) { Map allDefinitions = ModelUtils.getSchemas(this.openAPI); if (typeAliases == null) { @@ -2490,13 +2377,6 @@ public CodegenModel fromModel(String name, Schema schema) { if (StringUtils.isBlank(interfaceSchema.get$ref())) { // primitive type String languageType = getTypeDeclaration(interfaceSchema); - if (ModelUtils.isArraySchema(interfaceSchema) || ModelUtils.isMapSchema(interfaceSchema)) { - CodegenProperty cp = fromProperty("composedSchemaImports", interfaceSchema); - while (cp != null) { - addImport(m, cp.complexType); - cp = cp.items; - } - } if (composed.getAnyOf() != null) { if (m.anyOf.contains(languageType)) { @@ -2626,13 +2506,8 @@ public CodegenModel fromModel(String name, Schema schema) { m.isNumeric = Boolean.TRUE; if (ModelUtils.isLongSchema(schema)) { // int64/long format m.isLong = Boolean.TRUE; - } else { - m.isInteger = Boolean.TRUE; // older use case, int32 and unbounded int - if (ModelUtils.isShortSchema(schema)) { // int32 - m.setIsShort(Boolean.TRUE); - } else { // unbounded integer - m.setIsUnboundedInteger(Boolean.TRUE); - } + } else { // int32 format + m.isInteger = Boolean.TRUE; } } else if (ModelUtils.isDateTimeSchema(schema)) { // NOTE: DateTime schemas as CodegenModel is a rare use case and may be removed at a later date. @@ -2653,8 +2528,6 @@ public CodegenModel fromModel(String name, Schema schema) { } else { // type is number and without format m.isNumber = Boolean.TRUE; } - } else if (ModelUtils.isBooleanSchema(schema)) { - m.isBoolean = Boolean.TRUE; } else if (ModelUtils.isFreeFormObject(openAPI, schema)) { addAdditionPropertiesToCodeGenModel(m, schema); } @@ -2686,10 +2559,6 @@ public CodegenModel fromModel(String name, Schema schema) { } } - if (m.requiredVars != null && m.requiredVars.size() > 0){ - m.setHasRequired(true); - } - if (sortModelPropertiesByRequiredFlag) { Comparator comparator = new Comparator() { @Override @@ -2704,7 +2573,27 @@ public int compare(CodegenProperty one, CodegenProperty another) { } // process 'additionalProperties' - setAddProps(schema, m); + if (schema.getAdditionalProperties() == null) { + if (disallowAdditionalPropertiesIfNotPresent) { + m.isAdditionalPropertiesTrue = false; + } else { + m.isAdditionalPropertiesTrue = true; + CodegenProperty cp = fromProperty("", new Schema()); + m.setAdditionalProperties(cp); + } + } else if (schema.getAdditionalProperties() instanceof Boolean) { + if (Boolean.TRUE.equals(schema.getAdditionalProperties())) { + m.isAdditionalPropertiesTrue = true; + CodegenProperty cp = fromProperty("", new Schema()); + m.setAdditionalProperties(cp); + } else { + m.isAdditionalPropertiesTrue = false; + } + } else { + m.isAdditionalPropertiesTrue = false; + CodegenProperty cp = fromProperty("", (Schema) schema.getAdditionalProperties()); + m.setAdditionalProperties(cp); + } // post process model properties if (m.vars != null) { @@ -2721,60 +2610,15 @@ public int compare(CodegenProperty one, CodegenProperty another) { return m; } - private void setAddProps(Schema schema, IJsonSchemaValidationProperties property){ - if (schema.equals(new Schema())) { - // if we are trying to set additionalProperties on an empty schema stop recursing - return; - } - boolean additionalPropertiesIsAnyType = false; - CodegenModel m = null; - if (property instanceof CodegenModel) { - m = (CodegenModel) property; - } - CodegenProperty addPropProp = null; - boolean isAdditionalPropertiesTrue = false; - if (schema.getAdditionalProperties() == null) { - if (!disallowAdditionalPropertiesIfNotPresent) { - isAdditionalPropertiesTrue = true; - addPropProp = fromProperty("", new Schema()); - additionalPropertiesIsAnyType = true; - } - } else if (schema.getAdditionalProperties() instanceof Boolean) { - if (Boolean.TRUE.equals(schema.getAdditionalProperties())) { - isAdditionalPropertiesTrue = true; - addPropProp = fromProperty("", new Schema()); - additionalPropertiesIsAnyType = true; - } - } else { - addPropProp = fromProperty("", (Schema) schema.getAdditionalProperties()); - if (isAnyTypeSchema((Schema) schema.getAdditionalProperties())) { - additionalPropertiesIsAnyType = true; - } - } - if (additionalPropertiesIsAnyType) { - property.setAdditionalPropertiesIsAnyType(true); - } - if (m != null && isAdditionalPropertiesTrue) { - m.isAdditionalPropertiesTrue = true; - } - if (ModelUtils.isComposedSchema(schema) && !supportsAdditionalPropertiesWithComposedSchema) { - return; - } - if (addPropProp != null) { - property.setAdditionalProperties(addPropProp); - } - } - - - /** - * Recursively look in Schema sc for the discriminator discPropName - * and return a CodegenProperty with the dataType and required params set - * the returned CodegenProperty may not be required and it may not be of type string - * - * @param composedSchemaName The name of the sc Schema - * @param sc The Schema that may contain the discriminator - * @param discPropName The String that is the discriminator propertyName in the schema - */ + /** + * Recursively look in Schema sc for the discriminator discPropName + * and return a CodegenProperty with the dataType and required params set + * the returned CodegenProperty may not be required and it may not be of type string + * + * @param composedSchemaName The name of the sc Schema + * @param sc The Schema that may contain the discriminator + * @param discPropName The String that is the discriminator propertyName in the schema + */ private CodegenProperty discriminatorFound(String composedSchemaName, Schema sc, String discPropName, OpenAPI openAPI) { Schema refSchema = ModelUtils.getReferencedSchema(openAPI, sc); if (refSchema.getProperties() != null && refSchema.getProperties().get(discPropName) != null) { @@ -2807,18 +2651,14 @@ private CodegenProperty discriminatorFound(String composedSchemaName, Schema sc, String modelName = ModelUtils.getSimpleRef(oneOf.get$ref()); CodegenProperty thisCp = discriminatorFound(composedSchemaName, oneOf, discPropName, openAPI); if (thisCp == null) { - LOGGER.warn( - "'{}' defines discriminator '{}', but the referenced OneOf schema '{}' is missing {}", - composedSchemaName, discPropName, modelName, discPropName); + throw new RuntimeException("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the referenced OneOf schema '" + modelName + "' is missing " + discPropName); } if (cp.dataType == null) { cp = thisCp; continue; } if (cp != thisCp) { - LOGGER.warn( - "'{}' defines discriminator '{}', but the OneOf schema '{}' has a different {} definition than the prior OneOf schema's. Make sure the {} type and required values are the same", - composedSchemaName, discPropName, modelName, discPropName, discPropName); + throw new RuntimeException("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the OneOf schema '" + modelName + "' has a different " + discPropName + " definition than the prior OneOf schema's. Make sure the " + discPropName + " type and required values are the same"); } } return cp; @@ -2830,18 +2670,14 @@ private CodegenProperty discriminatorFound(String composedSchemaName, Schema sc, String modelName = ModelUtils.getSimpleRef(anyOf.get$ref()); CodegenProperty thisCp = discriminatorFound(composedSchemaName, anyOf, discPropName, openAPI); if (thisCp == null) { - LOGGER.warn( - "'{}' defines discriminator '{}', but the referenced AnyOf schema '{}' is missing {}", - composedSchemaName, discPropName, modelName, discPropName); + throw new RuntimeException("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the referenced AnyOf schema '" + modelName + "' is missing " + discPropName); } - if (cp != null && cp.dataType == null) { + if (cp.dataType == null) { cp = thisCp; continue; } if (cp != thisCp) { - LOGGER.warn( - "'{}' defines discriminator '{}', but the AnyOf schema '{}' has a different {} definition than the prior AnyOf schema's. Make sure the {} type and required values are the same", - composedSchemaName, discPropName, modelName, discPropName, discPropName); + throw new RuntimeException("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the AnyOf schema '" + modelName + "' has a different " + discPropName + " definition than the prior AnyOf schema's. Make sure the " + discPropName + " type and required values are the same"); } } return cp; @@ -2900,7 +2736,7 @@ private Discriminator recursiveGetDiscriminator(Schema sc, OpenAPI openAPI) { } } if (discriminatorsPropNames.size() > 1) { - LOGGER.warn("The oneOf schemas have conflicting discriminator property names. " + + throw new RuntimeException("The oneOf schemas have conflicting discriminator property names. " + "oneOf schemas must have the same property name, but found " + String.join(", ", discriminatorsPropNames)); } if (foundDisc != null && (hasDiscriminatorCnt + hasNullTypeCnt) == composedSchema.getOneOf().size() && discriminatorsPropNames.size() == 1) { @@ -2929,7 +2765,7 @@ private Discriminator recursiveGetDiscriminator(Schema sc, OpenAPI openAPI) { } } if (discriminatorsPropNames.size() > 1) { - LOGGER.warn("The anyOf schemas have conflicting discriminator property names. " + + throw new RuntimeException("The anyOf schemas have conflicting discriminator property names. " + "anyOf schemas must have the same property name, but found " + String.join(", ", discriminatorsPropNames)); } if (foundDisc != null && (hasDiscriminatorCnt + hasNullTypeCnt) == composedSchema.getAnyOf().size() && discriminatorsPropNames.size() == 1) { @@ -2959,10 +2795,10 @@ private Discriminator recursiveGetDiscriminator(Schema sc, OpenAPI openAPI) { * @return the list of oneOf and anyOf MappedModel that need to be added to the discriminator map */ protected List getOneOfAnyOfDescendants(String composedSchemaName, String discPropName, ComposedSchema c, OpenAPI openAPI) { - ArrayList> listOLists = new ArrayList<>(); + ArrayList> listOLists = new ArrayList>(); listOLists.add(c.getOneOf()); listOLists.add(c.getAnyOf()); - List descendentSchemas = new ArrayList<>(); + List descendentSchemas = new ArrayList(); for (List schemaList : listOLists) { if (schemaList == null) { continue; @@ -2979,9 +2815,7 @@ protected List getOneOfAnyOfDescendants(String composedSchemaName, // schemas also has inline composed schemas // Note: if it is only inline one level, then the inline model resolver will move it into its own // schema and make it a $ref schema in the oneOf/anyOf location - LOGGER.warn( - "Invalid inline schema defined in oneOf/anyOf in '{}'. Per the OpenApi spec, for this case when a composed schema defines a discriminator, the oneOf/anyOf schemas must use $ref. Change this inline definition to a $ref definition", - composedSchemaName); + throw new RuntimeException("Invalid inline schema defined in oneOf/anyOf in '" + composedSchemaName + "'. Per the OpenApi spec, for this case when a composed schema defines a discriminator, the oneOf/anyOf schemas must use $ref. Change this inline definition to a $ref definition"); } CodegenProperty df = discriminatorFound(composedSchemaName, sc, discPropName, openAPI); String modelName = ModelUtils.getSimpleRef(ref); @@ -3001,8 +2835,7 @@ protected List getOneOfAnyOfDescendants(String composedSchemaName, msgSuffix += spacer + "invalid optional definition of " + discPropName + ", include it in required"; } } - LOGGER.warn("'{}' defines discriminator '{}', but the referenced schema '{}' is incorrect. {}", - composedSchemaName, discPropName, modelName, msgSuffix); + throw new RuntimeException("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the referenced schema '" + modelName + "' is incorrect. " + msgSuffix); } MappedModel mm = new MappedModel(modelName, toModelName(modelName)); descendentSchemas.add(mm); @@ -3208,7 +3041,7 @@ public String getterAndSetterCapitalize(String name) { /** * Convert OAS Property object to Codegen Property object. - * + * * The return value is cached. An internal cache is looked up to determine * if the CodegenProperty return value has already been instantiated for * the (String name, Schema p) arguments. @@ -3224,11 +3057,11 @@ public CodegenProperty fromProperty(String name, Schema p) { LOGGER.error("Undefined property/schema for `{}`. Default to type:string.", name); return null; } - LOGGER.debug("debugging fromProperty for {} : {}", name, p); + LOGGER.debug("debugging fromProperty for " + name + " : " + p); NamedSchema ns = new NamedSchema(name, p); CodegenProperty cpc = schemaCodegenPropertyCache.get(ns); if (cpc != null) { - LOGGER.debug("Cached fromProperty for {} : {}", name, p.getName()); + LOGGER.debug("Cached fromProperty for " + name + " : " + p.getName()); return cpc; } // unalias schema @@ -3251,14 +3084,7 @@ public CodegenProperty fromProperty(String name, Schema p) { property.title = p.getTitle(); property.getter = toGetter(name); property.setter = toSetter(name); - // put toExampleValue in a try-catch block to log the error as example values are not critical - try { - property.example = toExampleValue(p); - } catch (Exception e) { - LOGGER.error("Error in generating `example` for the property {}. Default to ERROR_TO_EXAMPLE_VALUE. Enable debugging for more info.", property.baseName); - LOGGER.debug("Exception from toExampleValue: {}", e); - property.example = "ERROR_TO_EXAMPLE_VALUE"; - } + property.example = toExampleValue(p); property.defaultValue = toDefaultValue(p); property.defaultValueWithParam = toDefaultValueWithParam(name, p); property.jsonSchema = Json.pretty(p); @@ -3297,11 +3123,6 @@ public CodegenProperty fromProperty(String name, Schema p) { } if (p.getExtensions() != null && !p.getExtensions().isEmpty()) { property.getVendorExtensions().putAll(p.getExtensions()); - } else if (p.get$ref() != null) { - Schema referencedSchema = ModelUtils.getReferencedSchema(this.openAPI, p); - if (referencedSchema.getExtensions() != null && !referencedSchema.getExtensions().isEmpty()) { - property.getVendorExtensions().putAll(referencedSchema.getExtensions()); - } } String type = getSchemaType(p); @@ -3309,14 +3130,10 @@ public CodegenProperty fromProperty(String name, Schema p) { property.isNumeric = Boolean.TRUE; if (ModelUtils.isLongSchema(p)) { // int64/long format property.isLong = Boolean.TRUE; - } else { - property.isInteger = Boolean.TRUE; // older use case, int32 and unbounded int - if (ModelUtils.isShortSchema(p)) { // int32 - property.setIsShort(Boolean.TRUE); - } else { // unbounded integer - property.setIsUnboundedInteger(Boolean.TRUE); - } + } else { // int32 format + property.isInteger = Boolean.TRUE; } + } else if (ModelUtils.isBooleanSchema(p)) { // boolean type property.isBoolean = true; property.getter = toBooleanGetter(name); @@ -3496,8 +3313,8 @@ public CodegenProperty fromProperty(String name, Schema p) { property.isModel = (ModelUtils.isComposedSchema(refOrCurrent) || ModelUtils.isObjectSchema(refOrCurrent)) && ModelUtils.isModel(refOrCurrent); } - addVarsRequiredVarsAdditionalProps(p, property); - LOGGER.debug("debugging from property return: {}", property); + addVarsRequiredVarsAdditionaProps(p, property); + LOGGER.debug("debugging from property return: " + property); schemaCodegenPropertyCache.put(ns, property); return property; } @@ -3510,9 +3327,7 @@ public CodegenProperty fromProperty(String name, Schema p) { */ protected void updatePropertyForArray(CodegenProperty property, CodegenProperty innerProperty) { if (innerProperty == null) { - if(LOGGER.isWarnEnabled()) { - LOGGER.warn("skipping invalid array property {}", Json.pretty(property)); - } + LOGGER.warn("skipping invalid array property " + Json.pretty(property)); return; } property.dataFormat = innerProperty.dataFormat; @@ -3545,9 +3360,7 @@ protected void updatePropertyForArray(CodegenProperty property, CodegenProperty */ protected void updatePropertyForMap(CodegenProperty property, CodegenProperty innerProperty) { if (innerProperty == null) { - if(LOGGER.isWarnEnabled()) { - LOGGER.warn("skipping invalid map property {}", Json.pretty(property)); - } + LOGGER.warn("skipping invalid map property " + Json.pretty(property)); return; } if (!languageSpecificPrimitives.contains(innerProperty.baseType)) { @@ -3596,7 +3409,7 @@ protected CodegenProperty getMostInnerItems(CodegenProperty property) { protected Map getInnerEnumAllowableValues(CodegenProperty property) { CodegenProperty currentProperty = getMostInnerItems(property); - return currentProperty == null ? new HashMap<>() : currentProperty.allowableValues; + return currentProperty == null ? new HashMap() : currentProperty.allowableValues; } /** @@ -3736,18 +3549,14 @@ protected void handleMethodResponse(Operation operation, } } - // check skipOperationExample, which can be set to true to avoid out of memory errors for large spec - if (!isSkipOperationExample()) { - // generate examples - String exampleStatusCode = "200"; - for (String key : operation.getResponses().keySet()) { - if (operation.getResponses().get(key) == methodResponse && !key.equals("default")) { - exampleStatusCode = key; - } + // generate examples + String exampleStatusCode = "200"; + for (String key : operation.getResponses().keySet()) { + if (operation.getResponses().get(key) == methodResponse && !key.equals("default")) { + exampleStatusCode = key; } - op.examples = new ExampleGenerator(schemas, this.openAPI).generateFromResponseSchema(exampleStatusCode, responseSchema, getProducesInfo(this.openAPI, operation)); } - + op.examples = new ExampleGenerator(schemas, this.openAPI).generateFromResponseSchema(exampleStatusCode, responseSchema, getProducesInfo(this.openAPI, operation)); op.defaultResponse = toDefaultValue(responseSchema); op.returnType = cm.dataType; op.returnFormat = cm.dataFormat; @@ -3793,12 +3602,11 @@ protected void handleMethodResponse(Operation operation, * @param servers list of servers * @return Codegen Operation object */ - @Override public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, List servers) { - LOGGER.debug("fromOperation => operation: {}", operation); + LOGGER.debug("fromOperation => operation: " + operation); if (operation == null) throw new RuntimeException("operation cannot be null in fromOperation"); @@ -3827,14 +3635,9 @@ public CodegenOperation fromOperation(String path, String operationId = getOrGenerateOperationId(operation, path, httpMethod); // remove prefix in operationId if (removeOperationIdPrefix) { - // The prefix is everything before the removeOperationIdPrefixCount occurrence of removeOperationIdPrefixDelimiter - String[] componenets = operationId.split("[" + removeOperationIdPrefixDelimiter + "]"); - if (componenets.length > 1) { - // If removeOperationIdPrefixCount is -1 or bigger that the number of occurrences, uses the last one - int componenet_number = removeOperationIdPrefixCount == -1 ? componenets.length - 1 : removeOperationIdPrefixCount; - componenet_number = Math.min(componenet_number, componenets.length - 1); - // Reconstruct the operationId from its split elements and the delimiter - operationId = String.join(removeOperationIdPrefixDelimiter, Arrays.copyOfRange(componenets, componenet_number, componenets.length)); + int offset = operationId.indexOf('_'); + if (offset > -1) { + operationId = operationId.substring(offset + 1); } } operationId = removeNonNameElementToCamelCase(operationId); @@ -3967,7 +3770,7 @@ public CodegenOperation fromOperation(String path, // ensure unique params if (ensureUniqueParams) { - while (!isParameterNameUnique(p, allParams)) { + if (!isParameterNameUnique(p, allParams)) { p.paramName = generateNextName(p.paramName); } } @@ -3983,7 +3786,7 @@ public CodegenOperation fromOperation(String path, } else if (param instanceof CookieParameter || "cookie".equalsIgnoreCase(param.getIn())) { cookieParams.add(p.copy()); } else { - LOGGER.warn("Unknown parameter type {} for {}", p.baseType, p.baseName); + LOGGER.warn("Unknown parameter type " + p.baseType + " for " + p.baseName); } } @@ -3993,7 +3796,7 @@ public CodegenOperation fromOperation(String path, if (!prependFormOrBodyParameters) { for (CodegenParameter cp : formParams) { if (ensureUniqueParams) { - while (!isParameterNameUnique(cp, allParams)) { + if (!isParameterNameUnique(cp, allParams)) { cp.paramName = generateNextName(cp.paramName); } } @@ -4002,7 +3805,7 @@ public CodegenOperation fromOperation(String path, for (CodegenParameter cp : bodyParams) { if (ensureUniqueParams) { - while (!isParameterNameUnique(cp, allParams)) { + if (!isParameterNameUnique(cp, allParams)) { cp.paramName = generateNextName(cp.paramName); } } @@ -4194,11 +3997,6 @@ public CodegenResponse fromResponse(String responseCode, ApiResponse response) { } else if (Boolean.TRUE.equals(cp.isInteger)) { r.isInteger = true; r.isNumeric = true; - if (Boolean.TRUE.equals(cp.isShort)) { - r.isShort = true; - } else if (Boolean.TRUE.equals(cp.isUnboundedInteger)) { - r.isUnboundedInteger = true; - } } else if (Boolean.TRUE.equals(cp.isNumber)) { r.isNumber = true; r.isNumeric = true; @@ -4225,7 +4023,7 @@ public CodegenResponse fromResponse(String responseCode, ApiResponse response) { } else if (Boolean.TRUE.equals(cp.isAnyType)) { r.isAnyType = true; } else { - LOGGER.debug("Property type is not primitive: {}", cp.dataType); + LOGGER.debug("Property type is not primitive: " + cp.dataType); } if (cp.isContainer) { @@ -4241,7 +4039,7 @@ public CodegenResponse fromResponse(String responseCode, ApiResponse response) { r.primitiveType = (r.baseType == null || languageSpecificPrimitives().contains(r.baseType)); - addVarsRequiredVarsAdditionalProps(responseSchema, r); + addVarsRequiredVarsAdditionaProps(responseSchema, r); } if (r.baseType == null) { @@ -4337,8 +4135,8 @@ public CodegenParameter fromParameter(Parameter parameter, Set imports) codegenParameter.jsonSchema = Json.pretty(parameter); if (GlobalSettings.getProperty("debugParser") != null) { - LOGGER.info("working on Parameter {}", parameter.getName()); - LOGGER.info("JSON schema: {}", codegenParameter.jsonSchema); + LOGGER.info("working on Parameter " + parameter.getName()); + LOGGER.info("JSON schema: " + codegenParameter.jsonSchema); } if (parameter.getExtensions() != null && !parameter.getExtensions().isEmpty()) { @@ -4363,7 +4161,7 @@ public CodegenParameter fromParameter(Parameter parameter, Set imports) if (parameterSchema != null) { parameterSchema = unaliasSchema(parameterSchema, Collections.emptyMap()); if (parameterSchema == null) { - LOGGER.warn("warning! Schema not found for parameter \" {} \", using String", parameter.getName()); + LOGGER.warn("warning! Schema not found for parameter \"" + parameter.getName() + "\", using String"); parameterSchema = new StringSchema().description("//TODO automatically added by openapi-generator due to missing type definition."); } ModelUtils.syncValidationProperties(parameterSchema, codegenParameter); @@ -4373,19 +4171,17 @@ public CodegenParameter fromParameter(Parameter parameter, Set imports) } // set default value - codegenParameter.defaultValue = toDefaultParameterValue(parameterSchema); + codegenParameter.defaultValue = toDefaultValue(parameterSchema); if (parameter.getStyle() != null) { codegenParameter.style = parameter.getStyle().toString(); - codegenParameter.isDeepObject = Parameter.StyleEnum.DEEPOBJECT == parameter.getStyle(); } // the default value is false // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#user-content-parameterexplode codegenParameter.isExplode = parameter.getExplode() == null ? false : parameter.getExplode(); - // TODO revise collectionFormat, default collection format in OAS 3 appears to multi at least for query parameters - // https://swagger.io/docs/specification/serialization/ + // TODO revise collectionFormat String collectionFormat = null; if (ModelUtils.isArraySchema(parameterSchema)) { // for array parameter final ArraySchema arraySchema = (ArraySchema) parameterSchema; @@ -4513,10 +4309,10 @@ public CodegenParameter fromParameter(Parameter parameter, Set imports) codegenParameter.pattern != null || codegenParameter.multipleOf != null) { codegenParameter.hasValidation = true; } - addVarsRequiredVarsAdditionalProps(parameterSchema, codegenParameter); + addVarsRequiredVarsAdditionaProps(parameterSchema, codegenParameter); } else { - LOGGER.error("Not handling {} as Body Parameter at the moment", parameter); + LOGGER.error("ERROR! Not handling " + parameter + " as Body Parameter at the moment"); } if (parameter instanceof QueryParameter || "query".equalsIgnoreCase(parameter.getIn())) { @@ -4529,7 +4325,7 @@ public CodegenParameter fromParameter(Parameter parameter, Set imports) } else if (parameter instanceof CookieParameter || "cookie".equalsIgnoreCase(parameter.getIn())) { codegenParameter.isCookieParam = true; } else { - LOGGER.warn("Unknown parameter type: {}", parameter.getName()); + LOGGER.warn("Unknown parameter type: " + parameter.getName()); } // default to UNKNOWN_PARAMETER_NAME if paramName is null @@ -4538,34 +4334,12 @@ public CodegenParameter fromParameter(Parameter parameter, Set imports) codegenParameter.paramName = "UNKNOWN_PARAMETER_NAME"; } - if (codegenParameter.isQueryParam && codegenParameter.isDeepObject) { - Schema schema = ModelUtils.getSchema(openAPI, codegenParameter.dataType); - codegenParameter.items = fromProperty(codegenParameter.paramName, schema); - // TODO Check why schema is actually null for a schema of type object defined inline - // https://swagger.io/docs/specification/serialization/ - if(schema != null) { - Map> properties = schema.getProperties(); - codegenParameter.items.vars = - properties.entrySet().stream() - .map(entry -> { - CodegenProperty property = fromProperty(entry.getKey(), entry.getValue()); - property.baseName = codegenParameter.baseName + "[" + entry.getKey() + "]"; - return property; - }).collect(Collectors.toList()); - } - else { - LOGGER.warn( - "No object schema found for deepObject parameter{} deepObject won't have specific properties", - codegenParameter); - } - } - // set the parameter example value // should be overridden by lang codegen setParameterExampleValue(codegenParameter, parameter); postProcessParameter(codegenParameter); - LOGGER.debug("debugging codegenParameter return: {}", codegenParameter); + LOGGER.debug("debugging codegenParameter return: " + codegenParameter); return codegenParameter; } @@ -4609,7 +4383,6 @@ public boolean isDataTypeFile(String dataType) { * @param securitySchemeMap a map of OAS SecuritySchemeDefinition object * @return a list of Codegen Security objects */ - @Override @SuppressWarnings("static-method") public List fromSecurity(Map securitySchemeMap) { if (securitySchemeMap == null) { @@ -4757,7 +4530,7 @@ protected String getOrGenerateOperationId(Operation operation, String path, Stri } } operationId = sanitizeName(builder.toString()); - LOGGER.warn("Empty operationId found for path: {} {}. Renamed to auto-generated operationId: {}", httpMethod, path, operationId); + LOGGER.warn("Empty operationId found for path: " + httpMethod + " " + path + ". Renamed to auto-generated operationId: " + operationId); } return operationId; } @@ -4804,7 +4577,7 @@ protected void addHeaders(ApiResponse response, List properties Schema schema; if (header.getSchema() == null) { - LOGGER.warn("No schema defined for Header '{}', using a String schema", headerEntry.getKey()); + LOGGER.warn("No schema defined for Header '" + headerEntry.getKey() + "', using a String schema"); schema = new StringSchema(); } else { schema = header.getSchema(); @@ -4831,7 +4604,6 @@ protected void addHeaders(ApiResponse response, List properties * @param co Codegen Operation object * @param operations map of Codegen operations */ - @Override @SuppressWarnings("static-method") public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map> operations) { @@ -4850,7 +4622,7 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera } } if (!co.operationId.equals(uniqueName)) { - LOGGER.warn("generated unique operationId `{}`", uniqueName); + LOGGER.warn("generated unique operationId `" + uniqueName + "`"); } co.operationId = uniqueName; co.operationIdLowerCase = uniqueName.toLowerCase(Locale.ROOT); @@ -4865,13 +4637,13 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera * of the 'additionalProperties' keyword. Some language generator use class inheritance * to implement additional properties. For example, in Java the generated model class * has 'extends HashMap' to represent the additional properties. - * + * * TODO: it's not a good idea to use single class inheritance to implement * additionalProperties. That may work for non-composed schemas, but that does not * work for composed 'allOf' schemas. For example, in Java, if additionalProperties * is set to true (which it should be by default, per OAS spec), then the generated * code has extends HashMap. That wouldn't work for composed 'allOf' schemas. - * + * * @param model the codegen representation of the OAS schema. * @param name the name of the model. * @param schema the input OAS schema. @@ -5005,7 +4777,7 @@ private void addVars(IJsonSchemaValidationProperties m, List va final String key = entry.getKey(); final Schema prop = entry.getValue(); if (prop == null) { - LOGGER.warn("Please report the issue. There shouldn't be null property for {}", key); + LOGGER.warn("Please report the issue. There shouldn't be null property for " + key); } else { final CodegenProperty cp = fromProperty(key, prop); cp.required = mandatory.contains(key); @@ -5099,7 +4871,7 @@ private static Boolean isAliasOfSimpleTypes(Schema schema) { */ @SuppressWarnings("static-method") public String removeNonNameElementToCamelCase(String name) { - return removeNonNameElementToCamelCase(name, "[-_:;#" + removeOperationIdPrefixDelimiter + "]"); + return removeNonNameElementToCamelCase(name, "[-_:;#]"); } /** @@ -5119,13 +4891,11 @@ protected String removeNonNameElementToCamelCase(final String name, final String return result; } - @Override public String apiFilename(String templateName, String tag) { String suffix = apiTemplateFiles().get(templateName); return apiFileFolder() + File.separator + toApiFilename(tag) + suffix; } - @Override public String modelFilename(String templateName, String modelName) { String suffix = modelTemplateFiles().get(templateName); return modelFileFolder() + File.separator + toModelFilename(modelName) + suffix; @@ -5138,7 +4908,6 @@ public String modelFilename(String templateName, String modelName) { * @param tag tag * @return the API documentation file name with full path */ - @Override public String apiDocFilename(String templateName, String tag) { String docExtension = getDocExtension(); String suffix = docExtension != null ? docExtension : apiDocTemplateFiles().get(templateName); @@ -5152,69 +4921,35 @@ public String apiDocFilename(String templateName, String tag) { * @param tag tag * @return the API test file name with full path */ - @Override public String apiTestFilename(String templateName, String tag) { String suffix = apiTestTemplateFiles().get(templateName); return apiTestFileFolder() + File.separator + toApiTestFilename(tag) + suffix; } - @Override public boolean shouldOverwrite(String filename) { return !(skipOverwrite && new File(filename).exists()); } - @Override public boolean isSkipOverwrite() { return skipOverwrite; } - @Override public void setSkipOverwrite(boolean skipOverwrite) { this.skipOverwrite = skipOverwrite; } - @Override public boolean isRemoveOperationIdPrefix() { return removeOperationIdPrefix; } - @Override - public boolean isSkipOperationExample() { - return skipOperationExample; - } - - @Override public void setRemoveOperationIdPrefix(boolean removeOperationIdPrefix) { this.removeOperationIdPrefix = removeOperationIdPrefix; } - public String getRemoveOperationIdPrefixDelimiter() { - return removeOperationIdPrefixDelimiter; - } - - public void setRemoveOperationIdPrefixDelimiter(String removeOperationIdPrefixDelimiter) { - this.removeOperationIdPrefixDelimiter = removeOperationIdPrefixDelimiter; - } - - public int getRemoveOperationIdPrefixCount() { - return removeOperationIdPrefixCount; - } - - public void setRemoveOperationIdPrefixCount(int removeOperationIdPrefixCount) { - this.removeOperationIdPrefixCount = removeOperationIdPrefixCount; - } - - @Override - public void setSkipOperationExample(boolean skipOperationExample) { - this.skipOperationExample = skipOperationExample; - } - - @Override public boolean isHideGenerationTimestamp() { return hideGenerationTimestamp; } - @Override public void setHideGenerationTimestamp(boolean hideGenerationTimestamp) { this.hideGenerationTimestamp = hideGenerationTimestamp; } @@ -5225,7 +4960,6 @@ public void setHideGenerationTimestamp(boolean hideGenerationTimestamp) { * * @return the supported libraries */ - @Override public Map supportedLibraries() { return supportedLibraries; } @@ -5235,7 +4969,6 @@ public Map supportedLibraries() { * * @param library Library template */ - @Override public void setLibrary(String library) { if (library != null && !supportedLibraries.containsKey(library)) { StringBuilder sb = new StringBuilder("Unknown library: " + library + "\nAvailable libraries:"); @@ -5256,7 +4989,6 @@ public void setLibrary(String library) { * * @return Library template */ - @Override public String getLibrary() { return library; } @@ -5275,7 +5007,6 @@ public final boolean isLibrary(String library) { * * @param gitHost Git host */ - @Override public void setGitHost(String gitHost) { this.gitHost = gitHost; } @@ -5285,7 +5016,6 @@ public void setGitHost(String gitHost) { * * @return Git host */ - @Override public String getGitHost() { return gitHost; } @@ -5295,7 +5025,6 @@ public String getGitHost() { * * @param gitUserId Git user ID */ - @Override public void setGitUserId(String gitUserId) { this.gitUserId = gitUserId; } @@ -5305,7 +5034,6 @@ public void setGitUserId(String gitUserId) { * * @return Git user ID */ - @Override public String getGitUserId() { return gitUserId; } @@ -5315,7 +5043,6 @@ public String getGitUserId() { * * @param gitRepoId Git repo ID */ - @Override public void setGitRepoId(String gitRepoId) { this.gitRepoId = gitRepoId; } @@ -5325,7 +5052,6 @@ public void setGitRepoId(String gitRepoId) { * * @return Git repo ID */ - @Override public String getGitRepoId() { return gitRepoId; } @@ -5335,7 +5061,6 @@ public String getGitRepoId() { * * @param releaseNote Release note */ - @Override public void setReleaseNote(String releaseNote) { this.releaseNote = releaseNote; } @@ -5345,7 +5070,6 @@ public void setReleaseNote(String releaseNote) { * * @return Release note */ - @Override public String getReleaseNote() { return releaseNote; } @@ -5355,7 +5079,6 @@ public String getReleaseNote() { * * @return Documentation files extension */ - @Override public String getDocExtension() { return docExtension; } @@ -5365,7 +5088,6 @@ public String getDocExtension() { * * @param userDocExtension documentation files extension */ - @Override public void setDocExtension(String userDocExtension) { this.docExtension = userDocExtension; } @@ -5375,7 +5097,6 @@ public void setDocExtension(String userDocExtension) { * * @param httpUserAgent HTTP user agent */ - @Override public void setHttpUserAgent(String httpUserAgent) { this.httpUserAgent = httpUserAgent; } @@ -5385,7 +5106,6 @@ public void setHttpUserAgent(String httpUserAgent) { * * @return HTTP user agent */ - @Override public String getHttpUserAgent() { return httpUserAgent; } @@ -5405,7 +5125,6 @@ protected CliOption buildLibraryCliOption(Map supportedLibraries * @param name string to be sanitize * @return sanitized string */ - @Override @SuppressWarnings("static-method") public String sanitizeName(String name) { return sanitizeName(name, "\\W"); @@ -5515,7 +5234,6 @@ private String sanitizeValue(String value, String replaceMatch, String replaceVa * @param tag Tag * @return Sanitized tag */ - @Override public String sanitizeTag(String tag) { tag = camelize(sanitizeName(tag)); @@ -5565,11 +5283,6 @@ public void setParameterBooleanFlagWithCodegenProperty(CodegenParameter paramete } else if (Boolean.TRUE.equals(property.isInteger)) { parameter.isInteger = true; parameter.isPrimitiveType = true; - if (Boolean.TRUE.equals(property.isShort)) { - parameter.isShort = true; - } else if (Boolean.TRUE.equals(property.isUnboundedInteger)) { - parameter.isUnboundedInteger = true; - } } else if (Boolean.TRUE.equals(property.isDouble)) { parameter.isDouble = true; parameter.isPrimitiveType = true; @@ -5593,7 +5306,7 @@ public void setParameterBooleanFlagWithCodegenProperty(CodegenParameter paramete } else if (Boolean.TRUE.equals(property.isAnyType)) { parameter.isAnyType = true; } else { - LOGGER.debug("Property type is not primitive: {}", property.dataType); + LOGGER.debug("Property type is not primitive: " + property.dataType); } if (Boolean.TRUE.equals(property.isFile)) { @@ -5644,9 +5357,13 @@ public void updateCodegenPropertyEnum(CodegenProperty var) { // handle default value for enum, e.g. available => StatusEnum.AVAILABLE if (var.defaultValue != null) { - final String enumDefaultValue = getEnumDefaultValue(var.defaultValue, dataType); - String enumName = null; + final String enumDefaultValue; + if (isDataTypeString(dataType)) { + enumDefaultValue = toEnumValue(var.defaultValue, dataType); + } else { + enumDefaultValue = var.defaultValue; + } for (Map enumVar : enumVars) { if (enumDefaultValue.equals(enumVar.get("value"))) { enumName = (String) enumVar.get("name"); @@ -5659,16 +5376,6 @@ public void updateCodegenPropertyEnum(CodegenProperty var) { } } - protected String getEnumDefaultValue(String defaultValue, String dataType) { - final String enumDefaultValue; - if (isDataTypeString(dataType)) { - enumDefaultValue = toEnumValue(defaultValue, dataType); - } else { - enumDefaultValue = defaultValue; - } - return enumDefaultValue; - } - protected List> buildEnumVars(List values, String dataType) { List> enumVars = new ArrayList<>(); int truncateIdx = 0; @@ -5755,7 +5462,6 @@ public boolean convertPropertyToBooleanAndWriteBack(String propertyKey) { * * @return a string of the full path to an override ignore file. */ - @Override public String getIgnoreFilePathOverride() { return ignoreFilePathOverride; } @@ -5765,14 +5471,13 @@ public String getIgnoreFilePathOverride() { * * @param ignoreFileOverride The full path to an ignore file */ - @Override public void setIgnoreFilePathOverride(final String ignoreFileOverride) { this.ignoreFilePathOverride = ignoreFileOverride; } public boolean convertPropertyToBoolean(String propertyKey) { final Object booleanValue = additionalProperties.get(propertyKey); - boolean result = Boolean.FALSE; + Boolean result = Boolean.FALSE; if (booleanValue instanceof Boolean) { result = (Boolean) booleanValue; } else if (booleanValue instanceof String) { @@ -5798,10 +5503,10 @@ protected String getContentType(RequestBody requestBody) { private void setOauth2Info(CodegenSecurity codegenSecurity, OAuthFlow flow) { codegenSecurity.authorizationUrl = flow.getAuthorizationUrl(); codegenSecurity.tokenUrl = flow.getTokenUrl(); - codegenSecurity.refreshUrl = flow.getRefreshUrl(); if (flow.getScopes() != null && !flow.getScopes().isEmpty()) { List> scopes = new ArrayList<>(); + int count = 0, numScopes = flow.getScopes().size(); for (Map.Entry scopeEntry : flow.getScopes().entrySet()) { Map scope = new HashMap<>(); scope.put("scope", scopeEntry.getKey()); @@ -5820,6 +5525,7 @@ private void addConsumesInfo(Operation operation, CodegenOperation codegenOperat Set consumes = requestBody.getContent().keySet(); List> mediaTypeList = new ArrayList<>(); + int count = 0; for (String key : consumes) { Map mediaType = new HashMap<>(); if ("*/*".equals(key)) { @@ -5890,12 +5596,13 @@ private void addProducesInfo(ApiResponse inputResponse, CodegenOperation codegen existingMediaTypes.add(mediaType.get("mediaType")); } + int count = 0; for (String key : produces) { // escape quotation to avoid code injection, "*/*" is a special case, do nothing String encodedKey = "*/*".equals(key) ? key : escapeText(escapeQuotationMark(key)); //Only unique media types should be added to "produces" if (!existingMediaTypes.contains(encodedKey)) { - Map mediaType = new HashMap<>(); + Map mediaType = new HashMap(); mediaType.put("mediaType", encodedKey); codegenOperation.produces.add(mediaType); codegenOperation.hasProduces = Boolean.TRUE; @@ -5946,24 +5653,21 @@ protected String getCollectionFormat(Parameter parameter) { } } - @Override public CodegenType getTag() { return null; } - @Override public String getName() { return null; } - @Override public String getHelp() { return null; } public List fromRequestBodyToFormParameters(RequestBody body, Set imports) { - List parameters = new ArrayList<>(); - LOGGER.debug("debugging fromRequestBodyToFormParameters= {}", body); + List parameters = new ArrayList(); + LOGGER.debug("debugging fromRequestBodyToFormParameters= " + body); Schema schema = ModelUtils.getSchemaFromRequestBody(body); schema = ModelUtils.getReferencedSchema(this.openAPI, schema); List allRequired = new ArrayList(); @@ -5972,7 +5676,7 @@ public List fromRequestBodyToFormParameters(RequestBody body, if (!properties.isEmpty()) { for (Map.Entry entry : properties.entrySet()) { - CodegenParameter codegenParameter; + CodegenParameter codegenParameter = CodegenModelFactory.newInstance(CodegenModelType.PARAMETER); // key => property name // value => property schema Schema s = entry.getValue(); @@ -5994,7 +5698,7 @@ public List fromRequestBodyToFormParameters(RequestBody body, if (codegenParameter.baseType != null && codegenParameter.enumName != null) { codegenParameter.datatypeWithEnum = codegenParameter.dataType.replace(codegenParameter.baseType, codegenParameter.enumName); } else { - LOGGER.warn("Could not compute datatypeWithEnum from {}, {}", codegenParameter.baseType, codegenParameter.enumName); + LOGGER.warn("Could not compute datatypeWithEnum from " + codegenParameter.baseType + ", " + codegenParameter.enumName); } //TODO fix collectformat for form parameters //collectionFormat = getCollectionFormat(s); @@ -6164,7 +5868,7 @@ protected void addBodyModelSchema(CodegenParameter codegenParameter, String name "It could be due to form parameter defined in OpenAPI v2 spec with incorrect consumes. " + "A correct 'consumes' for form parameters should be " + "'application/x-www-form-urlencoded' or 'multipart/?'"); - LOGGER.warn("schema: {}", schema); + LOGGER.warn("schema: " + schema); LOGGER.warn("codegenModel is null. Default to UNKNOWN_BASE_TYPE"); codegenModelName = "UNKNOWN_BASE_TYPE"; codegenModelDescription = "UNKNOWN_DESCRIPTION"; @@ -6210,7 +5914,7 @@ public CodegenParameter fromRequestBody(RequestBody body, Set imports, S } String name = null; - LOGGER.debug("Request body = {}", body); + LOGGER.debug("Request body = " + body); Schema schema = ModelUtils.getSchemaFromRequestBody(body); if (schema == null) { throw new RuntimeException("Request body cannot be null. Possible cause: missing schema in body parameter (OAS v2): " + body); @@ -6363,7 +6067,7 @@ public CodegenParameter fromRequestBody(RequestBody body, Set imports, S setParameterNullable(codegenParameter, codegenProperty); } - addVarsRequiredVarsAdditionalProps(schema, codegenParameter); + addVarsRequiredVarsAdditionaProps(schema, codegenParameter); addJsonSchemaForBodyRequestInCaseItsNotPresent(codegenParameter, body); // set the parameter's example value @@ -6373,8 +6077,7 @@ public CodegenParameter fromRequestBody(RequestBody body, Set imports, S return codegenParameter; } - private void addVarsRequiredVarsAdditionalProps(Schema schema, IJsonSchemaValidationProperties property){ - setAddProps(schema, property); + private void addVarsRequiredVarsAdditionaProps(Schema schema, IJsonSchemaValidationProperties property){ if (!"object".equals(schema.getType())) { return; } @@ -6384,18 +6087,27 @@ private void addVarsRequiredVarsAdditionalProps(Schema schema, IJsonSchemaValida if (objSchema.getRequired() != null) { requiredVars.addAll(objSchema.getRequired()); } - if (objSchema.getProperties() != null && objSchema.getProperties().size() > 0) { - property.setHasVars(true); - } addVars(property, property.getVars(), objSchema.getProperties(), requiredVars); List requireCpVars = property.getVars() .stream() .filter(p -> Boolean.TRUE.equals(p.required)).collect(Collectors.toList()); property.setRequiredVars(requireCpVars); - if (property.getRequiredVars() != null && property.getRequiredVars().size() > 0) { - property.setHasRequired(true); + } + if (schema.getAdditionalProperties() == null) { + if (!disallowAdditionalPropertiesIfNotPresent) { + CodegenProperty cp = fromProperty("", new Schema()); + property.setAdditionalProperties(cp); } + } else if (schema.getAdditionalProperties() instanceof Boolean) { + if (Boolean.TRUE.equals(schema.getAdditionalProperties())) { + CodegenProperty cp = fromProperty("", new Schema()); + property.setAdditionalProperties(cp); + } + } else { + CodegenProperty cp = fromProperty("", (Schema) schema.getAdditionalProperties()); + property.setAdditionalProperties(cp); } + return; } private void addJsonSchemaForBodyRequestInCaseItsNotPresent(CodegenParameter codegenParameter, RequestBody body) { @@ -6515,9 +6227,7 @@ public List fromServerVariables(Map> operations) { - if ((SPRING_BOOT.equals(library) || SPRING_MVC_LIBRARY.equals(library)) && !useTags) { + if ((library.equals(SPRING_BOOT) || library.equals(SPRING_MVC_LIBRARY)) && !useTags) { String basePath = resourcePath; if (basePath.startsWith("/")) { basePath = basePath.substring(1); @@ -510,7 +510,7 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera basePath = basePath.substring(0, pos); } - if ("".equals(basePath)) { + if (basePath.equals("")) { basePath = "default"; } else { co.subresourceOperation = !co.path.isEmpty(); @@ -682,7 +682,7 @@ private void removeHeadersFromAllParams(List allParams) { @Override public Map postProcessSupportingFileData(Map objs) { generateYAMLSpecFile(objs); - if (SPRING_CLOUD_LIBRARY.equals(library)) { + if (library.equals(SPRING_CLOUD_LIBRARY)) { List authMethods = (List) objs.get("authMethods"); if (authMethods != null) { for (CodegenSecurity authMethod : authMethods) { @@ -874,4 +874,16 @@ public void setPerformBeanValidation(boolean performBeanValidation) { public void setUseOptional(boolean useOptional) { this.useOptional = useOptional; } + + @Override + public void addImportsToOneOfInterface(List> imports) { + for (String i : Arrays.asList("JsonSubTypes", "JsonTypeInfo")) { + Map oneImport = new HashMap() {{ + put("import", importMapping.get(i)); + }}; + if (!imports.contains(oneImport)) { + imports.add(oneImport); + } + } + } } diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache index 78c3c9ae19d4..8b39ebd13c30 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache @@ -37,7 +37,7 @@ import org.springframework.hateoas.RepresentationModel; {{>enumOuterClass}} {{/isEnum}} {{^isEnum}} -{{>pojo}} +{{#vendorExtensions.x-is-one-of-interface}}{{>oneof_interface}}{{/vendorExtensions.x-is-one-of-interface}}{{^vendorExtensions.x-is-one-of-interface}}{{>pojo}}{{/vendorExtensions.x-is-one-of-interface}} {{/isEnum}} {{/model}} {{/models}} diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache new file mode 100644 index 000000000000..4500871766c1 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache @@ -0,0 +1,6 @@ +{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}} +public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} { + {{#discriminator}} + public {{propertyType}} {{propertyGetter}}(); + {{/discriminator}} +} \ No newline at end of file