private static CodegenModel reconcileInlineEnums( CodegenModel codegenModel, CodegenModel parentCodegenModel) { // This generator uses inline classes to define enums, which breaks when // dealing with models that have subTypes. To clean this up, we will analyze // the parent and child models, look for enums that match, and remove // them from the child models and leave them in the parent. // Because the child models extend the parents, the enums will be available via the parent. // Only bother with reconciliation if the parent model has enums. if (parentCodegenModel.hasEnums) { // Get the properties for the parent and child models final List<CodegenProperty> parentModelCodegenProperties = parentCodegenModel.vars; List<CodegenProperty> codegenProperties = codegenModel.vars; // Iterate over all of the parent model properties boolean removedChildEnum = false; for (CodegenProperty parentModelCodegenPropery : parentModelCodegenProperties) { // Look for enums if (parentModelCodegenPropery.isEnum) { // Now that we have found an enum in the parent class, // and search the child class for the same enum. Iterator<CodegenProperty> iterator = codegenProperties.iterator(); while (iterator.hasNext()) { CodegenProperty codegenProperty = iterator.next(); if (codegenProperty.isEnum && codegenProperty.equals(parentModelCodegenPropery)) { // We found an enum in the child class that is // a duplicate of the one in the parent, so remove it. iterator.remove(); removedChildEnum = true; } } } } if (removedChildEnum) { // If we removed an entry from this model's vars, we need to ensure hasMore is updated int count = 0, numVars = codegenProperties.size(); for (CodegenProperty codegenProperty : codegenProperties) { count += 1; codegenProperty.hasMore = (count < numVars) ? true : null; } codegenModel.vars = codegenProperties; } } return codegenModel; }
@Override public int hashCode() { int result = parent != null ? parent.hashCode() : 0; result = 31 * result + (parentSchema != null ? parentSchema.hashCode() : 0); result = 31 * result + (interfaces != null ? interfaces.hashCode() : 0); result = 31 * result + (parentModel != null ? parentModel.hashCode() : 0); result = 31 * result + (interfaceModels != null ? interfaceModels.hashCode() : 0); result = 31 * result + (name != null ? name.hashCode() : 0); result = 31 * result + (classname != null ? classname.hashCode() : 0); result = 31 * result + (title != null ? title.hashCode() : 0); result = 31 * result + (description != null ? description.hashCode() : 0); result = 31 * result + (classVarName != null ? classVarName.hashCode() : 0); result = 31 * result + (modelJson != null ? modelJson.hashCode() : 0); result = 31 * result + (dataType != null ? dataType.hashCode() : 0); result = 31 * result + (classFilename != null ? classFilename.hashCode() : 0); result = 31 * result + (unescapedDescription != null ? unescapedDescription.hashCode() : 0); result = 31 * result + (discriminator != null ? discriminator.hashCode() : 0); result = 31 * result + (defaultValue != null ? defaultValue.hashCode() : 0); result = 31 * result + (vars != null ? vars.hashCode() : 0); result = 31 * result + (requiredVars != null ? requiredVars.hashCode() : 0); result = 31 * result + (optionalVars != null ? optionalVars.hashCode() : 0); result = 31 * result + (allVars != null ? allVars.hashCode() : 0); result = 31 * result + (allowableValues != null ? allowableValues.hashCode() : 0); result = 31 * result + (mandatory != null ? mandatory.hashCode() : 0); result = 31 * result + (allMandatory != null ? allMandatory.hashCode() : 0); result = 31 * result + (imports != null ? imports.hashCode() : 0); result = 31 * result + (hasVars != null ? hasVars.hashCode() : 0); result = 31 * result + (emptyVars != null ? emptyVars.hashCode() : 0); result = 31 * result + (hasMoreModels != null ? hasMoreModels.hashCode() : 0); result = 31 * result + (hasEnums != null ? hasEnums.hashCode() : 0); result = 31 * result + (isEnum != null ? isEnum.hashCode() : 0); result = 31 * result + (externalDocs != null ? externalDocs.hashCode() : 0); result = 31 * result + (vendorExtensions != null ? vendorExtensions.hashCode() : 0); result = 31 * result + Objects.hash(hasOnlyReadOnly); result = 31 * result + Objects.hash(hasChildren); result = 31 * result + Objects.hash(parentVars); return result; }
@Override public List<File> generate() { Boolean generateApis = null; Boolean generateModels = null; Boolean generateSupportingFiles = null; Set<String> modelsToGenerate = null; Set<String> apisToGenerate = null; Set<String> supportingFilesToGenerate = null; // allows generating only models by specifying a CSV of models to generate, or empty for all if (System.getProperty("models") != null) { String modelNames = System.getProperty("models"); generateModels = true; if (!modelNames.isEmpty()) { modelsToGenerate = new HashSet<String>(Arrays.asList(modelNames.split(","))); } } if (System.getProperty("apis") != null) { String apiNames = System.getProperty("apis"); generateApis = true; if (!apiNames.isEmpty()) { apisToGenerate = new HashSet<String>(Arrays.asList(apiNames.split(","))); } } if (System.getProperty("supportingFiles") != null) { String supportingFiles = System.getProperty("supportingFiles"); generateSupportingFiles = true; if (!supportingFiles.isEmpty()) { supportingFilesToGenerate = new HashSet<String>(Arrays.asList(supportingFiles.split(","))); } } if (generateApis == null && generateModels == null && generateSupportingFiles == null) { // no specifics are set, generate everything generateApis = true; generateModels = true; generateSupportingFiles = true; } else { if (generateApis == null) { generateApis = false; } if (generateModels == null) { generateModels = false; } if (generateSupportingFiles == null) { generateSupportingFiles = false; } } if (swagger == null || config == null) { throw new RuntimeException("missing swagger input or config!"); } if (System.getProperty("debugSwagger") != null) { Json.prettyPrint(swagger); } List<File> files = new ArrayList<File>(); config.processOpts(); config.preprocessSwagger(swagger); config.additionalProperties().put("generatedDate", DateTime.now().toString()); config.additionalProperties().put("generatorClass", config.getClass().toString()); if (swagger.getInfo() != null) { Info info = swagger.getInfo(); if (info.getTitle() != null) { config.additionalProperties().put("appName", info.getTitle()); } if (info.getVersion() != null) { config.additionalProperties().put("appVersion", info.getVersion()); } if (info.getDescription() != null) { config .additionalProperties() .put("appDescription", config.escapeText(info.getDescription())); } if (info.getContact() != null) { Contact contact = info.getContact(); config.additionalProperties().put("infoUrl", contact.getUrl()); if (contact.getEmail() != null) { config.additionalProperties().put("infoEmail", contact.getEmail()); } } if (info.getLicense() != null) { License license = info.getLicense(); if (license.getName() != null) { config.additionalProperties().put("licenseInfo", license.getName()); } if (license.getUrl() != null) { config.additionalProperties().put("licenseUrl", license.getUrl()); } } if (info.getVersion() != null) { config.additionalProperties().put("version", info.getVersion()); } } StringBuilder hostBuilder = new StringBuilder(); String scheme; if (swagger.getSchemes() != null && swagger.getSchemes().size() > 0) { scheme = swagger.getSchemes().get(0).toValue(); } else { scheme = "https"; } hostBuilder.append(scheme); hostBuilder.append("://"); if (swagger.getHost() != null) { hostBuilder.append(swagger.getHost()); } else { hostBuilder.append("localhost"); } if (swagger.getBasePath() != null) { hostBuilder.append(swagger.getBasePath()); } String contextPath = swagger.getBasePath() == null ? "" : swagger.getBasePath(); String basePath = hostBuilder.toString(); String basePathWithoutHost = swagger.getBasePath(); // resolve inline models InlineModelResolver inlineModelResolver = new InlineModelResolver(); inlineModelResolver.flatten(swagger); List<Object> allOperations = new ArrayList<Object>(); List<Object> allModels = new ArrayList<Object>(); // models Map<String, Model> definitions = swagger.getDefinitions(); if (definitions != null) { List<String> sortedModelKeys = sortModelsByInheritance(definitions); if (generateModels) { if (modelsToGenerate != null && modelsToGenerate.size() > 0) { List<String> updatedKeys = new ArrayList<String>(); for (String m : sortedModelKeys) { if (modelsToGenerate.contains(m)) { updatedKeys.add(m); } } sortedModelKeys = updatedKeys; } for (String name : sortedModelKeys) { try { // don't generate models that have an import mapping if (config.importMapping().containsKey(name)) { continue; } Model model = definitions.get(name); Map<String, Model> modelMap = new HashMap<String, Model>(); modelMap.put(name, model); Map<String, Object> models = processModels(config, modelMap, definitions); models.putAll(config.additionalProperties()); allModels.add(((List<Object>) models.get("models")).get(0)); for (String templateName : config.modelTemplateFiles().keySet()) { String suffix = config.modelTemplateFiles().get(templateName); String filename = config.modelFileFolder() + File.separator + config.toModelFilename(name) + suffix; if (!config.shouldOverwrite(filename)) { continue; } String templateFile = getFullTemplateFile(config, templateName); String template = readTemplate(templateFile); Template tmpl = Mustache.compiler() .withLoader( new Mustache.TemplateLoader() { @Override public Reader getTemplate(String name) { return getTemplateReader( getFullTemplateFile(config, name + ".mustache")); } }) .defaultValue("") .compile(template); writeToFile(filename, tmpl.execute(models)); files.add(new File(filename)); } } catch (Exception e) { throw new RuntimeException("Could not generate model '" + name + "'", e); } } } } if (System.getProperty("debugModels") != null) { System.out.println("############ Model info ############"); Json.prettyPrint(allModels); } // apis Map<String, List<CodegenOperation>> paths = processPaths(swagger.getPaths()); if (generateApis) { if (apisToGenerate != null && apisToGenerate.size() > 0) { Map<String, List<CodegenOperation>> updatedPaths = new TreeMap<String, List<CodegenOperation>>(); for (String m : paths.keySet()) { if (apisToGenerate.contains(m)) { updatedPaths.put(m, paths.get(m)); } } paths = updatedPaths; } for (String tag : paths.keySet()) { try { List<CodegenOperation> ops = paths.get(tag); Map<String, Object> operation = processOperations(config, tag, ops); operation.put("basePath", basePath); operation.put("basePathWithoutHost", basePathWithoutHost); operation.put("contextPath", contextPath); operation.put("baseName", tag); operation.put("modelPackage", config.modelPackage()); operation.putAll(config.additionalProperties()); operation.put("classname", config.toApiName(tag)); operation.put("classVarName", config.toApiVarName(tag)); operation.put("importPath", config.toApiImport(tag)); // Pass sortParamsByRequiredFlag through to the Mustache template... boolean sortParamsByRequiredFlag = true; if (this.config .additionalProperties() .containsKey(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG)) { sortParamsByRequiredFlag = Boolean.valueOf( (String) this.config .additionalProperties() .get(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG) .toString()); } operation.put("sortParamsByRequiredFlag", sortParamsByRequiredFlag); processMimeTypes(swagger.getConsumes(), operation, "consumes"); processMimeTypes(swagger.getProduces(), operation, "produces"); allOperations.add(new HashMap<String, Object>(operation)); for (int i = 0; i < allOperations.size(); i++) { Map<String, Object> oo = (Map<String, Object>) allOperations.get(i); if (i < (allOperations.size() - 1)) { oo.put("hasMore", "true"); } } for (String templateName : config.apiTemplateFiles().keySet()) { String filename = config.apiFilename(templateName, tag); if (!config.shouldOverwrite(filename) && new File(filename).exists()) { continue; } String templateFile = getFullTemplateFile(config, templateName); String template = readTemplate(templateFile); Template tmpl = Mustache.compiler() .withLoader( new Mustache.TemplateLoader() { @Override public Reader getTemplate(String name) { return getTemplateReader( getFullTemplateFile(config, name + ".mustache")); } }) .defaultValue("") .compile(template); writeToFile(filename, tmpl.execute(operation)); files.add(new File(filename)); } } catch (Exception e) { throw new RuntimeException("Could not generate api file for '" + tag + "'", e); } } } if (System.getProperty("debugOperations") != null) { System.out.println("############ Operation info ############"); Json.prettyPrint(allOperations); } // supporting files Map<String, Object> bundle = new HashMap<String, Object>(); bundle.putAll(config.additionalProperties()); bundle.put("apiPackage", config.apiPackage()); Map<String, Object> apis = new HashMap<String, Object>(); apis.put("apis", allOperations); if (swagger.getHost() != null) { bundle.put("host", swagger.getHost()); } bundle.put("basePath", basePath); bundle.put("scheme", scheme); bundle.put("contextPath", contextPath); bundle.put("apiInfo", apis); bundle.put("models", allModels); bundle.put("apiFolder", config.apiPackage().replace('.', File.separatorChar)); bundle.put("modelPackage", config.modelPackage()); List<CodegenSecurity> authMethods = config.fromSecurity(swagger.getSecurityDefinitions()); if (authMethods != null && !authMethods.isEmpty()) { bundle.put("authMethods", authMethods); bundle.put("hasAuthMethods", true); } if (swagger.getExternalDocs() != null) { bundle.put("externalDocs", swagger.getExternalDocs()); } for (int i = 0; i < allModels.size() - 1; i++) { HashMap<String, CodegenModel> cm = (HashMap<String, CodegenModel>) allModels.get(i); CodegenModel m = cm.get("model"); m.hasMoreModels = true; } config.postProcessSupportingFileData(bundle); if (System.getProperty("debugSupportingFiles") != null) { System.out.println("############ Supporting file info ############"); Json.prettyPrint(bundle); } if (generateSupportingFiles) { for (SupportingFile support : config.supportingFiles()) { try { String outputFolder = config.outputFolder(); if (isNotEmpty(support.folder)) { outputFolder += File.separator + support.folder; } File of = new File(outputFolder); if (!of.isDirectory()) { of.mkdirs(); } String outputFilename = outputFolder + File.separator + support.destinationFilename; if (!config.shouldOverwrite(outputFilename)) { continue; } String templateFile = getFullTemplateFile(config, support.templateFile); boolean shouldGenerate = true; if (supportingFilesToGenerate != null && supportingFilesToGenerate.size() > 0) { if (supportingFilesToGenerate.contains(support.destinationFilename)) { shouldGenerate = true; } else { shouldGenerate = false; } } if (shouldGenerate) { if (templateFile.endsWith("mustache")) { String template = readTemplate(templateFile); Template tmpl = Mustache.compiler() .withLoader( new Mustache.TemplateLoader() { @Override public Reader getTemplate(String name) { return getTemplateReader( getFullTemplateFile(config, name + ".mustache")); } }) .defaultValue("") .compile(template); writeToFile(outputFilename, tmpl.execute(bundle)); files.add(new File(outputFilename)); } else { InputStream in = null; try { in = new FileInputStream(templateFile); } catch (Exception e) { // continue } if (in == null) { in = this.getClass() .getClassLoader() .getResourceAsStream(getCPResourcePath(templateFile)); } File outputFile = new File(outputFilename); OutputStream out = new FileOutputStream(outputFile, false); if (in != null && out != null) { System.out.println("writing file " + outputFile); IOUtils.copy(in, out); } else { if (in == null) { System.out.println("can't open " + templateFile + " for input"); } if (out == null) { System.out.println("can't open " + outputFile + " for output"); } } files.add(outputFile); } } } catch (Exception e) { throw new RuntimeException("Could not generate supporting file '" + support + "'", e); } } } config.processSwagger(swagger); return files; }
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; CodegenModel that = (CodegenModel) o; if (parent != null ? !parent.equals(that.parent) : that.parent != null) return false; if (parentSchema != null ? !parentSchema.equals(that.parentSchema) : that.parentSchema != null) return false; if (interfaces != null ? !interfaces.equals(that.interfaces) : that.interfaces != null) return false; if (parentModel != null ? !parentModel.equals(that.parentModel) : that.parentModel != null) return false; if (interfaceModels != null ? !interfaceModels.equals(that.interfaceModels) : that.interfaceModels != null) return false; if (name != null ? !name.equals(that.name) : that.name != null) return false; if (classname != null ? !classname.equals(that.classname) : that.classname != null) return false; if (title != null ? !title.equals(that.title) : that.title != null) return false; if (description != null ? !description.equals(that.description) : that.description != null) return false; if (classVarName != null ? !classVarName.equals(that.classVarName) : that.classVarName != null) return false; if (modelJson != null ? !modelJson.equals(that.modelJson) : that.modelJson != null) return false; if (dataType != null ? !dataType.equals(that.dataType) : that.dataType != null) return false; if (classFilename != null ? !classFilename.equals(that.classFilename) : that.classFilename != null) return false; if (unescapedDescription != null ? !unescapedDescription.equals(that.unescapedDescription) : that.unescapedDescription != null) return false; if (discriminator != null ? !discriminator.equals(that.discriminator) : that.discriminator != null) return false; if (defaultValue != null ? !defaultValue.equals(that.defaultValue) : that.defaultValue != null) return false; if (vars != null ? !vars.equals(that.vars) : that.vars != null) return false; if (requiredVars != null ? !requiredVars.equals(that.requiredVars) : that.requiredVars != null) return false; if (optionalVars != null ? !optionalVars.equals(that.optionalVars) : that.optionalVars != null) return false; if (allVars != null ? !allVars.equals(that.allVars) : that.allVars != null) return false; if (allowableValues != null ? !allowableValues.equals(that.allowableValues) : that.allowableValues != null) return false; if (mandatory != null ? !mandatory.equals(that.mandatory) : that.mandatory != null) return false; if (allMandatory != null ? !allMandatory.equals(that.allMandatory) : that.allMandatory != null) return false; if (imports != null ? !imports.equals(that.imports) : that.imports != null) return false; if (hasVars != null ? !hasVars.equals(that.hasVars) : that.hasVars != null) return false; if (emptyVars != null ? !emptyVars.equals(that.emptyVars) : that.emptyVars != null) return false; if (hasMoreModels != null ? !hasMoreModels.equals(that.hasMoreModels) : that.hasMoreModels != null) return false; if (hasEnums != null ? !hasEnums.equals(that.hasEnums) : that.hasEnums != null) return false; if (isEnum != null ? !isEnum.equals(that.isEnum) : that.isEnum != null) return false; if (externalDocs != null ? !externalDocs.equals(that.externalDocs) : that.externalDocs != null) return false; if (!Objects.equals(hasOnlyReadOnly, that.hasOnlyReadOnly)) return false; if (!Objects.equals(hasChildren, that.hasChildren)) return false; if (!Objects.equals(parentVars, that.parentVars)) return false; return vendorExtensions != null ? vendorExtensions.equals(that.vendorExtensions) : that.vendorExtensions == null; }