forked from loafle/openapi-generator-original
Merge branch 'oas3_support2' into tweak
This commit is contained in:
commit
e3ba2d9936
@ -0,0 +1,664 @@
|
|||||||
|
package org.openapitools.codegen.languages;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.CliOption;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
import org.openapitools.codegen.CodegenOperation;
|
||||||
|
import org.openapitools.codegen.CodegenParameter;
|
||||||
|
import org.openapitools.codegen.CodegenProperty;
|
||||||
|
import org.openapitools.codegen.CodegenType;
|
||||||
|
import org.openapitools.codegen.DefaultCodegen;
|
||||||
|
import org.openapitools.codegen.SupportingFile;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.Operation;
|
||||||
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public abstract class AbstractPhpCodegen extends DefaultCodegen implements CodegenConfig {
|
||||||
|
|
||||||
|
static Logger LOGGER = LoggerFactory.getLogger(AbstractPhpCodegen.class);
|
||||||
|
|
||||||
|
public static final String VARIABLE_NAMING_CONVENTION = "variableNamingConvention";
|
||||||
|
public static final String PACKAGE_PATH = "packagePath";
|
||||||
|
public static final String SRC_BASE_PATH = "srcBasePath";
|
||||||
|
// composerVendorName/composerProjectName has be replaced by gitUserId/gitRepoId. prepare to remove these.
|
||||||
|
// public static final String COMPOSER_VENDOR_NAME = "composerVendorName";
|
||||||
|
// public static final String COMPOSER_PROJECT_NAME = "composerProjectName";
|
||||||
|
// protected String composerVendorName = null;
|
||||||
|
// protected String composerProjectName = null;
|
||||||
|
protected String invokerPackage = "php";
|
||||||
|
protected String packagePath = "php-base";
|
||||||
|
protected String artifactVersion = null;
|
||||||
|
protected String srcBasePath = "lib";
|
||||||
|
protected String testBasePath = "test";
|
||||||
|
protected String docsBasePath = "docs";
|
||||||
|
protected String apiDirName = "Api";
|
||||||
|
protected String modelDirName = "Model";
|
||||||
|
protected String variableNamingConvention= "snake_case";
|
||||||
|
protected String apiDocPath = docsBasePath + File.separator + apiDirName;
|
||||||
|
protected String modelDocPath = docsBasePath + File.separator + modelDirName;
|
||||||
|
|
||||||
|
public AbstractPhpCodegen() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
modelTemplateFiles.put("model.mustache", ".php");
|
||||||
|
apiTemplateFiles.put("api.mustache", ".php");
|
||||||
|
apiTestTemplateFiles.put("api_test.mustache", ".php");
|
||||||
|
modelDocTemplateFiles.put("model_doc.mustache", ".md");
|
||||||
|
apiDocTemplateFiles.put("api_doc.mustache", ".md");
|
||||||
|
|
||||||
|
apiPackage = invokerPackage + "\\" + apiDirName;
|
||||||
|
modelPackage = invokerPackage + "\\" + modelDirName;
|
||||||
|
|
||||||
|
setReservedWordsLowerCase(
|
||||||
|
Arrays.asList(
|
||||||
|
// local variables used in api methods (endpoints)
|
||||||
|
"resourcePath", "httpBody", "queryParams", "headerParams",
|
||||||
|
"formParams", "_header_accept", "_tempBody",
|
||||||
|
|
||||||
|
// PHP reserved words
|
||||||
|
"__halt_compiler", "abstract", "and", "array", "as", "break", "callable", "case", "catch", "class", "clone", "const", "continue", "declare", "default", "die", "do", "echo", "else", "elseif", "empty", "enddeclare", "endfor", "endforeach", "endif", "endswitch", "endwhile", "eval", "exit", "extends", "final", "for", "foreach", "function", "global", "goto", "if", "implements", "include", "include_once", "instanceof", "insteadof", "interface", "isset", "list", "namespace", "new", "or", "print", "private", "protected", "public", "require", "require_once", "return", "static", "switch", "throw", "trait", "try", "unset", "use", "var", "while", "xor")
|
||||||
|
);
|
||||||
|
|
||||||
|
// ref: http://php.net/manual/en/language.types.intro.php
|
||||||
|
languageSpecificPrimitives = new HashSet<String>(
|
||||||
|
Arrays.asList(
|
||||||
|
"bool",
|
||||||
|
"boolean",
|
||||||
|
"int",
|
||||||
|
"integer",
|
||||||
|
"double",
|
||||||
|
"float",
|
||||||
|
"string",
|
||||||
|
"object",
|
||||||
|
"DateTime",
|
||||||
|
"mixed",
|
||||||
|
"number",
|
||||||
|
"void",
|
||||||
|
"byte")
|
||||||
|
);
|
||||||
|
|
||||||
|
instantiationTypes.put("array", "array");
|
||||||
|
instantiationTypes.put("map", "map");
|
||||||
|
|
||||||
|
|
||||||
|
// provide primitives to mustache template
|
||||||
|
String primitives = "'" + StringUtils.join(languageSpecificPrimitives, "', '") + "'";
|
||||||
|
additionalProperties.put("primitives", primitives);
|
||||||
|
|
||||||
|
// ref: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types
|
||||||
|
typeMapping = new HashMap<String, String>();
|
||||||
|
typeMapping.put("integer", "int");
|
||||||
|
typeMapping.put("long", "int");
|
||||||
|
typeMapping.put("number", "float");
|
||||||
|
typeMapping.put("float", "float");
|
||||||
|
typeMapping.put("double", "double");
|
||||||
|
typeMapping.put("string", "string");
|
||||||
|
typeMapping.put("byte", "int");
|
||||||
|
typeMapping.put("boolean", "bool");
|
||||||
|
typeMapping.put("Date", "\\DateTime");
|
||||||
|
typeMapping.put("DateTime", "\\DateTime");
|
||||||
|
typeMapping.put("file", "\\SplFileObject");
|
||||||
|
typeMapping.put("map", "map");
|
||||||
|
typeMapping.put("array", "array");
|
||||||
|
typeMapping.put("list", "array");
|
||||||
|
typeMapping.put("object", "object");
|
||||||
|
typeMapping.put("binary", "string");
|
||||||
|
typeMapping.put("ByteArray", "string");
|
||||||
|
typeMapping.put("UUID", "string");
|
||||||
|
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
|
||||||
|
cliOptions.add(new CliOption(VARIABLE_NAMING_CONVENTION, "naming convention of variable name, e.g. camelCase.")
|
||||||
|
.defaultValue("snake_case"));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, "The main namespace to use for all classes. e.g. Yay\\Pets"));
|
||||||
|
cliOptions.add(new CliOption(PACKAGE_PATH, "The main package name for classes. e.g. GeneratedPetstore"));
|
||||||
|
cliOptions.add(new CliOption(SRC_BASE_PATH, "The directory under packagePath to serve as source root."));
|
||||||
|
// cliOptions.add(new CliOption(COMPOSER_VENDOR_NAME, "The vendor name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. yaypets. IMPORTANT NOTE (2016/03): composerVendorName will be deprecated and replaced by gitUserId in the next swagger-codegen release"));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.GIT_USER_ID, CodegenConstants.GIT_USER_ID_DESC));
|
||||||
|
// cliOptions.add(new CliOption(COMPOSER_PROJECT_NAME, "The project name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. petstore-client. IMPORTANT NOTE (2016/03): composerProjectName will be deprecated and replaced by gitRepoId in the next swagger-codegen release"));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.GIT_REPO_ID, CodegenConstants.GIT_REPO_ID_DESC));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, "The version to use in the composer package version field. e.g. 1.2.3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processOpts() {
|
||||||
|
super.processOpts();
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(PACKAGE_PATH)) {
|
||||||
|
this.setPackagePath((String) additionalProperties.get(PACKAGE_PATH));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(PACKAGE_PATH, packagePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(SRC_BASE_PATH)) {
|
||||||
|
this.setSrcBasePath((String) additionalProperties.get(SRC_BASE_PATH));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(SRC_BASE_PATH, srcBasePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
|
||||||
|
this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
|
||||||
|
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
|
||||||
|
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (additionalProperties.containsKey(COMPOSER_PROJECT_NAME)) {
|
||||||
|
// this.setComposerProjectName((String) additionalProperties.get(COMPOSER_PROJECT_NAME));
|
||||||
|
// } else {
|
||||||
|
// additionalProperties.put(COMPOSER_PROJECT_NAME, composerProjectName);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.GIT_USER_ID)) {
|
||||||
|
this.setGitUserId((String) additionalProperties.get(CodegenConstants.GIT_USER_ID));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(CodegenConstants.GIT_USER_ID, gitUserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (additionalProperties.containsKey(COMPOSER_VENDOR_NAME)) {
|
||||||
|
// this.setComposerVendorName((String) additionalProperties.get(COMPOSER_VENDOR_NAME));
|
||||||
|
// } else {
|
||||||
|
// additionalProperties.put(COMPOSER_VENDOR_NAME, composerVendorName);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.GIT_REPO_ID)) {
|
||||||
|
this.setGitRepoId((String) additionalProperties.get(CodegenConstants.GIT_REPO_ID));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(CodegenConstants.GIT_REPO_ID, gitRepoId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_VERSION)) {
|
||||||
|
this.setArtifactVersion((String) additionalProperties.get(CodegenConstants.ARTIFACT_VERSION));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(VARIABLE_NAMING_CONVENTION)) {
|
||||||
|
this.setParameterNamingConvention((String) additionalProperties.get(VARIABLE_NAMING_CONVENTION));
|
||||||
|
}
|
||||||
|
|
||||||
|
additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\"));
|
||||||
|
|
||||||
|
// make api and model src path available in mustache template
|
||||||
|
additionalProperties.put("apiSrcPath", "." + File.separator + toSrcPath(apiPackage, srcBasePath));
|
||||||
|
additionalProperties.put("modelSrcPath", "." + File.separator + toSrcPath(modelPackage, srcBasePath));
|
||||||
|
additionalProperties.put("apiTestPath", "." + File.separator + testBasePath + File.separator + apiDirName);
|
||||||
|
additionalProperties.put("modelTestPath", "." + File.separator + testBasePath + File.separator + modelDirName);
|
||||||
|
|
||||||
|
// make api and model doc path available in mustache template
|
||||||
|
additionalProperties.put("apiDocPath", apiDocPath);
|
||||||
|
additionalProperties.put("modelDocPath", modelDocPath);
|
||||||
|
|
||||||
|
// make test path available in mustache template
|
||||||
|
additionalProperties.put("testBasePath", testBasePath);
|
||||||
|
|
||||||
|
// // apache v2 license
|
||||||
|
// supportingFiles.add(new SupportingFile("LICENSE", getPackagePath(), "LICENSE"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPackagePath() {
|
||||||
|
return packagePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toPackagePath(String packageName, String basePath) {
|
||||||
|
return (getPackagePath() + File.separatorChar + toSrcPath(packageName, basePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toSrcPath(String packageName, String basePath) {
|
||||||
|
packageName = packageName.replace(invokerPackage, ""); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
if (basePath != null && basePath.length() > 0) {
|
||||||
|
basePath = basePath.replaceAll("[\\\\/]?$", "") + File.separatorChar; // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
}
|
||||||
|
|
||||||
|
String regFirstPathSeparator;
|
||||||
|
if ("/".equals(File.separator)) { // for mac, linux
|
||||||
|
regFirstPathSeparator = "^/";
|
||||||
|
} else { // for windows
|
||||||
|
regFirstPathSeparator = "^\\\\";
|
||||||
|
}
|
||||||
|
|
||||||
|
String regLastPathSeparator;
|
||||||
|
if ("/".equals(File.separator)) { // for mac, linux
|
||||||
|
regLastPathSeparator = "/$";
|
||||||
|
} else { // for windows
|
||||||
|
regLastPathSeparator = "\\\\$";
|
||||||
|
}
|
||||||
|
|
||||||
|
return (basePath
|
||||||
|
// Replace period, backslash, forward slash with file separator in package name
|
||||||
|
+ packageName.replaceAll("[\\.\\\\/]", Matcher.quoteReplacement(File.separator))
|
||||||
|
// Trim prefix file separators from package path
|
||||||
|
.replaceAll(regFirstPathSeparator, ""))
|
||||||
|
// Trim trailing file separators from the overall path
|
||||||
|
.replaceAll(regLastPathSeparator+ "$", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeReservedWord(String name) {
|
||||||
|
if(this.reservedWordsMappings().containsKey(name)) {
|
||||||
|
return this.reservedWordsMappings().get(name);
|
||||||
|
}
|
||||||
|
return "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiFileFolder() {
|
||||||
|
return (outputFolder + File.separator + toPackagePath(apiPackage, srcBasePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelFileFolder() {
|
||||||
|
return (outputFolder + File.separator + toPackagePath(modelPackage, srcBasePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiTestFileFolder() {
|
||||||
|
return (outputFolder + File.separator + getPackagePath() + File.separator + testBasePath + File.separator + apiDirName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelTestFileFolder() {
|
||||||
|
return (outputFolder + File.separator + getPackagePath() + File.separator + testBasePath + File.separator + modelDirName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiDocFileFolder() {
|
||||||
|
return (outputFolder + File.separator + getPackagePath() + File.separator + apiDocPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelDocFileFolder() {
|
||||||
|
return (outputFolder + File.separator + getPackagePath() + File.separator + modelDocPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelDocFilename(String name) {
|
||||||
|
return toModelName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiDocFilename(String name) {
|
||||||
|
return toApiName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(Schema p) {
|
||||||
|
if (p instanceof ArraySchema) {
|
||||||
|
ArraySchema ap = (ArraySchema) p;
|
||||||
|
Schema inner = ap.getItems();
|
||||||
|
return getTypeDeclaration(inner) + "[]";
|
||||||
|
} else if (p instanceof MapSchema) {
|
||||||
|
MapSchema mp = (MapSchema) p;
|
||||||
|
Schema inner = (Schema) mp.getAdditionalProperties();
|
||||||
|
return getSchemaType(p) + "[string," + getTypeDeclaration(inner) + "]";
|
||||||
|
} else if (!StringUtils.isEmpty(p.get$ref())) { // model
|
||||||
|
String type = super.getTypeDeclaration(p);
|
||||||
|
return (!languageSpecificPrimitives.contains(type))
|
||||||
|
? "\\" + modelPackage + "\\" + type : type;
|
||||||
|
}
|
||||||
|
return super.getTypeDeclaration(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(String name) {
|
||||||
|
if (!languageSpecificPrimitives.contains(name)) {
|
||||||
|
return "\\" + modelPackage + "\\" + name;
|
||||||
|
}
|
||||||
|
return super.getTypeDeclaration(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSchemaType(Schema p) {
|
||||||
|
String openAPIType = super.getSchemaType(p);
|
||||||
|
String type = null;
|
||||||
|
if (typeMapping.containsKey(openAPIType)) {
|
||||||
|
type = typeMapping.get(openAPIType);
|
||||||
|
if (languageSpecificPrimitives.contains(type)) {
|
||||||
|
return type;
|
||||||
|
} else if (instantiationTypes.containsKey(type)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
type = openAPIType;
|
||||||
|
}
|
||||||
|
if (type == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return toModelName(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInvokerPackage(String invokerPackage) {
|
||||||
|
this.invokerPackage = invokerPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArtifactVersion(String artifactVersion) {
|
||||||
|
this.artifactVersion = artifactVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPackagePath(String packagePath) {
|
||||||
|
this.packagePath = packagePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSrcBasePath(String srcBasePath) {
|
||||||
|
this.srcBasePath = srcBasePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParameterNamingConvention(String variableNamingConvention) {
|
||||||
|
this.variableNamingConvention = variableNamingConvention;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public void setComposerVendorName(String composerVendorName) {
|
||||||
|
// this.composerVendorName = composerVendorName;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void setComposerProjectName(String composerProjectName) {
|
||||||
|
// this.composerProjectName = composerProjectName;
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toVarName(String name) {
|
||||||
|
// sanitize name
|
||||||
|
name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
|
||||||
|
if ("camelCase".equals(variableNamingConvention)) {
|
||||||
|
// return the name in camelCase style
|
||||||
|
// phone_number => phoneNumber
|
||||||
|
name = camelize(name, true);
|
||||||
|
} else { // default to snake case
|
||||||
|
// return the name in underscore style
|
||||||
|
// PhoneNumber => phone_number
|
||||||
|
name = underscore(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// parameter name starting with number won't compile
|
||||||
|
// need to escape it by appending _ at the beginning
|
||||||
|
if (name.matches("^\\d.*")) {
|
||||||
|
name = "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toParamName(String name) {
|
||||||
|
// should be the same as variable name
|
||||||
|
return toVarName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelName(String name) {
|
||||||
|
// remove [
|
||||||
|
name = name.replaceAll("\\]", "");
|
||||||
|
|
||||||
|
// Note: backslash ("\\") is allowed for e.g. "\\DateTime"
|
||||||
|
name = name.replaceAll("[^\\w\\\\]+", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
|
||||||
|
// remove dollar sign
|
||||||
|
name = name.replaceAll("$", "");
|
||||||
|
|
||||||
|
// model name cannot use reserved keyword
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + camelize("model_" + name));
|
||||||
|
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// model name starts with number
|
||||||
|
if (name.matches("^\\d.*")) {
|
||||||
|
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + camelize("model_" + name));
|
||||||
|
name = "model_" + name; // e.g. 200Response => Model200Response (after camelize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add prefix and/or suffic only if name does not start wth \ (e.g. \DateTime)
|
||||||
|
if (!name.matches("^\\\\.*")) {
|
||||||
|
name = modelNamePrefix + name + modelNameSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize the model name
|
||||||
|
// phone_number => PhoneNumber
|
||||||
|
return camelize(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelFilename(String name) {
|
||||||
|
// should be the same as the model name
|
||||||
|
return toModelName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelTestFilename(String name) {
|
||||||
|
// should be the same as the model name
|
||||||
|
return toModelName(name) + "Test";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toOperationId(String operationId) {
|
||||||
|
// throw exception if method name is empty
|
||||||
|
if (StringUtils.isEmpty(operationId)) {
|
||||||
|
throw new RuntimeException("Empty method name (operationId) not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// method name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(operationId)) {
|
||||||
|
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + camelize(sanitizeName("call_" + operationId), true));
|
||||||
|
operationId = "call_" + operationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return camelize(sanitizeName(operationId), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the default value of the property
|
||||||
|
*
|
||||||
|
* @param p Swagger property object
|
||||||
|
* @return string presentation of the default value of the property
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toDefaultValue(Schema p) {
|
||||||
|
if (p instanceof StringSchema) {
|
||||||
|
StringSchema dp = (StringSchema) p;
|
||||||
|
if (dp.getDefault() != null) {
|
||||||
|
return "'" + dp.getDefault() + "'";
|
||||||
|
}
|
||||||
|
} else if (p instanceof BooleanSchema) {
|
||||||
|
BooleanSchema dp = (BooleanSchema) p;
|
||||||
|
if (dp.getDefault() != null) {
|
||||||
|
return dp.getDefault().toString();
|
||||||
|
}
|
||||||
|
} else if (p instanceof DateSchema) {
|
||||||
|
// TODO
|
||||||
|
} else if (p instanceof DateTimeSchema) {
|
||||||
|
// TODO
|
||||||
|
} else if (p instanceof NumberSchema) {
|
||||||
|
NumberSchema dp = (NumberSchema) p;
|
||||||
|
if (dp.getDefault() != null) {
|
||||||
|
return dp.getDefault().toString();
|
||||||
|
}
|
||||||
|
} else if (p instanceof IntegerSchema) {
|
||||||
|
IntegerSchema dp = (IntegerSchema) p;
|
||||||
|
if (dp.getDefault() != null) {
|
||||||
|
return dp.getDefault().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setParameterExampleValue(CodegenParameter p) {
|
||||||
|
String example;
|
||||||
|
|
||||||
|
if (p.defaultValue == null) {
|
||||||
|
example = p.example;
|
||||||
|
} else {
|
||||||
|
example = p.defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String type = p.baseType;
|
||||||
|
if (type == null) {
|
||||||
|
type = p.dataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("String".equalsIgnoreCase(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = p.paramName + "_example";
|
||||||
|
}
|
||||||
|
example = "\"" + escapeText(example) + "\"";
|
||||||
|
} else if ("Integer".equals(type) || "int".equals(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "56";
|
||||||
|
}
|
||||||
|
} else if ("Float".equalsIgnoreCase(type) || "Double".equalsIgnoreCase(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "3.4";
|
||||||
|
}
|
||||||
|
} else if ("BOOLEAN".equalsIgnoreCase(type) || "bool".equalsIgnoreCase(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "True";
|
||||||
|
}
|
||||||
|
} else if ("\\SplFileObject".equalsIgnoreCase(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "/path/to/file";
|
||||||
|
}
|
||||||
|
example = "\"" + escapeText(example) + "\"";
|
||||||
|
} else if ("Date".equalsIgnoreCase(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "2013-10-20";
|
||||||
|
}
|
||||||
|
example = "new \\DateTime(\"" + escapeText(example) + "\")";
|
||||||
|
} else if ("DateTime".equalsIgnoreCase(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "2013-10-20T19:20:30+01:00";
|
||||||
|
}
|
||||||
|
example = "new \\DateTime(\"" + escapeText(example) + "\")";
|
||||||
|
} else if (!languageSpecificPrimitives.contains(type)) {
|
||||||
|
// type is a model class, e.g. User
|
||||||
|
example = "new " + getTypeDeclaration(type) + "()";
|
||||||
|
} else {
|
||||||
|
LOGGER.warn("Type " + type + " not handled properly in setParameterExampleValue");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (example == null) {
|
||||||
|
example = "NULL";
|
||||||
|
} else if (Boolean.TRUE.equals(p.isListContainer)) {
|
||||||
|
example = "array(" + example + ")";
|
||||||
|
} else if (Boolean.TRUE.equals(p.isMapContainer)) {
|
||||||
|
example = "array('key' => " + example + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
p.example = example;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toEnumValue(String value, String datatype) {
|
||||||
|
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return "\'" + escapeText(value) + "\'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toEnumDefaultValue(String value, String datatype) {
|
||||||
|
return datatype + "_" + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toEnumVarName(String name, String datatype) {
|
||||||
|
if (name.length() == 0) {
|
||||||
|
return "EMPTY";
|
||||||
|
}
|
||||||
|
|
||||||
|
// for symbol, e.g. $, #
|
||||||
|
if (getSymbolName(name) != null) {
|
||||||
|
return (getSymbolName(name)).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
// number
|
||||||
|
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
|
||||||
|
String varName = name;
|
||||||
|
varName = varName.replaceAll("-", "MINUS_");
|
||||||
|
varName = varName.replaceAll("\\+", "PLUS_");
|
||||||
|
varName = varName.replaceAll("\\.", "_DOT_");
|
||||||
|
return varName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// string
|
||||||
|
String enumName = sanitizeName(underscore(name).toUpperCase());
|
||||||
|
enumName = enumName.replaceFirst("^_", "");
|
||||||
|
enumName = enumName.replaceFirst("_$", "");
|
||||||
|
|
||||||
|
if (enumName.matches("\\d.*")) { // starts with number
|
||||||
|
return "_" + enumName;
|
||||||
|
} else {
|
||||||
|
return enumName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toEnumName(CodegenProperty property) {
|
||||||
|
String enumName = underscore(toModelName(property.name)).toUpperCase();
|
||||||
|
|
||||||
|
if (enumName.matches("\\d.*")) { // starts with number
|
||||||
|
return "_" + enumName;
|
||||||
|
} else {
|
||||||
|
return enumName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||||
|
// process enum in models
|
||||||
|
return postProcessModelsEnum(objs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||||
|
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||||
|
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
|
||||||
|
for (CodegenOperation op : operationList) {
|
||||||
|
op.vendorExtensions.put("x-testOperationId", camelize(op.operationId));
|
||||||
|
}
|
||||||
|
return objs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeQuotationMark(String input) {
|
||||||
|
// remove ' to avoid code injection
|
||||||
|
return input.replace("'", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeUnsafeCharacters(String input) {
|
||||||
|
return input.replace("*/", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String extractSimpleName(String phpClassName) {
|
||||||
|
if (phpClassName == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int lastBackslashIndex = phpClassName.lastIndexOf('\\');
|
||||||
|
return phpClassName.substring(lastBackslashIndex + 1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,595 @@
|
|||||||
|
package org.openapitools.codegen.languages;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.CliOption;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
import org.openapitools.codegen.CodegenParameter;
|
||||||
|
import org.openapitools.codegen.CodegenType;
|
||||||
|
import org.openapitools.codegen.DefaultCodegen;
|
||||||
|
import org.openapitools.codegen.SupportingFile;
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.Operation;
|
||||||
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(AndroidClientCodegen.class);
|
||||||
|
public static final String USE_ANDROID_MAVEN_GRADLE_PLUGIN = "useAndroidMavenGradlePlugin";
|
||||||
|
public static final String ANDROID_GRADLE_VERSION = "androidGradleVersion";
|
||||||
|
public static final String ANDROID_SDK_VERSION = "androidSdkVersion";
|
||||||
|
public static final String ANDROID_BUILD_TOOLS_VERSION = "androidBuildToolsVersion";
|
||||||
|
protected String invokerPackage = "io.swagger.client";
|
||||||
|
protected String groupId = "io.swagger";
|
||||||
|
protected String artifactId = "swagger-android-client";
|
||||||
|
protected String artifactVersion = "1.0.0";
|
||||||
|
protected String projectFolder = "src/main";
|
||||||
|
protected String sourceFolder = projectFolder + "/java";
|
||||||
|
protected Boolean useAndroidMavenGradlePlugin = true;
|
||||||
|
protected String androidGradleVersion;
|
||||||
|
protected String androidSdkVersion;
|
||||||
|
protected String androidBuildToolsVersion;
|
||||||
|
protected Boolean serializableModel = false;
|
||||||
|
|
||||||
|
// requestPackage and authPackage are used by the "volley" template/library
|
||||||
|
protected String requestPackage = "io.swagger.client.request";
|
||||||
|
protected String authPackage = "io.swagger.client.auth";
|
||||||
|
protected String gradleWrapperPackage = "gradle.wrapper";
|
||||||
|
protected String apiDocPath = "docs/";
|
||||||
|
protected String modelDocPath = "docs/";
|
||||||
|
|
||||||
|
public AndroidClientCodegen() {
|
||||||
|
super();
|
||||||
|
outputFolder = "generated-code/android";
|
||||||
|
modelTemplateFiles.put("model.mustache", ".java");
|
||||||
|
apiTemplateFiles.put("api.mustache", ".java");
|
||||||
|
embeddedTemplateDir = templateDir = "android";
|
||||||
|
apiPackage = "io.swagger.client.api";
|
||||||
|
modelPackage = "io.swagger.client.model";
|
||||||
|
|
||||||
|
setReservedWordsLowerCase(
|
||||||
|
Arrays.asList(
|
||||||
|
// local variable names used in API methods (endpoints)
|
||||||
|
"localVarPostBody", "localVarPath", "localVarQueryParams", "localVarHeaderParams",
|
||||||
|
"localVarFormParams", "localVarContentTypes", "localVarContentType",
|
||||||
|
"localVarResponse", "localVarBuilder", "authNames", "basePath", "apiInvoker",
|
||||||
|
|
||||||
|
// due to namespace collusion
|
||||||
|
"Object",
|
||||||
|
|
||||||
|
// android reserved words
|
||||||
|
"abstract", "continue", "for", "new", "switch", "assert",
|
||||||
|
"default", "if", "package", "synchronized", "boolean", "do", "goto", "private",
|
||||||
|
"this", "break", "double", "implements", "protected", "throw", "byte", "else",
|
||||||
|
"import", "public", "throws", "case", "enum", "instanceof", "return", "transient",
|
||||||
|
"catch", "extends", "int", "short", "try", "char", "final", "interface", "static",
|
||||||
|
"void", "class", "finally", "long", "strictfp", "volatile", "const", "float",
|
||||||
|
"native", "super", "while", "null")
|
||||||
|
);
|
||||||
|
|
||||||
|
languageSpecificPrimitives = new HashSet<String>(
|
||||||
|
Arrays.asList(
|
||||||
|
"String",
|
||||||
|
"boolean",
|
||||||
|
"Boolean",
|
||||||
|
"Double",
|
||||||
|
"Integer",
|
||||||
|
"Long",
|
||||||
|
"Float",
|
||||||
|
"byte[]",
|
||||||
|
"Object")
|
||||||
|
);
|
||||||
|
instantiationTypes.put("array", "ArrayList");
|
||||||
|
instantiationTypes.put("map", "HashMap");
|
||||||
|
typeMapping.put("date", "Date");
|
||||||
|
typeMapping.put("file", "File");
|
||||||
|
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, CodegenConstants.INVOKER_PACKAGE_DESC));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.GROUP_ID, "groupId for use in the generated build.gradle and pom.xml"));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_ID, "artifactId for use in the generated build.gradle and pom.xml"));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, "artifact version for use in the generated build.gradle and pom.xml"));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC));
|
||||||
|
cliOptions.add(CliOption.newBoolean(USE_ANDROID_MAVEN_GRADLE_PLUGIN, "A flag to toggle android-maven gradle plugin.")
|
||||||
|
.defaultValue(Boolean.TRUE.toString()));
|
||||||
|
cliOptions.add(new CliOption(ANDROID_GRADLE_VERSION, "gradleVersion version for use in the generated build.gradle"));
|
||||||
|
cliOptions.add(new CliOption(ANDROID_SDK_VERSION, "compileSdkVersion version for use in the generated build.gradle"));
|
||||||
|
cliOptions.add(new CliOption(ANDROID_BUILD_TOOLS_VERSION, "buildToolsVersion version for use in the generated build.gradle"));
|
||||||
|
|
||||||
|
cliOptions.add(CliOption.newBoolean(CodegenConstants.SERIALIZABLE_MODEL, CodegenConstants.SERIALIZABLE_MODEL_DESC));
|
||||||
|
|
||||||
|
supportedLibraries.put("volley", "HTTP client: Volley 1.0.19 (default)");
|
||||||
|
supportedLibraries.put("httpclient", "HTTP client: Apache HttpClient 4.3.6. JSON processing: Gson 2.3.1. IMPORTANT: Android client using HttpClient is not actively maintained and will be depecreated in the next major release.");
|
||||||
|
CliOption library = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use");
|
||||||
|
library.setEnum(supportedLibraries);
|
||||||
|
cliOptions.add(library);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.CLIENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "android";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates an Android client library.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeReservedWord(String name) {
|
||||||
|
if (this.reservedWordsMappings().containsKey(name)) {
|
||||||
|
return this.reservedWordsMappings().get(name);
|
||||||
|
}
|
||||||
|
return "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiFileFolder() {
|
||||||
|
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelFileFolder() {
|
||||||
|
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiDocFileFolder() {
|
||||||
|
return (outputFolder + "/" + apiDocPath).replace('/', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelDocFileFolder() {
|
||||||
|
return (outputFolder + "/" + modelDocPath).replace('/', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiDocFilename(String name) {
|
||||||
|
return toApiName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelDocFilename(String name) {
|
||||||
|
return toModelName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(Schema p) {
|
||||||
|
if (p instanceof ArraySchema) {
|
||||||
|
ArraySchema ap = (ArraySchema) p;
|
||||||
|
Schema inner = ap.getItems();
|
||||||
|
return getSchemaType(p) + "<" + getTypeDeclaration(inner) + ">";
|
||||||
|
} else if (p instanceof MapSchema) {
|
||||||
|
MapSchema mp = (MapSchema) p;
|
||||||
|
Schema inner = (Schema) mp.getAdditionalProperties();
|
||||||
|
|
||||||
|
return getSchemaType(p) + "<String, " + getTypeDeclaration(inner) + ">";
|
||||||
|
}
|
||||||
|
return super.getTypeDeclaration(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSchemaType(Schema p) {
|
||||||
|
String swaggerType = super.getSchemaType(p);
|
||||||
|
String type = null;
|
||||||
|
if (typeMapping.containsKey(swaggerType)) {
|
||||||
|
type = typeMapping.get(swaggerType);
|
||||||
|
if (languageSpecificPrimitives.contains(type) || type.indexOf(".") >= 0 ||
|
||||||
|
type.equals("Map") || type.equals("List") ||
|
||||||
|
type.equals("File") || type.equals("Date")) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
type = swaggerType;
|
||||||
|
}
|
||||||
|
return toModelName(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toVarName(String name) {
|
||||||
|
// sanitize name
|
||||||
|
name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
|
||||||
|
// replace - with _ e.g. created-at => created_at
|
||||||
|
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
|
||||||
|
// if it's all uppper case, do nothing
|
||||||
|
if (name.matches("^[A-Z_]*$")) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize (lower first character) the variable name
|
||||||
|
// pet_id => petId
|
||||||
|
name = camelize(name, true);
|
||||||
|
|
||||||
|
// for reserved word or word starting with number, append _
|
||||||
|
if (isReservedWord(name) || name.matches("^\\d.*")) {
|
||||||
|
name = escapeReservedWord(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toParamName(String name) {
|
||||||
|
// should be the same as variable name
|
||||||
|
return toVarName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelName(String name) {
|
||||||
|
// add prefix, suffix if needed
|
||||||
|
if (!StringUtils.isEmpty(modelNamePrefix)) {
|
||||||
|
name = modelNamePrefix + "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(modelNameSuffix)) {
|
||||||
|
name = name + "_" + modelNameSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize the model name
|
||||||
|
// phone_number => PhoneNumber
|
||||||
|
name = camelize(sanitizeName(name));
|
||||||
|
|
||||||
|
// model name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
String modelName = "Model" + name;
|
||||||
|
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + modelName);
|
||||||
|
return modelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// model name starts with number
|
||||||
|
if (name.matches("^\\d.*")) {
|
||||||
|
String modelName = "Model" + name; // e.g. 200Response => Model200Response (after camelize)
|
||||||
|
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + modelName);
|
||||||
|
return modelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelFilename(String name) {
|
||||||
|
// should be the same as the model name
|
||||||
|
return toModelName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setParameterExampleValue(CodegenParameter p) {
|
||||||
|
String example;
|
||||||
|
|
||||||
|
if (p.defaultValue == null) {
|
||||||
|
example = p.example;
|
||||||
|
} else {
|
||||||
|
example = p.defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String type = p.baseType;
|
||||||
|
if (type == null) {
|
||||||
|
type = p.dataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("String".equals(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = p.paramName + "_example";
|
||||||
|
}
|
||||||
|
example = "\"" + escapeText(example) + "\"";
|
||||||
|
} else if ("Integer".equals(type) || "Short".equals(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "56";
|
||||||
|
}
|
||||||
|
} else if ("Long".equals(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "56";
|
||||||
|
}
|
||||||
|
example = example + "L";
|
||||||
|
} else if ("Float".equals(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "3.4";
|
||||||
|
}
|
||||||
|
example = example + "F";
|
||||||
|
} else if ("Double".equals(type)) {
|
||||||
|
example = "3.4";
|
||||||
|
example = example + "D";
|
||||||
|
} else if ("Boolean".equals(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "true";
|
||||||
|
}
|
||||||
|
} else if ("File".equals(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "/path/to/file";
|
||||||
|
}
|
||||||
|
example = "new File(\"" + escapeText(example) + "\")";
|
||||||
|
} else if ("Date".equals(type)) {
|
||||||
|
example = "new Date()";
|
||||||
|
} else if (!languageSpecificPrimitives.contains(type)) {
|
||||||
|
// type is a model class, e.g. User
|
||||||
|
example = "new " + type + "()";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (example == null) {
|
||||||
|
example = "null";
|
||||||
|
} else if (Boolean.TRUE.equals(p.isListContainer)) {
|
||||||
|
example = "Arrays.asList(" + example + ")";
|
||||||
|
} else if (Boolean.TRUE.equals(p.isMapContainer)) {
|
||||||
|
example = "new HashMap()";
|
||||||
|
}
|
||||||
|
|
||||||
|
p.example = example;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toOperationId(String operationId) {
|
||||||
|
// throw exception if method name is empty
|
||||||
|
if (StringUtils.isEmpty(operationId)) {
|
||||||
|
throw new RuntimeException("Empty method name (operationId) not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
operationId = camelize(sanitizeName(operationId), true);
|
||||||
|
|
||||||
|
// method name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(operationId)) {
|
||||||
|
String newOperationId = camelize("call_" + operationId, true);
|
||||||
|
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + newOperationId);
|
||||||
|
return newOperationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return operationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processOpts() {
|
||||||
|
super.processOpts();
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
|
||||||
|
this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
|
||||||
|
this.setRequestPackage(invokerPackage + ".request");
|
||||||
|
this.setAuthPackage(invokerPackage + ".auth");
|
||||||
|
} else {
|
||||||
|
//not set, use default to be passed to template
|
||||||
|
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||||
|
additionalProperties.put("requestPackage", requestPackage);
|
||||||
|
additionalProperties.put("authPackage", authPackage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.GROUP_ID)) {
|
||||||
|
this.setGroupId((String) additionalProperties.get(CodegenConstants.GROUP_ID));
|
||||||
|
} else {
|
||||||
|
//not set, use to be passed to template
|
||||||
|
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_ID)) {
|
||||||
|
this.setArtifactId((String) additionalProperties.get(CodegenConstants.ARTIFACT_ID));
|
||||||
|
} else {
|
||||||
|
//not set, use to be passed to template
|
||||||
|
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_VERSION)) {
|
||||||
|
this.setArtifactVersion((String) additionalProperties.get(CodegenConstants.ARTIFACT_VERSION));
|
||||||
|
} else {
|
||||||
|
//not set, use to be passed to template
|
||||||
|
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
|
||||||
|
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(USE_ANDROID_MAVEN_GRADLE_PLUGIN)) {
|
||||||
|
this.setUseAndroidMavenGradlePlugin(Boolean.valueOf((String) additionalProperties
|
||||||
|
.get(USE_ANDROID_MAVEN_GRADLE_PLUGIN)));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(USE_ANDROID_MAVEN_GRADLE_PLUGIN, useAndroidMavenGradlePlugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(ANDROID_GRADLE_VERSION)) {
|
||||||
|
this.setAndroidGradleVersion((String) additionalProperties.get(ANDROID_GRADLE_VERSION));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(ANDROID_SDK_VERSION)) {
|
||||||
|
this.setAndroidSdkVersion((String) additionalProperties.get(ANDROID_SDK_VERSION));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(ANDROID_BUILD_TOOLS_VERSION)) {
|
||||||
|
this.setAndroidBuildToolsVersion((String) additionalProperties.get(ANDROID_BUILD_TOOLS_VERSION));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.LIBRARY)) {
|
||||||
|
this.setLibrary((String) additionalProperties.get(CodegenConstants.LIBRARY));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.SERIALIZABLE_MODEL)) {
|
||||||
|
this.setSerializableModel(Boolean.valueOf(additionalProperties.get(CodegenConstants.SERIALIZABLE_MODEL).toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// need to put back serializableModel (boolean) into additionalProperties as value in additionalProperties is string
|
||||||
|
additionalProperties.put(CodegenConstants.SERIALIZABLE_MODEL, serializableModel);
|
||||||
|
|
||||||
|
//make api and model doc path available in mustache template
|
||||||
|
additionalProperties.put("apiDocPath", apiDocPath);
|
||||||
|
additionalProperties.put("modelDocPath", modelDocPath);
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(getLibrary())) {
|
||||||
|
setLibrary("volley"); // set volley as the default library
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine which file (mustache) to add based on library
|
||||||
|
if ("volley".equals(getLibrary())) {
|
||||||
|
addSupportingFilesForVolley();
|
||||||
|
} else if ("httpclient".equals(getLibrary())) {
|
||||||
|
addSupportingFilesForHttpClient();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Invalid 'library' option specified: '" + getLibrary() + "'. Must be 'httpclient' or 'volley' (default)");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSupportingFilesForHttpClient() {
|
||||||
|
// documentation files
|
||||||
|
modelDocTemplateFiles.put("model_doc.mustache", ".md");
|
||||||
|
apiDocTemplateFiles.put("api_doc.mustache", ".md");
|
||||||
|
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
|
||||||
|
supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle"));
|
||||||
|
supportingFiles.add(new SupportingFile("build.mustache", "", "build.gradle"));
|
||||||
|
supportingFiles.add(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml"));
|
||||||
|
supportingFiles.add(new SupportingFile("apiInvoker.mustache",
|
||||||
|
(sourceFolder + File.separator + invokerPackage).replace(".", File.separator), "ApiInvoker.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("httpPatch.mustache",
|
||||||
|
(sourceFolder + File.separator + invokerPackage).replace(".", File.separator), "HttpPatch.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("jsonUtil.mustache",
|
||||||
|
(sourceFolder + File.separator + invokerPackage).replace(".", File.separator), "JsonUtil.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("apiException.mustache",
|
||||||
|
(sourceFolder + File.separator + invokerPackage).replace(".", File.separator), "ApiException.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("Pair.mustache",
|
||||||
|
(sourceFolder + File.separator + invokerPackage).replace(".", File.separator), "Pair.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
|
||||||
|
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
|
||||||
|
|
||||||
|
// gradle wrapper files
|
||||||
|
supportingFiles.add(new SupportingFile("gradlew.mustache", "", "gradlew"));
|
||||||
|
supportingFiles.add(new SupportingFile("gradlew.bat.mustache", "", "gradlew.bat"));
|
||||||
|
supportingFiles.add(new SupportingFile("gradle-wrapper.properties.mustache",
|
||||||
|
gradleWrapperPackage.replace(".", File.separator), "gradle-wrapper.properties"));
|
||||||
|
supportingFiles.add(new SupportingFile("gradle-wrapper.jar",
|
||||||
|
gradleWrapperPackage.replace(".", File.separator), "gradle-wrapper.jar"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSupportingFilesForVolley() {
|
||||||
|
// documentation files
|
||||||
|
modelDocTemplateFiles.put("model_doc.mustache", ".md");
|
||||||
|
apiDocTemplateFiles.put("api_doc.mustache", ".md");
|
||||||
|
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
|
||||||
|
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
|
||||||
|
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
|
||||||
|
// supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle"));
|
||||||
|
supportingFiles.add(new SupportingFile("build.mustache", "", "build.gradle"));
|
||||||
|
supportingFiles.add(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml"));
|
||||||
|
supportingFiles.add(new SupportingFile("apiInvoker.mustache",
|
||||||
|
(sourceFolder + File.separator + invokerPackage).replace(".", File.separator), "ApiInvoker.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("jsonUtil.mustache",
|
||||||
|
(sourceFolder + File.separator + invokerPackage).replace(".", File.separator), "JsonUtil.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("apiException.mustache",
|
||||||
|
(sourceFolder + File.separator + invokerPackage).replace(".", File.separator), "ApiException.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("Pair.mustache",
|
||||||
|
(sourceFolder + File.separator + invokerPackage).replace(".", File.separator), "Pair.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("request/getrequest.mustache",
|
||||||
|
(sourceFolder + File.separator + requestPackage).replace(".", File.separator), "GetRequest.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("request/postrequest.mustache",
|
||||||
|
(sourceFolder + File.separator + requestPackage).replace(".", File.separator), "PostRequest.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("request/putrequest.mustache",
|
||||||
|
(sourceFolder + File.separator + requestPackage).replace(".", File.separator), "PutRequest.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("request/deleterequest.mustache",
|
||||||
|
(sourceFolder + File.separator + requestPackage).replace(".", File.separator), "DeleteRequest.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("request/patchrequest.mustache",
|
||||||
|
(sourceFolder + File.separator + requestPackage).replace(".", File.separator), "PatchRequest.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("auth/apikeyauth.mustache",
|
||||||
|
(sourceFolder + File.separator + authPackage).replace(".", File.separator), "ApiKeyAuth.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("auth/httpbasicauth.mustache",
|
||||||
|
(sourceFolder + File.separator + authPackage).replace(".", File.separator), "HttpBasicAuth.java"));
|
||||||
|
supportingFiles.add(new SupportingFile("auth/authentication.mustache",
|
||||||
|
(sourceFolder + File.separator + authPackage).replace(".", File.separator), "Authentication.java"));
|
||||||
|
|
||||||
|
// gradle wrapper files
|
||||||
|
supportingFiles.add(new SupportingFile("gradlew.mustache", "", "gradlew"));
|
||||||
|
supportingFiles.add(new SupportingFile("gradlew.bat.mustache", "", "gradlew.bat"));
|
||||||
|
supportingFiles.add(new SupportingFile("gradle-wrapper.properties.mustache",
|
||||||
|
gradleWrapperPackage.replace(".", File.separator), "gradle-wrapper.properties"));
|
||||||
|
supportingFiles.add(new SupportingFile("gradle-wrapper.jar",
|
||||||
|
gradleWrapperPackage.replace(".", File.separator), "gradle-wrapper.jar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getUseAndroidMavenGradlePlugin() {
|
||||||
|
return useAndroidMavenGradlePlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAndroidGradleVersion() {
|
||||||
|
return androidGradleVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAndroidSdkVersion() {
|
||||||
|
return androidSdkVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAndroidBuildToolsVersion() {
|
||||||
|
return androidBuildToolsVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUseAndroidMavenGradlePlugin(Boolean useAndroidMavenGradlePlugin) {
|
||||||
|
this.useAndroidMavenGradlePlugin = useAndroidMavenGradlePlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAndroidGradleVersion(String androidGradleVersion) {
|
||||||
|
this.androidGradleVersion = androidGradleVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAndroidSdkVersion(String androidSdkVersion) {
|
||||||
|
this.androidSdkVersion = androidSdkVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAndroidBuildToolsVersion(String androidBuildToolsVersion) {
|
||||||
|
this.androidBuildToolsVersion = androidBuildToolsVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInvokerPackage(String invokerPackage) {
|
||||||
|
this.invokerPackage = invokerPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestPackage(String requestPackage) {
|
||||||
|
this.requestPackage = requestPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthPackage(String authPackage) {
|
||||||
|
this.authPackage = authPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroupId(String groupId) {
|
||||||
|
this.groupId = groupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArtifactId(String artifactId) {
|
||||||
|
this.artifactId = artifactId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArtifactVersion(String artifactVersion) {
|
||||||
|
this.artifactVersion = artifactVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceFolder(String sourceFolder) {
|
||||||
|
this.sourceFolder = sourceFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSerializableModel(Boolean serializableModel) {
|
||||||
|
this.serializableModel = serializableModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeQuotationMark(String input) {
|
||||||
|
// remove " to avoid code injection
|
||||||
|
return input.replace("\"", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeUnsafeCharacters(String input) {
|
||||||
|
return input.replace("*/", "*_/").replace("/*", "/_*");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,475 @@
|
|||||||
|
package org.openapitools.codegen.languages;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.CliOption;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
import org.openapitools.codegen.CodegenModel;
|
||||||
|
import org.openapitools.codegen.CodegenProperty;
|
||||||
|
import org.openapitools.codegen.CodegenType;
|
||||||
|
import org.openapitools.codegen.DefaultCodegen;
|
||||||
|
import org.openapitools.codegen.SupportingFile;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.Operation;
|
||||||
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||||
|
public static final String BROWSER_CLIENT = "browserClient";
|
||||||
|
public static final String PUB_NAME = "pubName";
|
||||||
|
public static final String PUB_VERSION = "pubVersion";
|
||||||
|
public static final String PUB_DESCRIPTION = "pubDescription";
|
||||||
|
public static final String USE_ENUM_EXTENSION = "useEnumExtension";
|
||||||
|
protected boolean browserClient = true;
|
||||||
|
protected String pubName = "swagger";
|
||||||
|
protected String pubVersion = "1.0.0";
|
||||||
|
protected String pubDescription = "Swagger API client";
|
||||||
|
protected boolean useEnumExtension = false;
|
||||||
|
protected String sourceFolder = "";
|
||||||
|
protected String apiDocPath = "docs/";
|
||||||
|
protected String modelDocPath = "docs/";
|
||||||
|
|
||||||
|
public DartClientCodegen() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// clear import mapping (from default generator) as dart does not use it
|
||||||
|
// at the moment
|
||||||
|
importMapping.clear();
|
||||||
|
|
||||||
|
outputFolder = "generated-code/dart";
|
||||||
|
modelTemplateFiles.put("model.mustache", ".dart");
|
||||||
|
apiTemplateFiles.put("api.mustache", ".dart");
|
||||||
|
embeddedTemplateDir = templateDir = "dart";
|
||||||
|
apiPackage = "lib.api";
|
||||||
|
modelPackage = "lib.model";
|
||||||
|
modelDocTemplateFiles.put("object_doc.mustache", ".md");
|
||||||
|
apiDocTemplateFiles.put("api_doc.mustache", ".md");
|
||||||
|
|
||||||
|
setReservedWordsLowerCase(
|
||||||
|
Arrays.asList(
|
||||||
|
"abstract", "as", "assert", "async", "async*", "await",
|
||||||
|
"break", "case", "catch", "class", "const", "continue",
|
||||||
|
"default", "deferred", "do", "dynamic", "else", "enum",
|
||||||
|
"export", "external", "extends", "factory", "false", "final",
|
||||||
|
"finally", "for", "get", "if", "implements", "import", "in",
|
||||||
|
"is", "library", "new", "null", "operator", "part", "rethrow",
|
||||||
|
"return", "set", "static", "super", "switch", "sync*", "this",
|
||||||
|
"throw", "true", "try", "typedef", "var", "void", "while",
|
||||||
|
"with", "yield", "yield*" )
|
||||||
|
);
|
||||||
|
|
||||||
|
languageSpecificPrimitives = new HashSet<String>(
|
||||||
|
Arrays.asList(
|
||||||
|
"String",
|
||||||
|
"bool",
|
||||||
|
"int",
|
||||||
|
"num",
|
||||||
|
"double")
|
||||||
|
);
|
||||||
|
instantiationTypes.put("array", "List");
|
||||||
|
instantiationTypes.put("map", "Map");
|
||||||
|
|
||||||
|
typeMapping = new HashMap<String, String>();
|
||||||
|
typeMapping.put("Array", "List");
|
||||||
|
typeMapping.put("array", "List");
|
||||||
|
typeMapping.put("List", "List");
|
||||||
|
typeMapping.put("boolean", "bool");
|
||||||
|
typeMapping.put("string", "String");
|
||||||
|
typeMapping.put("char", "String");
|
||||||
|
typeMapping.put("int", "int");
|
||||||
|
typeMapping.put("long", "int");
|
||||||
|
typeMapping.put("short", "int");
|
||||||
|
typeMapping.put("number", "num");
|
||||||
|
typeMapping.put("float", "double");
|
||||||
|
typeMapping.put("double", "double");
|
||||||
|
typeMapping.put("object", "Object");
|
||||||
|
typeMapping.put("integer", "int");
|
||||||
|
typeMapping.put("Date", "DateTime");
|
||||||
|
typeMapping.put("date", "DateTime");
|
||||||
|
typeMapping.put("File", "MultipartFile");
|
||||||
|
typeMapping.put("UUID", "String");
|
||||||
|
//TODO binary should be mapped to byte array
|
||||||
|
// mapped to String as a workaround
|
||||||
|
typeMapping.put("binary", "String");
|
||||||
|
|
||||||
|
cliOptions.add(new CliOption(BROWSER_CLIENT, "Is the client browser based"));
|
||||||
|
cliOptions.add(new CliOption(PUB_NAME, "Name in generated pubspec"));
|
||||||
|
cliOptions.add(new CliOption(PUB_VERSION, "Version in generated pubspec"));
|
||||||
|
cliOptions.add(new CliOption(PUB_DESCRIPTION, "Description in generated pubspec"));
|
||||||
|
cliOptions.add(new CliOption(USE_ENUM_EXTENSION, "Allow the 'x-enum-values' extension for enums"));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, "source folder for generated code"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.CLIENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "dart";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates a Dart client library.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processOpts() {
|
||||||
|
super.processOpts();
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(BROWSER_CLIENT)) {
|
||||||
|
this.setBrowserClient(convertPropertyToBooleanAndWriteBack(BROWSER_CLIENT));
|
||||||
|
} else {
|
||||||
|
//not set, use to be passed to template
|
||||||
|
additionalProperties.put(BROWSER_CLIENT, browserClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(PUB_NAME)) {
|
||||||
|
this.setPubName((String) additionalProperties.get(PUB_NAME));
|
||||||
|
} else {
|
||||||
|
//not set, use to be passed to template
|
||||||
|
additionalProperties.put(PUB_NAME, pubName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(PUB_VERSION)) {
|
||||||
|
this.setPubVersion((String) additionalProperties.get(PUB_VERSION));
|
||||||
|
} else {
|
||||||
|
//not set, use to be passed to template
|
||||||
|
additionalProperties.put(PUB_VERSION, pubVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(PUB_DESCRIPTION)) {
|
||||||
|
this.setPubDescription((String) additionalProperties.get(PUB_DESCRIPTION));
|
||||||
|
} else {
|
||||||
|
//not set, use to be passed to template
|
||||||
|
additionalProperties.put(PUB_DESCRIPTION, pubDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(USE_ENUM_EXTENSION)) {
|
||||||
|
this.setUseEnumExtension(convertPropertyToBooleanAndWriteBack(USE_ENUM_EXTENSION));
|
||||||
|
} else {
|
||||||
|
// Not set, use to be passed to template.
|
||||||
|
additionalProperties.put(USE_ENUM_EXTENSION, useEnumExtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
|
||||||
|
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
|
||||||
|
}
|
||||||
|
|
||||||
|
// default HIDE_GENERATION_TIMESTAMP to true
|
||||||
|
if (!additionalProperties.containsKey(CodegenConstants.HIDE_GENERATION_TIMESTAMP)) {
|
||||||
|
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, Boolean.TRUE.toString());
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP,
|
||||||
|
Boolean.valueOf(additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP).toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// make api and model doc path available in mustache template
|
||||||
|
additionalProperties.put("apiDocPath", apiDocPath);
|
||||||
|
additionalProperties.put("modelDocPath", modelDocPath);
|
||||||
|
|
||||||
|
final String libFolder = sourceFolder + File.separator + "lib";
|
||||||
|
supportingFiles.add(new SupportingFile("pubspec.mustache", "", "pubspec.yaml"));
|
||||||
|
supportingFiles.add(new SupportingFile("analysis_options.mustache", "", ".analysis_options"));
|
||||||
|
supportingFiles.add(new SupportingFile("api_client.mustache", libFolder, "api_client.dart"));
|
||||||
|
supportingFiles.add(new SupportingFile("api_exception.mustache", libFolder, "api_exception.dart"));
|
||||||
|
supportingFiles.add(new SupportingFile("api_helper.mustache", libFolder, "api_helper.dart"));
|
||||||
|
supportingFiles.add(new SupportingFile("apilib.mustache", libFolder, "api.dart"));
|
||||||
|
|
||||||
|
final String authFolder = sourceFolder + File.separator + "lib" + File.separator + "auth";
|
||||||
|
supportingFiles.add(new SupportingFile("auth/authentication.mustache", authFolder, "authentication.dart"));
|
||||||
|
supportingFiles.add(new SupportingFile("auth/http_basic_auth.mustache", authFolder, "http_basic_auth.dart"));
|
||||||
|
supportingFiles.add(new SupportingFile("auth/api_key_auth.mustache", authFolder, "api_key_auth.dart"));
|
||||||
|
supportingFiles.add(new SupportingFile("auth/oauth.mustache", authFolder, "oauth.dart"));
|
||||||
|
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
|
||||||
|
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
|
||||||
|
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeReservedWord(String name) {
|
||||||
|
return name + "_";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiFileFolder() {
|
||||||
|
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelFileFolder() {
|
||||||
|
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiDocFileFolder() {
|
||||||
|
return (outputFolder + "/" + apiDocPath).replace('/', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelDocFileFolder() {
|
||||||
|
return (outputFolder + "/" + modelDocPath).replace('/', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toVarName(String name) {
|
||||||
|
// replace - with _ e.g. created-at => created_at
|
||||||
|
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
|
||||||
|
// if it's all uppper case, do nothing
|
||||||
|
if (name.matches("^[A-Z_]*$")) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize (lower first character) the variable name
|
||||||
|
// pet_id => petId
|
||||||
|
name = camelize(name, true);
|
||||||
|
|
||||||
|
if (name.matches("^\\d.*")) {
|
||||||
|
name = "n" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
name = escapeReservedWord(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toParamName(String name) {
|
||||||
|
// should be the same as variable name
|
||||||
|
return toVarName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelName(String name) {
|
||||||
|
// model name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
LOGGER.warn(name + " (reserved word) cannot be used as model filename. Renamed to " + camelize("model_" + name));
|
||||||
|
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize the model name
|
||||||
|
// phone_number => PhoneNumber
|
||||||
|
return camelize(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelFilename(String name) {
|
||||||
|
return underscore(toModelName(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiFilename(String name) {
|
||||||
|
return underscore(toApiName(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toDefaultValue(Schema p) {
|
||||||
|
if (p instanceof MapSchema) {
|
||||||
|
return "{}";
|
||||||
|
} else if (p instanceof ArraySchema) {
|
||||||
|
return "[]";
|
||||||
|
}
|
||||||
|
return super.toDefaultValue(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(Schema p) {
|
||||||
|
if (p instanceof ArraySchema) {
|
||||||
|
ArraySchema ap = (ArraySchema) p;
|
||||||
|
Schema inner = ap.getItems();
|
||||||
|
return getSchemaType(p) + "<" + getTypeDeclaration(inner) + ">";
|
||||||
|
} else if (p instanceof MapSchema) {
|
||||||
|
MapSchema mp = (MapSchema) p;
|
||||||
|
Schema inner = (Schema) mp.getAdditionalProperties();
|
||||||
|
|
||||||
|
return getSchemaType(p) + "<String, " + getTypeDeclaration(inner) + ">";
|
||||||
|
}
|
||||||
|
return super.getTypeDeclaration(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSchemaType(Schema p) {
|
||||||
|
String openAPIType = super.getSchemaType(p);
|
||||||
|
String type = null;
|
||||||
|
if (typeMapping.containsKey(openAPIType)) {
|
||||||
|
type = typeMapping.get(openAPIType);
|
||||||
|
if (languageSpecificPrimitives.contains(type)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
type = openAPIType;
|
||||||
|
}
|
||||||
|
return toModelName(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||||
|
return postProcessModelsEnum(objs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
|
||||||
|
List<Object> models = (List<Object>) objs.get("models");
|
||||||
|
for (Object _mo : models) {
|
||||||
|
Map<String, Object> mo = (Map<String, Object>) _mo;
|
||||||
|
CodegenModel cm = (CodegenModel) mo.get("model");
|
||||||
|
boolean succes = buildEnumFromVendorExtension(cm) ||
|
||||||
|
buildEnumFromValues(cm);
|
||||||
|
for (CodegenProperty var : cm.vars) {
|
||||||
|
updateCodegenPropertyEnum(var);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return objs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the set of enum members from their declared value.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the enum was built
|
||||||
|
*/
|
||||||
|
private boolean buildEnumFromValues(CodegenModel cm) {
|
||||||
|
if (!cm.isEnum || cm.allowableValues == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Map<String, Object> allowableValues = cm.allowableValues;
|
||||||
|
List<Object> values = (List<Object>) allowableValues.get("values");
|
||||||
|
List<Map<String, String>> enumVars =
|
||||||
|
new ArrayList<Map<String, String>>();
|
||||||
|
String commonPrefix = findCommonPrefixOfVars(values);
|
||||||
|
int truncateIdx = commonPrefix.length();
|
||||||
|
for (Object value : values) {
|
||||||
|
Map<String, String> enumVar = new HashMap<String, String>();
|
||||||
|
String enumName;
|
||||||
|
if (truncateIdx == 0) {
|
||||||
|
enumName = value.toString();
|
||||||
|
} else {
|
||||||
|
enumName = value.toString().substring(truncateIdx);
|
||||||
|
if ("".equals(enumName)) {
|
||||||
|
enumName = value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumVar.put("name", toEnumVarName(enumName, cm.dataType));
|
||||||
|
enumVar.put("value", toEnumValue(value.toString(), cm.dataType));
|
||||||
|
enumVars.add(enumVar);
|
||||||
|
}
|
||||||
|
cm.allowableValues.put("enumVars", enumVars);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the set of enum members from a vendor extension.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the enum was built
|
||||||
|
*/
|
||||||
|
private boolean buildEnumFromVendorExtension(CodegenModel cm) {
|
||||||
|
if (!cm.isEnum || cm.allowableValues == null ||
|
||||||
|
!useEnumExtension ||
|
||||||
|
!cm.vendorExtensions.containsKey("x-enum-values")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Object extension = cm.vendorExtensions.get("x-enum-values");
|
||||||
|
List<Map<String, Object>> values =
|
||||||
|
(List<Map<String, Object>>) extension;
|
||||||
|
List<Map<String, String>> enumVars =
|
||||||
|
new ArrayList<Map<String, String>>();
|
||||||
|
for (Map<String, Object> value : values) {
|
||||||
|
Map<String, String> enumVar = new HashMap<String, String>();
|
||||||
|
String name = camelize((String) value.get("identifier"), true);
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
name = escapeReservedWord(name);
|
||||||
|
}
|
||||||
|
enumVar.put("name", name);
|
||||||
|
enumVar.put("value", toEnumValue(
|
||||||
|
value.get("numericValue").toString(), cm.dataType));
|
||||||
|
if (value.containsKey("description")) {
|
||||||
|
enumVar.put("description", value.get("description").toString());
|
||||||
|
}
|
||||||
|
enumVars.add(enumVar);
|
||||||
|
}
|
||||||
|
cm.allowableValues.put("enumVars", enumVars);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toEnumVarName(String value, String datatype) {
|
||||||
|
if (value.length() == 0) {
|
||||||
|
return "empty";
|
||||||
|
}
|
||||||
|
String var = value.replaceAll("\\W+", "_");
|
||||||
|
if ("number".equalsIgnoreCase(datatype) ||
|
||||||
|
"int".equalsIgnoreCase(datatype)) {
|
||||||
|
var = "Number" + var;
|
||||||
|
}
|
||||||
|
return escapeReservedWord(camelize(var, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toEnumValue(String value, String datatype) {
|
||||||
|
if ("number".equalsIgnoreCase(datatype) ||
|
||||||
|
"int".equalsIgnoreCase(datatype)) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return "\"" + escapeText(value) + "\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toOperationId(String operationId) {
|
||||||
|
// method name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(operationId)) {
|
||||||
|
String newOperationId = camelize("call_" + operationId, true);
|
||||||
|
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + newOperationId);
|
||||||
|
return newOperationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return camelize(operationId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBrowserClient(boolean browserClient) {
|
||||||
|
this.browserClient = browserClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPubName(String pubName) {
|
||||||
|
this.pubName = pubName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPubVersion(String pubVersion) {
|
||||||
|
this.pubVersion = pubVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPubDescription(String pubDescription) {
|
||||||
|
this.pubDescription = pubDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUseEnumExtension(boolean useEnumExtension) {
|
||||||
|
this.useEnumExtension = useEnumExtension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceFolder(String sourceFolder) {
|
||||||
|
this.sourceFolder = sourceFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeQuotationMark(String input) {
|
||||||
|
// remove " to avoid code injection
|
||||||
|
return input.replace("\"", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeUnsafeCharacters(String input) {
|
||||||
|
return input.replace("*/", "*_/").replace("/*", "/_*");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,759 @@
|
|||||||
|
package org.openapitools.codegen.languages;
|
||||||
|
|
||||||
|
import com.samskivert.mustache.Mustache;
|
||||||
|
import com.samskivert.mustache.Template;
|
||||||
|
import org.openapitools.codegen.*;
|
||||||
|
import io.swagger.v3.oas.models.*;
|
||||||
|
import io.swagger.v3.oas.models.info.Info;
|
||||||
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class ElixirClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||||
|
protected String apiVersion = "1.0.0";
|
||||||
|
protected String moduleName;
|
||||||
|
protected static final String defaultModuleName = "Swagger.Client";
|
||||||
|
|
||||||
|
// This is the name of elixir project name;
|
||||||
|
protected static final String defaultPackageName = "swagger_client";
|
||||||
|
|
||||||
|
String supportedElixirVersion = "1.4";
|
||||||
|
List<String> extraApplications = Arrays.asList(":logger");
|
||||||
|
List<String> deps = Arrays.asList(
|
||||||
|
"{:tesla, \"~> 0.8\"}",
|
||||||
|
"{:poison, \">= 1.0.0\"}"
|
||||||
|
);
|
||||||
|
|
||||||
|
public ElixirClientCodegen() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// set the output folder here
|
||||||
|
outputFolder = "generated-code/elixir";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Models. You can write model files using the modelTemplateFiles map.
|
||||||
|
* if you want to create one template for file, you can do so here.
|
||||||
|
* for multiple files for model, just put another entry in the `modelTemplateFiles` with
|
||||||
|
* a different extension
|
||||||
|
*/
|
||||||
|
modelTemplateFiles.put(
|
||||||
|
"model.mustache", // the template to use
|
||||||
|
".ex"); // the extension for each file to write
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Api classes. You can write classes for each Api file with the apiTemplateFiles map.
|
||||||
|
* as with models, add multiple entries with different extensions for multiple files per
|
||||||
|
* class
|
||||||
|
*/
|
||||||
|
apiTemplateFiles.put(
|
||||||
|
"api.mustache", // the template to use
|
||||||
|
".ex"); // the extension for each file to write
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template Location. This is the location which templates will be read from. The generator
|
||||||
|
* will use the resource stream to attempt to read the templates.
|
||||||
|
*/
|
||||||
|
templateDir = "elixir";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reserved words. Override this with reserved words specific to your language
|
||||||
|
* Ref: https://github.com/itsgreggreg/elixir_quick_reference#reserved-words
|
||||||
|
*/
|
||||||
|
reservedWords = new HashSet<String>(
|
||||||
|
Arrays.asList(
|
||||||
|
"nil",
|
||||||
|
"true",
|
||||||
|
"false",
|
||||||
|
"__MODULE__",
|
||||||
|
"__FILE__",
|
||||||
|
"__DIR__",
|
||||||
|
"__ENV__",
|
||||||
|
"__CALLER__")
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional Properties. These values can be passed to the templates and
|
||||||
|
* are available in models, apis, and supporting files
|
||||||
|
*/
|
||||||
|
additionalProperties.put("apiVersion", apiVersion);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supporting Files. You can write single files for the generator with the
|
||||||
|
* entire object tree available. If the input file has a suffix of `.mustache
|
||||||
|
* it will be processed by the template engine. Otherwise, it will be copied
|
||||||
|
*/
|
||||||
|
supportingFiles.add(new SupportingFile("README.md.mustache", // the input template or file
|
||||||
|
"", // the destination folder, relative `outputFolder`
|
||||||
|
"README.md") // the output file
|
||||||
|
);
|
||||||
|
supportingFiles.add(new SupportingFile("config.exs.mustache",
|
||||||
|
"config",
|
||||||
|
"config.exs")
|
||||||
|
);
|
||||||
|
supportingFiles.add(new SupportingFile("mix.exs.mustache",
|
||||||
|
"",
|
||||||
|
"mix.exs")
|
||||||
|
);
|
||||||
|
supportingFiles.add(new SupportingFile("test_helper.exs.mustache",
|
||||||
|
"test",
|
||||||
|
"test_helper.exs")
|
||||||
|
);
|
||||||
|
supportingFiles.add(new SupportingFile("gitignore.mustache",
|
||||||
|
"",
|
||||||
|
".gitignore")
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Language Specific Primitives. These types will not trigger imports by
|
||||||
|
* the client generator
|
||||||
|
*/
|
||||||
|
languageSpecificPrimitives = new HashSet<String>(
|
||||||
|
Arrays.asList(
|
||||||
|
"Integer",
|
||||||
|
"Float",
|
||||||
|
"Boolean",
|
||||||
|
"String",
|
||||||
|
"List",
|
||||||
|
"Atom",
|
||||||
|
"Map",
|
||||||
|
"Tuple",
|
||||||
|
"PID",
|
||||||
|
"DateTime"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// ref: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types
|
||||||
|
typeMapping = new HashMap<String, String>();
|
||||||
|
typeMapping.put("integer", "Integer");
|
||||||
|
typeMapping.put("long", "Integer");
|
||||||
|
typeMapping.put("number", "Float");
|
||||||
|
typeMapping.put("float", "Float");
|
||||||
|
typeMapping.put("double", "Float");
|
||||||
|
typeMapping.put("string", "String");
|
||||||
|
typeMapping.put("byte", "Integer");
|
||||||
|
typeMapping.put("boolean", "Boolean");
|
||||||
|
typeMapping.put("Date", "DateTime");
|
||||||
|
typeMapping.put("DateTime", "DateTime");
|
||||||
|
typeMapping.put("file", "String");
|
||||||
|
typeMapping.put("map", "Map");
|
||||||
|
typeMapping.put("array", "List");
|
||||||
|
typeMapping.put("list", "List");
|
||||||
|
// typeMapping.put("object", "Map");
|
||||||
|
typeMapping.put("binary", "String");
|
||||||
|
typeMapping.put("ByteArray", "String");
|
||||||
|
typeMapping.put("UUID", "String");
|
||||||
|
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, "The main namespace to use for all classes. e.g. Yay.Pets"));
|
||||||
|
cliOptions.add(new CliOption("licenseHeader", "The license header to prepend to the top of all source files."));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Elixir package name (convention: lowercase)."));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the type of generator.
|
||||||
|
*
|
||||||
|
* @return the CodegenType for this generator
|
||||||
|
* @see org.openapitools.codegen.CodegenType
|
||||||
|
*/
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.CLIENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures a friendly name for the generator. This will be used by the generator
|
||||||
|
* to select the library with the -l flag.
|
||||||
|
*
|
||||||
|
* @return the friendly name for the generator
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return "elixir";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns human-friendly help for the generator. Provide the consumer with help
|
||||||
|
* tips, parameters here
|
||||||
|
*
|
||||||
|
* @return A string value for the help message
|
||||||
|
*/
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates an elixir client library (alpha).";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processOpts() {
|
||||||
|
super.processOpts();
|
||||||
|
additionalProperties.put("supportedElixirVersion", supportedElixirVersion);
|
||||||
|
additionalProperties.put("extraApplications", join(",", extraApplications));
|
||||||
|
additionalProperties.put("deps", deps);
|
||||||
|
additionalProperties.put("underscored", new Mustache.Lambda() {
|
||||||
|
@Override
|
||||||
|
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
|
||||||
|
writer.write(underscored(fragment.execute()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
additionalProperties.put("modulized", new Mustache.Lambda() {
|
||||||
|
@Override
|
||||||
|
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
|
||||||
|
writer.write(modulized(fragment.execute()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
|
||||||
|
setModuleName((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preprocessOpenAPI(OpenAPI openAPI) {
|
||||||
|
Info info = openAPI.getInfo();
|
||||||
|
if (moduleName == null) {
|
||||||
|
if (info.getTitle() != null) {
|
||||||
|
// default to the appName (from title field)
|
||||||
|
setModuleName(modulized(escapeText(info.getTitle())));
|
||||||
|
} else {
|
||||||
|
setModuleName(defaultModuleName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
additionalProperties.put("moduleName", moduleName);
|
||||||
|
|
||||||
|
if (!additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
|
||||||
|
additionalProperties.put(CodegenConstants.PACKAGE_NAME, underscored(moduleName));
|
||||||
|
}
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("connection.ex.mustache",
|
||||||
|
sourceFolder(),
|
||||||
|
"connection.ex"));
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("request_builder.ex.mustache",
|
||||||
|
sourceFolder(),
|
||||||
|
"request_builder.ex"));
|
||||||
|
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("deserializer.ex.mustache",
|
||||||
|
sourceFolder(),
|
||||||
|
"deserializer.ex"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||||
|
Map<String, Object> operations = (Map<String, Object>) super.postProcessOperations(objs).get("operations");
|
||||||
|
List<CodegenOperation> os = (List<CodegenOperation>) operations.get("operation");
|
||||||
|
List<ExtendedCodegenOperation> newOs = new ArrayList<ExtendedCodegenOperation>();
|
||||||
|
Pattern pattern = Pattern.compile("\\{([^\\}]+)\\}([^\\{]*)");
|
||||||
|
for (CodegenOperation o : os) {
|
||||||
|
ArrayList<String> pathTemplateNames = new ArrayList<String>();
|
||||||
|
Matcher matcher = pattern.matcher(o.path);
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
while (matcher.find()) {
|
||||||
|
String pathTemplateName = matcher.group(1);
|
||||||
|
matcher.appendReplacement(buffer, "#{" + underscore(pathTemplateName) + "}" + "$2");
|
||||||
|
pathTemplateNames.add(pathTemplateName);
|
||||||
|
}
|
||||||
|
ExtendedCodegenOperation eco = new ExtendedCodegenOperation(o);
|
||||||
|
if (buffer.toString().isEmpty()) {
|
||||||
|
eco.setReplacedPathName(o.path);
|
||||||
|
} else {
|
||||||
|
eco.setReplacedPathName(buffer.toString());
|
||||||
|
}
|
||||||
|
eco.setPathTemplateNames(pathTemplateNames);
|
||||||
|
|
||||||
|
// detect multipart form types
|
||||||
|
if (eco.hasConsumes == Boolean.TRUE) {
|
||||||
|
Map<String, String> firstType = eco.consumes.get(0);
|
||||||
|
if (firstType != null) {
|
||||||
|
if ("multipart/form-data".equals(firstType.get("mediaType"))) {
|
||||||
|
eco.isMultipart = Boolean.TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newOs.add(eco);
|
||||||
|
}
|
||||||
|
operations.put("operation", newOs);
|
||||||
|
return objs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodegenModel fromModel(String name, Schema model, Map<String, Schema> allDefinitions) {
|
||||||
|
CodegenModel cm = super.fromModel(name, model, allDefinitions);
|
||||||
|
return new ExtendedCodegenModel(cm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We should use String.join if we can use Java8
|
||||||
|
String join(CharSequence charSequence, Iterable<String> iterable) {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
for (String str : iterable) {
|
||||||
|
if (0 < buf.length()) {
|
||||||
|
buf.append((charSequence));
|
||||||
|
}
|
||||||
|
buf.append(str);
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
String underscored(String words) {
|
||||||
|
ArrayList<String> underscoredWords = new ArrayList<String>();
|
||||||
|
for (String word : words.split(" ")) {
|
||||||
|
underscoredWords.add(underscore(word));
|
||||||
|
}
|
||||||
|
return join("_", underscoredWords);
|
||||||
|
}
|
||||||
|
|
||||||
|
String modulized(String words) {
|
||||||
|
ArrayList<String> modulizedWords = new ArrayList<String>();
|
||||||
|
for (String word : words.split(" ")) {
|
||||||
|
modulizedWords.add(camelize(word));
|
||||||
|
}
|
||||||
|
return join("", modulizedWords);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
|
||||||
|
* those terms here. This logic is only called if a variable matches the reserved words
|
||||||
|
*
|
||||||
|
* @return the escaped term
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String escapeReservedWord(String name) {
|
||||||
|
return "_" + name; // add an underscore to the name
|
||||||
|
}
|
||||||
|
|
||||||
|
private String sourceFolder() {
|
||||||
|
ArrayList<String> underscoredWords = new ArrayList<String>();
|
||||||
|
for (String word : moduleName.split("\\.")) {
|
||||||
|
underscoredWords.add(underscore(word));
|
||||||
|
}
|
||||||
|
return "lib/" + join("/", underscoredWords);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location to write model files. You can use the modelPackage() as defined when the class is
|
||||||
|
* instantiated
|
||||||
|
*/
|
||||||
|
public String modelFileFolder() {
|
||||||
|
return outputFolder + "/" + sourceFolder() + "/" + "model";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location to write api files. You can use the apiPackage() as defined when the class is
|
||||||
|
* instantiated
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String apiFileFolder() {
|
||||||
|
return outputFolder + "/" + sourceFolder() + "/" + "api";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiName(String name) {
|
||||||
|
if (name.length() == 0) {
|
||||||
|
return "Default";
|
||||||
|
}
|
||||||
|
return camelize(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiFilename(String name) {
|
||||||
|
// replace - with _ e.g. created-at => created_at
|
||||||
|
name = name.replaceAll("-", "_");
|
||||||
|
|
||||||
|
// e.g. PetApi.go => pet_api.go
|
||||||
|
return underscore(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelName(String name) {
|
||||||
|
// camelize the model name
|
||||||
|
// phone_number => PhoneNumber
|
||||||
|
return camelize(toModelFilename(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelFilename(String name) {
|
||||||
|
if (!StringUtils.isEmpty(modelNamePrefix)) {
|
||||||
|
name = modelNamePrefix + "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(modelNameSuffix)) {
|
||||||
|
name = name + "_" + modelNameSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = sanitizeName(name);
|
||||||
|
|
||||||
|
// model name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + ("model_" + name));
|
||||||
|
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// model name starts with number
|
||||||
|
if (name.matches("^\\d.*")) {
|
||||||
|
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + ("model_" + name));
|
||||||
|
name = "model_" + name; // e.g. 200Response => Model200Response (after camelize)
|
||||||
|
}
|
||||||
|
|
||||||
|
return underscore(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toOperationId(String operationId) {
|
||||||
|
// throw exception if method name is empty (should not occur as an auto-generated method name will be used)
|
||||||
|
if (StringUtils.isEmpty(operationId)) {
|
||||||
|
throw new RuntimeException("Empty method name (operationId) not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return camelize(sanitizeName(operationId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional - type declaration. This is a String which is used by the templates to instantiate your
|
||||||
|
* types. There is typically special handling for different property types
|
||||||
|
*
|
||||||
|
* @return a string value used as the `dataType` field for model templates, `returnType` for api templates
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(Schema p) {
|
||||||
|
if (p instanceof ArraySchema) {
|
||||||
|
ArraySchema ap = (ArraySchema) p;
|
||||||
|
Schema inner = ap.getItems();
|
||||||
|
return "[" + getTypeDeclaration(inner) + "]";
|
||||||
|
} else if (p instanceof MapSchema) {
|
||||||
|
MapSchema mp = (MapSchema) p;
|
||||||
|
Schema inner = (Schema) mp.getAdditionalProperties();
|
||||||
|
return "%{optional(String.t) => " + getTypeDeclaration(inner) + "}";
|
||||||
|
} else if (p instanceof PasswordSchema) {
|
||||||
|
return "String.t";
|
||||||
|
} else if (p instanceof EmailSchema) {
|
||||||
|
return "String.t";
|
||||||
|
} else if (p instanceof ByteArraySchema) {
|
||||||
|
return "binary()";
|
||||||
|
} else if (p instanceof StringSchema) {
|
||||||
|
return "String.t";
|
||||||
|
} else if (p instanceof DateSchema) {
|
||||||
|
return "Date.t";
|
||||||
|
} else if (p instanceof UUIDSchema) {
|
||||||
|
return "String.t";
|
||||||
|
} else if (p instanceof DateTimeSchema) {
|
||||||
|
return "DateTime.t";
|
||||||
|
} else if (p instanceof ObjectSchema) {
|
||||||
|
// How to map it?
|
||||||
|
return super.getTypeDeclaration(p);
|
||||||
|
} else if (p instanceof IntegerSchema) {
|
||||||
|
return "integer()";
|
||||||
|
} else if (p instanceof NumberSchema) {
|
||||||
|
return "float()";
|
||||||
|
} else if (p instanceof BinarySchema) {
|
||||||
|
return "binary()";
|
||||||
|
} else if (p instanceof BooleanSchema) {
|
||||||
|
return "boolean()";
|
||||||
|
} else if (!StringUtils.isEmpty(p.get$ref())) { // model
|
||||||
|
// How to map it?
|
||||||
|
return super.getTypeDeclaration(p);
|
||||||
|
} else if (p instanceof FileSchema) {
|
||||||
|
return "String.t";
|
||||||
|
}
|
||||||
|
return super.getTypeDeclaration(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional - swagger type conversion. This is used to map swagger types in a `Schema` into
|
||||||
|
* either language specific types via `typeMapping` or into complex models if there is not a mapping.
|
||||||
|
*
|
||||||
|
* @return a string value of the type or complex model for this property
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getSchemaType(Schema p) {
|
||||||
|
String openAPIType = super.getSchemaType(p);
|
||||||
|
String type = null;
|
||||||
|
if (typeMapping.containsKey(openAPIType)) {
|
||||||
|
type = typeMapping.get(openAPIType);
|
||||||
|
if (languageSpecificPrimitives.contains(type))
|
||||||
|
return toModelName(type);
|
||||||
|
} else
|
||||||
|
type = openAPIType;
|
||||||
|
return toModelName(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExtendedCodegenOperation extends CodegenOperation {
|
||||||
|
private List<String> pathTemplateNames = new ArrayList<String>();
|
||||||
|
private String replacedPathName;
|
||||||
|
|
||||||
|
public ExtendedCodegenOperation(CodegenOperation o) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Copy all fields of CodegenOperation
|
||||||
|
this.responseHeaders.addAll(o.responseHeaders);
|
||||||
|
this.hasAuthMethods = o.hasAuthMethods;
|
||||||
|
this.hasConsumes = o.hasConsumes;
|
||||||
|
this.hasProduces = o.hasProduces;
|
||||||
|
this.hasParams = o.hasParams;
|
||||||
|
this.hasOptionalParams = o.hasOptionalParams;
|
||||||
|
this.returnTypeIsPrimitive = o.returnTypeIsPrimitive;
|
||||||
|
this.returnSimpleType = o.returnSimpleType;
|
||||||
|
this.subresourceOperation = o.subresourceOperation;
|
||||||
|
this.isMapContainer = o.isMapContainer;
|
||||||
|
this.isListContainer = o.isListContainer;
|
||||||
|
this.isMultipart = o.isMultipart;
|
||||||
|
this.hasMore = o.hasMore;
|
||||||
|
this.isResponseBinary = o.isResponseBinary;
|
||||||
|
this.hasReference = o.hasReference;
|
||||||
|
this.isRestfulIndex = o.isRestfulIndex;
|
||||||
|
this.isRestfulShow = o.isRestfulShow;
|
||||||
|
this.isRestfulCreate = o.isRestfulCreate;
|
||||||
|
this.isRestfulUpdate = o.isRestfulUpdate;
|
||||||
|
this.isRestfulDestroy = o.isRestfulDestroy;
|
||||||
|
this.isRestful = o.isRestful;
|
||||||
|
this.path = o.path;
|
||||||
|
this.operationId = o.operationId;
|
||||||
|
this.returnType = o.returnType;
|
||||||
|
this.httpMethod = o.httpMethod;
|
||||||
|
this.returnBaseType = o.returnBaseType;
|
||||||
|
this.returnContainer = o.returnContainer;
|
||||||
|
this.summary = o.summary;
|
||||||
|
this.unescapedNotes = o.unescapedNotes;
|
||||||
|
this.notes = o.notes;
|
||||||
|
this.baseName = o.baseName;
|
||||||
|
this.defaultResponse = o.defaultResponse;
|
||||||
|
this.discriminator = o.discriminator;
|
||||||
|
this.consumes = o.consumes;
|
||||||
|
this.produces = o.produces;
|
||||||
|
this.bodyParam = o.bodyParam;
|
||||||
|
this.allParams = o.allParams;
|
||||||
|
this.bodyParams = o.bodyParams;
|
||||||
|
this.pathParams = o.pathParams;
|
||||||
|
this.queryParams = o.queryParams;
|
||||||
|
this.headerParams = o.headerParams;
|
||||||
|
this.formParams = o.formParams;
|
||||||
|
this.authMethods = o.authMethods;
|
||||||
|
this.tags = o.tags;
|
||||||
|
this.responses = o.responses;
|
||||||
|
this.imports = o.imports;
|
||||||
|
this.examples = o.examples;
|
||||||
|
this.externalDocs = o.externalDocs;
|
||||||
|
this.vendorExtensions = o.vendorExtensions;
|
||||||
|
this.nickname = o.nickname;
|
||||||
|
this.operationIdLowerCase = o.operationIdLowerCase;
|
||||||
|
this.operationIdCamelCase = o.operationIdCamelCase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getPathTemplateNames() {
|
||||||
|
return pathTemplateNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPathTemplateNames(List<String> pathTemplateNames) {
|
||||||
|
this.pathTemplateNames = pathTemplateNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReplacedPathName() {
|
||||||
|
return replacedPathName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReplacedPathName(String replacedPathName) {
|
||||||
|
this.replacedPathName = replacedPathName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String typespec() {
|
||||||
|
StringBuilder sb = new StringBuilder("@spec ");
|
||||||
|
sb.append(underscore(operationId));
|
||||||
|
sb.append("(Tesla.Env.client, ");
|
||||||
|
|
||||||
|
for (CodegenParameter param : allParams) {
|
||||||
|
if (param.required) {
|
||||||
|
buildTypespec(param, sb);
|
||||||
|
sb.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append("keyword()) :: {:ok, ");
|
||||||
|
if (returnBaseType == null) {
|
||||||
|
sb.append("nil");
|
||||||
|
} else if (returnSimpleType) {
|
||||||
|
if (!returnTypeIsPrimitive) {
|
||||||
|
sb.append(moduleName);
|
||||||
|
sb.append(".Model.");
|
||||||
|
}
|
||||||
|
sb.append(returnBaseType);
|
||||||
|
sb.append(".t");
|
||||||
|
} else if (returnContainer == null) {
|
||||||
|
sb.append(returnBaseType);
|
||||||
|
sb.append(".t");
|
||||||
|
} else {
|
||||||
|
if (returnContainer.equals("array")) {
|
||||||
|
sb.append("list(");
|
||||||
|
if (!returnTypeIsPrimitive) {
|
||||||
|
sb.append(moduleName);
|
||||||
|
sb.append(".Model.");
|
||||||
|
}
|
||||||
|
sb.append(returnBaseType);
|
||||||
|
sb.append(".t)");
|
||||||
|
} else if (returnContainer.equals("map")) {
|
||||||
|
sb.append("map()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append("} | {:error, Tesla.Env.t}");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildTypespec(CodegenParameter param, StringBuilder sb) {
|
||||||
|
if (param.dataType == null) {
|
||||||
|
sb.append("nil");
|
||||||
|
} else if (param.isListContainer) {
|
||||||
|
// list(<subtype>)
|
||||||
|
sb.append("list(");
|
||||||
|
if (param.isBodyParam) {
|
||||||
|
buildTypespec(param.items.items, sb);
|
||||||
|
} else {
|
||||||
|
buildTypespec(param.items, sb);
|
||||||
|
}
|
||||||
|
sb.append(")");
|
||||||
|
} else if (param.isMapContainer) {
|
||||||
|
// %{optional(String.t) => <subtype>}
|
||||||
|
sb.append("%{optional(String.t) => ");
|
||||||
|
buildTypespec(param.items, sb);
|
||||||
|
sb.append("}");
|
||||||
|
} else if (param.isPrimitiveType) {
|
||||||
|
// like `integer()`, `String.t`
|
||||||
|
sb.append(param.dataType);
|
||||||
|
} else if (param.isFile) {
|
||||||
|
sb.append("String.t");
|
||||||
|
} else {
|
||||||
|
// <module>.Model.<type>.t
|
||||||
|
sb.append(moduleName);
|
||||||
|
sb.append(".Model.");
|
||||||
|
sb.append(param.dataType);
|
||||||
|
sb.append(".t");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildTypespec(CodegenProperty property, StringBuilder sb) {
|
||||||
|
if (property == null) {
|
||||||
|
LOGGER.warn("CodegenProperty cannot be null");
|
||||||
|
} else if (property.isListContainer) {
|
||||||
|
sb.append("list(");
|
||||||
|
buildTypespec(property.items, sb);
|
||||||
|
sb.append(")");
|
||||||
|
} else if (property.isMapContainer) {
|
||||||
|
sb.append("%{optional(String.t) => ");
|
||||||
|
buildTypespec(property.items, sb);
|
||||||
|
sb.append("}");
|
||||||
|
} else if (property.isPrimitiveType) {
|
||||||
|
sb.append(property.baseType);
|
||||||
|
sb.append(".t");
|
||||||
|
} else {
|
||||||
|
sb.append(moduleName);
|
||||||
|
sb.append(".Model.");
|
||||||
|
sb.append(property.baseType);
|
||||||
|
sb.append(".t");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String decodedStruct() {
|
||||||
|
// Let Poison decode the entire response into a generic blob
|
||||||
|
if (isMapContainer) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// Primitive return type, don't even try to decode
|
||||||
|
if (returnBaseType == null || (returnSimpleType && returnTypeIsPrimitive)) {
|
||||||
|
return "false";
|
||||||
|
}
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
if (isListContainer) {
|
||||||
|
sb.append("[");
|
||||||
|
}
|
||||||
|
sb.append("%");
|
||||||
|
sb.append(moduleName);
|
||||||
|
sb.append(".Model.");
|
||||||
|
sb.append(returnBaseType);
|
||||||
|
sb.append("{}");
|
||||||
|
if (isListContainer) {
|
||||||
|
sb.append("]");
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExtendedCodegenModel extends CodegenModel {
|
||||||
|
public boolean hasImports;
|
||||||
|
|
||||||
|
public ExtendedCodegenModel(CodegenModel cm) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Copy all fields of CodegenModel
|
||||||
|
this.parent = cm.parent;
|
||||||
|
this.parentSchema = cm.parentSchema;
|
||||||
|
this.parentModel = cm.parentModel;
|
||||||
|
this.interfaceModels = cm.interfaceModels;
|
||||||
|
this.children = cm.children;
|
||||||
|
this.name = cm.name;
|
||||||
|
this.classname = cm.classname;
|
||||||
|
this.title = cm.title;
|
||||||
|
this.description = cm.description;
|
||||||
|
this.classVarName = cm.classVarName;
|
||||||
|
this.modelJson = cm.modelJson;
|
||||||
|
this.dataType = cm.dataType;
|
||||||
|
this.xmlPrefix = cm.xmlPrefix;
|
||||||
|
this.xmlNamespace = cm.xmlNamespace;
|
||||||
|
this.xmlName = cm.xmlName;
|
||||||
|
this.classFilename = cm.classFilename;
|
||||||
|
this.unescapedDescription = cm.unescapedDescription;
|
||||||
|
this.discriminator = cm.discriminator;
|
||||||
|
this.defaultValue = cm.defaultValue;
|
||||||
|
this.arrayModelType = cm.arrayModelType;
|
||||||
|
this.isAlias = cm.isAlias;
|
||||||
|
this.vars = cm.vars;
|
||||||
|
this.requiredVars = cm.requiredVars;
|
||||||
|
this.optionalVars = cm.optionalVars;
|
||||||
|
this.readOnlyVars = cm.readOnlyVars;
|
||||||
|
this.readWriteVars = cm.readWriteVars;
|
||||||
|
this.allVars = cm.allVars;
|
||||||
|
this.parentVars = cm.parentVars;
|
||||||
|
this.allowableValues = cm.allowableValues;
|
||||||
|
this.mandatory = cm.mandatory;
|
||||||
|
this.allMandatory = cm.allMandatory;
|
||||||
|
this.imports = cm.imports;
|
||||||
|
this.hasVars = cm.hasVars;
|
||||||
|
this.emptyVars = cm.emptyVars;
|
||||||
|
this.hasMoreModels = cm.hasMoreModels;
|
||||||
|
this.hasEnums = cm.hasEnums;
|
||||||
|
this.isEnum = cm.isEnum;
|
||||||
|
this.hasRequired = cm.hasRequired;
|
||||||
|
this.hasOptional = cm.hasOptional;
|
||||||
|
this.isArrayModel = cm.isArrayModel;
|
||||||
|
this.hasChildren = cm.hasChildren;
|
||||||
|
this.hasOnlyReadOnly = cm.hasOnlyReadOnly;
|
||||||
|
this.externalDocumentation = cm.externalDocumentation;
|
||||||
|
this.vendorExtensions = cm.vendorExtensions;
|
||||||
|
this.additionalPropertiesType = cm.additionalPropertiesType;
|
||||||
|
|
||||||
|
this.hasImports = !this.imports.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasComplexVars() {
|
||||||
|
for (CodegenProperty p : vars) {
|
||||||
|
if (!p.isPrimitiveType) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeQuotationMark(String input) {
|
||||||
|
return input.replace("\"", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeUnsafeCharacters(String input) {
|
||||||
|
// no need to escape as Elixir does not support multi-line comments
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModuleName(String moduleName) {
|
||||||
|
this.moduleName = moduleName;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,128 @@
|
|||||||
|
package org.openapitools.codegen.languages;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.*;
|
||||||
|
import io.swagger.models.properties.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
public class LumenServerCodegen extends AbstractPhpCodegen
|
||||||
|
{
|
||||||
|
@SuppressWarnings("hiding")
|
||||||
|
protected String apiVersion = "1.0.0";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the type of generator.
|
||||||
|
*
|
||||||
|
* @return the CodegenType for this generator
|
||||||
|
* @see org.openapitools.codegen.CodegenType
|
||||||
|
*/
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.SERVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures a friendly name for the generator. This will be used by the generator
|
||||||
|
* to select the library with the -l flag.
|
||||||
|
*
|
||||||
|
* @return the friendly name for the generator
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return "php-lumen";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns human-friendly help for the generator. Provide the consumer with help
|
||||||
|
* tips, parameters here
|
||||||
|
*
|
||||||
|
* @return A string value for the help message
|
||||||
|
*/
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates a PHP Lumen server library.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public LumenServerCodegen() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
embeddedTemplateDir = templateDir = "lumen";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* packPath
|
||||||
|
*/
|
||||||
|
invokerPackage = "lumen";
|
||||||
|
packagePath = "";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Api Package. Optional, if needed, this can be used in templates
|
||||||
|
*/
|
||||||
|
apiPackage = "app.Http.Controllers";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Model Package. Optional, if needed, this can be used in templates
|
||||||
|
*/
|
||||||
|
modelPackage = "models";
|
||||||
|
|
||||||
|
// template files want to be ignored
|
||||||
|
modelTemplateFiles.clear();
|
||||||
|
apiTestTemplateFiles.clear();
|
||||||
|
apiDocTemplateFiles.clear();
|
||||||
|
modelDocTemplateFiles.clear();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Additional Properties. These values can be passed to the templates and
|
||||||
|
* are available in models, apis, and supporting files
|
||||||
|
*/
|
||||||
|
additionalProperties.put("apiVersion", apiVersion);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Supporting Files. You can write single files for the generator with the
|
||||||
|
* entire object tree available. If the input file has a suffix of `.mustache
|
||||||
|
* it will be processed by the template engine. Otherwise, it will be copied
|
||||||
|
*/
|
||||||
|
supportingFiles.add(new SupportingFile("composer.mustache", packagePath + File.separator + srcBasePath, "composer.json"));
|
||||||
|
supportingFiles.add(new SupportingFile("readme.md", packagePath + File.separator + srcBasePath, "readme.md"));
|
||||||
|
supportingFiles.add(new SupportingFile("app.php", packagePath + File.separator + srcBasePath + File.separator + "bootstrap", "app.php"));
|
||||||
|
supportingFiles.add(new SupportingFile("index.php", packagePath + File.separator + srcBasePath + File.separator + "public", "index.php"));
|
||||||
|
supportingFiles.add(new SupportingFile("User.php", packagePath + File.separator + srcBasePath + File.separator + "app", "User.php"));
|
||||||
|
supportingFiles.add(new SupportingFile("Kernel.php", packagePath + File.separator + srcBasePath + File.separator + "app" + File.separator + "Console", "Kernel.php"));
|
||||||
|
supportingFiles.add(new SupportingFile("Handler.php", packagePath + File.separator + srcBasePath + File.separator + "app" + File.separator + "Exceptions", "Handler.php"));
|
||||||
|
supportingFiles.add(new SupportingFile("routes.mustache", packagePath + File.separator + srcBasePath + File.separator + "app" + File.separator + "Http", "routes.php"));
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("Controller.php", packagePath + File.separator + srcBasePath + File.separator + "app" + File.separator + "Http" + File.separator + "Controllers" + File.separator, "Controller.php"));
|
||||||
|
supportingFiles.add(new SupportingFile("Authenticate.php", packagePath + File.separator + srcBasePath + File.separator + "app" + File.separator + "Http" + File.separator + "Middleware" + File.separator, "Authenticate.php"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// override with any special post-processing
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Map<String, Object> objectMap = (Map<String, Object>) objs.get("operations");
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
|
||||||
|
|
||||||
|
for (CodegenOperation op : operations) {
|
||||||
|
op.httpMethod = op.httpMethod.toLowerCase();
|
||||||
|
// check to see if the path contains ".", which is not supported by Lumen
|
||||||
|
// ref: https://github.com/swagger-api/swagger-codegen/issues/6897
|
||||||
|
if (op.path != null && op.path.contains(".")) {
|
||||||
|
throw new IllegalArgumentException("'.' (dot) is not supported by PHP Lumen. Please refer to https://github.com/swagger-api/swagger-codegen/issues/6897 for more info.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort the endpoints in ascending to avoid the route priority issure.
|
||||||
|
// https://github.com/swagger-api/swagger-codegen/issues/2643
|
||||||
|
Collections.sort(operations, new Comparator<CodegenOperation>() {
|
||||||
|
@Override
|
||||||
|
public int compare(CodegenOperation lhs, CodegenOperation rhs) {
|
||||||
|
return lhs.path.compareTo(rhs.path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return objs;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,407 @@
|
|||||||
|
package org.openapitools.codegen.languages;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.*;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.Operation;
|
||||||
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static java.util.UUID.randomUUID;
|
||||||
|
|
||||||
|
public class PowerShellClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||||
|
static Logger LOGGER = LoggerFactory.getLogger(PowerShellClientCodegen.class);
|
||||||
|
|
||||||
|
private String packageGuid = "{" + randomUUID().toString().toUpperCase() + "}";
|
||||||
|
|
||||||
|
protected String sourceFolder = "src";
|
||||||
|
protected String packageName = "IO.Swagger";
|
||||||
|
protected String csharpClientPath = "$ScriptDir\\csharp\\SwaggerClient";
|
||||||
|
protected String apiDocPath = "docs/";
|
||||||
|
protected String modelDocPath = "docs/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance of `PowerShellClientCodegen`.
|
||||||
|
*/
|
||||||
|
public PowerShellClientCodegen() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
outputFolder = "generated-code" + File.separator + "powershell";
|
||||||
|
modelTemplateFiles.put("model.mustache", ".ps1");
|
||||||
|
apiTemplateFiles.put("api.mustache", ".ps1");
|
||||||
|
modelTestTemplateFiles.put("model_test.mustache", ".ps1");
|
||||||
|
apiTestTemplateFiles.put("api_test.mustache", ".ps1");
|
||||||
|
modelDocTemplateFiles.clear();
|
||||||
|
apiDocTemplateFiles.clear();
|
||||||
|
embeddedTemplateDir = templateDir = "powershell";
|
||||||
|
apiPackage = packageName + File.separator + "API";
|
||||||
|
modelPackage = packageName + File.separator + "Model";
|
||||||
|
|
||||||
|
// https://blogs.msdn.microsoft.com/powershell/2010/01/07/how-objects-are-sent-to-and-from-remote-sessions/
|
||||||
|
languageSpecificPrimitives = new HashSet<String>(Arrays.asList(
|
||||||
|
"Byte",
|
||||||
|
"SByte",
|
||||||
|
"Byte[]",
|
||||||
|
"Int16",
|
||||||
|
"Int32",
|
||||||
|
"Int64",
|
||||||
|
"UInt16",
|
||||||
|
"UInt32",
|
||||||
|
"UInt64",
|
||||||
|
"Decimal",
|
||||||
|
"Single",
|
||||||
|
"Double",
|
||||||
|
"TimeSpan",
|
||||||
|
"System.DateTime",
|
||||||
|
"ProgressRecord",
|
||||||
|
"Char",
|
||||||
|
"String",
|
||||||
|
"XmlDocument",
|
||||||
|
"SecureString",
|
||||||
|
"Boolean",
|
||||||
|
"Guid",
|
||||||
|
"Uri",
|
||||||
|
"Version"
|
||||||
|
));
|
||||||
|
|
||||||
|
// https://richardspowershellblog.wordpress.com/2009/05/02/powershell-reserved-words/
|
||||||
|
reservedWords = new HashSet<String>(Arrays.asList(
|
||||||
|
"Begin",
|
||||||
|
"Break",
|
||||||
|
"Catch",
|
||||||
|
"Continue",
|
||||||
|
"Data",
|
||||||
|
"Do",
|
||||||
|
"Dynamicparam",
|
||||||
|
"Else",
|
||||||
|
"Elseif",
|
||||||
|
"End",
|
||||||
|
"Exit",
|
||||||
|
"Filter",
|
||||||
|
"Finally",
|
||||||
|
"For",
|
||||||
|
"Foreach",
|
||||||
|
"From",
|
||||||
|
"Function",
|
||||||
|
"If",
|
||||||
|
"In",
|
||||||
|
"Param",
|
||||||
|
"Process",
|
||||||
|
"Return",
|
||||||
|
"Switch",
|
||||||
|
"Throw",
|
||||||
|
"Trap",
|
||||||
|
"Try",
|
||||||
|
"Until",
|
||||||
|
"While",
|
||||||
|
"Local",
|
||||||
|
"Private",
|
||||||
|
"Where"
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
defaultIncludes = new HashSet<String>(Arrays.asList(
|
||||||
|
"Byte",
|
||||||
|
"SByte",
|
||||||
|
"Byte[]",
|
||||||
|
"Int16",
|
||||||
|
"Int32",
|
||||||
|
"Int64",
|
||||||
|
"UInt16",
|
||||||
|
"UInt32",
|
||||||
|
"UInt64",
|
||||||
|
"Decimal",
|
||||||
|
"Single",
|
||||||
|
"Double",
|
||||||
|
"TimeSpan",
|
||||||
|
"System.DateTime",
|
||||||
|
"ProgressRecord",
|
||||||
|
"Char",
|
||||||
|
"String",
|
||||||
|
"XmlDocument",
|
||||||
|
"SecureString",
|
||||||
|
"Boolean",
|
||||||
|
"Guid",
|
||||||
|
"Uri",
|
||||||
|
"Version"
|
||||||
|
));
|
||||||
|
|
||||||
|
typeMapping = new HashMap<String, String>();
|
||||||
|
typeMapping.put("string", "String");
|
||||||
|
typeMapping.put("boolean", "Boolean");
|
||||||
|
typeMapping.put("integer", "Int32");
|
||||||
|
typeMapping.put("float", "Double");
|
||||||
|
typeMapping.put("long", "Int64");
|
||||||
|
typeMapping.put("double", "Double");
|
||||||
|
typeMapping.put("number", "Decimal");
|
||||||
|
typeMapping.put("date-time", "System.DateTime");
|
||||||
|
typeMapping.put("date", "System.DateTime");
|
||||||
|
typeMapping.put("file", "String");
|
||||||
|
typeMapping.put("object", "String");
|
||||||
|
typeMapping.put("binary", "String");
|
||||||
|
typeMapping.put("Date", "System.DateTime");
|
||||||
|
typeMapping.put("DateTime", "System.DateTime");
|
||||||
|
|
||||||
|
cliOptions.clear();
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Client package name (e.g. io.swagger.client).").defaultValue(this.packageName));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.OPTIONAL_PROJECT_GUID, "GUID for PowerShell module (e.g. a27b908d-2a20-467f-bc32-af6f3a654ac5). A random GUID will be generated by default."));
|
||||||
|
cliOptions.add(new CliOption("csharpClientPath", "Path to the C# API client generated by Swagger Codegen, e.g. $ScriptDir\\..\\csharp\\SwaggerClient where $ScriptDir is the current directory. NOTE: you will need to generate the C# API client separately.").defaultValue(this.csharpClientPath));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.CLIENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return "powershell";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates a PowerShell API client (beta). (The dependency C# API client needs to be generated separately.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPackageName(String packageName) {
|
||||||
|
this.packageName = packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCsharpClientPath(String csharpClientPath) {
|
||||||
|
this.csharpClientPath = csharpClientPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceFolder(String sourceFolder) {
|
||||||
|
this.sourceFolder = sourceFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPackageGuid(String packageGuid) {
|
||||||
|
this.packageGuid = packageGuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processOpts() {
|
||||||
|
super.processOpts();
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_PROJECT_GUID)) {
|
||||||
|
setPackageGuid((String) additionalProperties.get(CodegenConstants.OPTIONAL_PROJECT_GUID));
|
||||||
|
}
|
||||||
|
additionalProperties.put("packageGuid", packageGuid);
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
|
||||||
|
this.setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey("csharpClientPath")) {
|
||||||
|
this.setCsharpClientPath((String) additionalProperties.get("csharpClientPath"));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put("csharpClientPath", csharpClientPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
|
||||||
|
LOGGER.warn(CodegenConstants.MODEL_PACKAGE + " with " + this.getName() + " generator is ignored. Setting this value independently of " + CodegenConstants.PACKAGE_NAME + " is not currently supported.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
|
||||||
|
LOGGER.warn(CodegenConstants.API_PACKAGE + " with " + this.getName() + " generator is ignored. Setting this value independently of " + CodegenConstants.PACKAGE_NAME + " is not currently supported.");
|
||||||
|
}
|
||||||
|
|
||||||
|
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage());
|
||||||
|
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage());
|
||||||
|
|
||||||
|
additionalProperties.put("apiDocPath", apiDocPath);
|
||||||
|
additionalProperties.put("modelDocPath", modelDocPath);
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||||
|
supportingFiles.add(new SupportingFile("Build.ps1.mustache", "", "Build.ps1"));
|
||||||
|
|
||||||
|
final String infrastructureFolder = (sourceFolder + File.separator + packageName + File.separator);
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("IO.Swagger.psm1.mustache", infrastructureFolder, packageName + ".psm1"));
|
||||||
|
|
||||||
|
// private
|
||||||
|
supportingFiles.add(new SupportingFile("Get-CommonParameters.ps1", infrastructureFolder + File.separator + "Private" + File.separator, "Get-CommonParameters.ps1"));
|
||||||
|
supportingFiles.add(new SupportingFile("Out-DebugParameter.ps1", infrastructureFolder + File.separator + "Private" + File.separator, "Out-DebugParameter.ps1"));
|
||||||
|
|
||||||
|
// en-US
|
||||||
|
supportingFiles.add(new SupportingFile("about_IO.Swagger.help.txt.mustache", infrastructureFolder + File.separator + "en-US" + File.separator + "about_" + packageName + ".help.txt"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeUnsafeCharacters(String input) {
|
||||||
|
return input.replace("#>", "#_>").replace("<#", "<_#");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeQuotationMark(String input) {
|
||||||
|
// remove " to avoid code injection
|
||||||
|
return input.replace("\"", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiTestFileFolder() {
|
||||||
|
return (outputFolder + "/test").replace('/', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiDocFileFolder() {
|
||||||
|
return (outputFolder + "/" + apiDocPath).replace('/', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiFileFolder() {
|
||||||
|
return outputFolder + File.separator + sourceFolder + File.separator + apiPackage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelTestFileFolder() {
|
||||||
|
return (outputFolder + "/test").replace('/', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelDocFileFolder() {
|
||||||
|
return (outputFolder + "/" + modelDocPath).replace('/', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelFileFolder() {
|
||||||
|
return outputFolder + File.separator + sourceFolder + File.separator + modelPackage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeReservedWord(String name) {
|
||||||
|
return "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output the proper model name (capitalized).
|
||||||
|
* In case the name belongs to the TypeSystem it won't be renamed.
|
||||||
|
*
|
||||||
|
* @param name the name of the model
|
||||||
|
* @return capitalized model name
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toModelName(String name) {
|
||||||
|
if (!StringUtils.isEmpty(modelNamePrefix)) {
|
||||||
|
name = modelNamePrefix + "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(modelNameSuffix)) {
|
||||||
|
name = name + "_" + modelNameSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = sanitizeName(name);
|
||||||
|
|
||||||
|
// model name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + camelize("model_" + name));
|
||||||
|
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// model name starts with number
|
||||||
|
if (name.matches("^\\d.*")) {
|
||||||
|
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + camelize("model_" + name));
|
||||||
|
name = "model_" + name; // e.g. 200Response => Model200Response (after camelize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize the model name
|
||||||
|
// phone_number => PhoneNumber
|
||||||
|
return camelize(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelFilename(String name) {
|
||||||
|
// should be the same as the model name
|
||||||
|
return "New-" + toModelName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the swagger type for the property
|
||||||
|
*
|
||||||
|
* @param p Swagger property object
|
||||||
|
* @return string presentation of the type
|
||||||
|
**/
|
||||||
|
@Override
|
||||||
|
public String getSchemaType(Schema p) {
|
||||||
|
String openAPIType = super.getSchemaType(p);
|
||||||
|
String type;
|
||||||
|
|
||||||
|
// This maps, for example, long -> Long based on hashes in this type's constructor
|
||||||
|
if (typeMapping.containsKey(openAPIType)) {
|
||||||
|
type = typeMapping.get(openAPIType);
|
||||||
|
if (languageSpecificPrimitives.contains(type)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
type = openAPIType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// model/object
|
||||||
|
return toModelName(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output the type declaration of the property
|
||||||
|
*
|
||||||
|
* @param p OpenAPI Schema object
|
||||||
|
* @return a string presentation of the property type
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(Schema p) {
|
||||||
|
if (p instanceof ArraySchema) {
|
||||||
|
ArraySchema ap = (ArraySchema) p;
|
||||||
|
Schema inner = ap.getItems();
|
||||||
|
return getTypeDeclaration(inner) + "[]";
|
||||||
|
} else if (p instanceof MapSchema) {
|
||||||
|
MapSchema mp = (MapSchema) p;
|
||||||
|
Schema inner = (Schema) mp.getAdditionalProperties();
|
||||||
|
// TODO not sure if the following map/hash declaration is correct
|
||||||
|
return "{String, " + getTypeDeclaration(inner) + "}";
|
||||||
|
} else if (!languageSpecificPrimitives.contains(getSchemaType(p))) {
|
||||||
|
return packageName + ".Model." + super.getTypeDeclaration(p);
|
||||||
|
}
|
||||||
|
return super.getTypeDeclaration(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toOperationId(String operationId) {
|
||||||
|
// throw exception if method name is empty (should not occur as an auto-generated method name will be used)
|
||||||
|
if (StringUtils.isEmpty(operationId)) {
|
||||||
|
throw new RuntimeException("Empty method name (operationId) not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// method name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(operationId)) {
|
||||||
|
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + camelize(sanitizeName("call_" + operationId)));
|
||||||
|
operationId = "call_" + operationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return camelize(sanitizeName(operationId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||||
|
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||||
|
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
|
||||||
|
for (CodegenOperation op : operationList) {
|
||||||
|
int index = 0;
|
||||||
|
for (CodegenParameter p : op.allParams) {
|
||||||
|
p.vendorExtensions.put("x-index", index);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return objs;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,674 @@
|
|||||||
|
package org.openapitools.codegen.languages;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.CliOption;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
import org.openapitools.codegen.CodegenModel;
|
||||||
|
import org.openapitools.codegen.CodegenParameter;
|
||||||
|
import org.openapitools.codegen.CodegenProperty;
|
||||||
|
import org.openapitools.codegen.CodegenType;
|
||||||
|
import org.openapitools.codegen.DefaultCodegen;
|
||||||
|
import org.openapitools.codegen.SupportingFile;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.Operation;
|
||||||
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||||
|
|
||||||
|
public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||||
|
public static final String PACKAGE_URL = "packageUrl";
|
||||||
|
public static final String DEFAULT_LIBRARY = "urllib3";
|
||||||
|
|
||||||
|
protected String packageName; // e.g. petstore_api
|
||||||
|
protected String packageVersion;
|
||||||
|
protected String projectName; // for setup.py, e.g. petstore-api
|
||||||
|
protected String packageUrl;
|
||||||
|
protected String apiDocPath = "docs/";
|
||||||
|
protected String modelDocPath = "docs/";
|
||||||
|
|
||||||
|
protected Map<Character, String> regexModifiers;
|
||||||
|
|
||||||
|
private String testFolder;
|
||||||
|
|
||||||
|
public PythonClientCodegen() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// clear import mapping (from default generator) as python does not use it
|
||||||
|
// at the moment
|
||||||
|
importMapping.clear();
|
||||||
|
|
||||||
|
supportsInheritance = true;
|
||||||
|
modelPackage = "models";
|
||||||
|
apiPackage = "api";
|
||||||
|
outputFolder = "generated-code" + File.separatorChar + "python";
|
||||||
|
|
||||||
|
modelTemplateFiles.put("model.mustache", ".py");
|
||||||
|
apiTemplateFiles.put("api.mustache", ".py");
|
||||||
|
|
||||||
|
modelTestTemplateFiles.put("model_test.mustache", ".py");
|
||||||
|
apiTestTemplateFiles.put("api_test.mustache", ".py");
|
||||||
|
|
||||||
|
embeddedTemplateDir = templateDir = "python";
|
||||||
|
|
||||||
|
modelDocTemplateFiles.put("model_doc.mustache", ".md");
|
||||||
|
apiDocTemplateFiles.put("api_doc.mustache", ".md");
|
||||||
|
|
||||||
|
testFolder = "test";
|
||||||
|
|
||||||
|
languageSpecificPrimitives.clear();
|
||||||
|
languageSpecificPrimitives.add("int");
|
||||||
|
languageSpecificPrimitives.add("float");
|
||||||
|
languageSpecificPrimitives.add("list");
|
||||||
|
languageSpecificPrimitives.add("dict");
|
||||||
|
languageSpecificPrimitives.add("bool");
|
||||||
|
languageSpecificPrimitives.add("str");
|
||||||
|
languageSpecificPrimitives.add("datetime");
|
||||||
|
languageSpecificPrimitives.add("date");
|
||||||
|
languageSpecificPrimitives.add("object");
|
||||||
|
|
||||||
|
typeMapping.clear();
|
||||||
|
typeMapping.put("integer", "int");
|
||||||
|
typeMapping.put("float", "float");
|
||||||
|
typeMapping.put("number", "float");
|
||||||
|
typeMapping.put("long", "int");
|
||||||
|
typeMapping.put("double", "float");
|
||||||
|
typeMapping.put("array", "list");
|
||||||
|
typeMapping.put("map", "dict");
|
||||||
|
typeMapping.put("boolean", "bool");
|
||||||
|
typeMapping.put("string", "str");
|
||||||
|
typeMapping.put("date", "date");
|
||||||
|
typeMapping.put("DateTime", "datetime");
|
||||||
|
typeMapping.put("object", "object");
|
||||||
|
typeMapping.put("file", "file");
|
||||||
|
// TODO binary should be mapped to byte array
|
||||||
|
// mapped to String as a workaround
|
||||||
|
typeMapping.put("binary", "str");
|
||||||
|
typeMapping.put("ByteArray", "str");
|
||||||
|
// map uuid to string for the time being
|
||||||
|
typeMapping.put("UUID", "str");
|
||||||
|
|
||||||
|
// from https://docs.python.org/3/reference/lexical_analysis.html#keywords
|
||||||
|
setReservedWordsLowerCase(
|
||||||
|
Arrays.asList(
|
||||||
|
// local variable name used in API methods (endpoints)
|
||||||
|
"all_params", "resource_path", "path_params", "query_params",
|
||||||
|
"header_params", "form_params", "local_var_files", "body_params", "auth_settings",
|
||||||
|
// @property
|
||||||
|
"property",
|
||||||
|
// python reserved words
|
||||||
|
"and", "del", "from", "not", "while", "as", "elif", "global", "or", "with",
|
||||||
|
"assert", "else", "if", "pass", "yield", "break", "except", "import",
|
||||||
|
"print", "class", "exec", "in", "raise", "continue", "finally", "is",
|
||||||
|
"return", "def", "for", "lambda", "try", "self", "nonlocal", "None", "True", "False"));
|
||||||
|
|
||||||
|
regexModifiers = new HashMap<Character, String>();
|
||||||
|
regexModifiers.put('i', "IGNORECASE");
|
||||||
|
regexModifiers.put('l', "LOCALE");
|
||||||
|
regexModifiers.put('m', "MULTILINE");
|
||||||
|
regexModifiers.put('s', "DOTALL");
|
||||||
|
regexModifiers.put('u', "UNICODE");
|
||||||
|
regexModifiers.put('x', "VERBOSE");
|
||||||
|
|
||||||
|
cliOptions.clear();
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "python package name (convention: snake_case).")
|
||||||
|
.defaultValue("swagger_client"));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.PROJECT_NAME, "python project name in setup.py (e.g. petstore-api)."));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_VERSION, "python package version.")
|
||||||
|
.defaultValue("1.0.0"));
|
||||||
|
cliOptions.add(new CliOption(PACKAGE_URL, "python package URL."));
|
||||||
|
cliOptions.add(CliOption.newBoolean(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG,
|
||||||
|
CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC).defaultValue(Boolean.TRUE.toString()));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "hides the timestamp when files were generated")
|
||||||
|
.defaultValue(Boolean.TRUE.toString()));
|
||||||
|
|
||||||
|
supportedLibraries.put("urllib3", "urllib3-based client");
|
||||||
|
supportedLibraries.put("asyncio", "Asyncio-based client (python 3.5+)");
|
||||||
|
supportedLibraries.put("tornado", "tornado-based client");
|
||||||
|
CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use");
|
||||||
|
libraryOption.setDefault(DEFAULT_LIBRARY);
|
||||||
|
cliOptions.add(libraryOption);
|
||||||
|
setLibrary(DEFAULT_LIBRARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processOpts() {
|
||||||
|
super.processOpts();
|
||||||
|
Boolean excludeTests = false;
|
||||||
|
|
||||||
|
if(additionalProperties.containsKey(CodegenConstants.EXCLUDE_TESTS)) {
|
||||||
|
excludeTests = Boolean.valueOf(additionalProperties.get(CodegenConstants.EXCLUDE_TESTS).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
|
||||||
|
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setPackageName("swagger_client");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.PROJECT_NAME)) {
|
||||||
|
setProjectName((String) additionalProperties.get(CodegenConstants.PROJECT_NAME));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// default: set project based on package name
|
||||||
|
// e.g. petstore_api (package name) => petstore-api (project name)
|
||||||
|
setProjectName(packageName.replaceAll("_", "-"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
|
||||||
|
setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setPackageVersion("1.0.0");
|
||||||
|
}
|
||||||
|
|
||||||
|
// default HIDE_GENERATION_TIMESTAMP to true
|
||||||
|
if (!additionalProperties.containsKey(CodegenConstants.HIDE_GENERATION_TIMESTAMP)) {
|
||||||
|
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, Boolean.TRUE.toString());
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP,
|
||||||
|
Boolean.valueOf(additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP).toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
additionalProperties.put(CodegenConstants.PROJECT_NAME, projectName);
|
||||||
|
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
|
||||||
|
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
|
||||||
|
|
||||||
|
// make api and model doc path available in mustache template
|
||||||
|
additionalProperties.put("apiDocPath", apiDocPath);
|
||||||
|
additionalProperties.put("modelDocPath", modelDocPath);
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(PACKAGE_URL)) {
|
||||||
|
setPackageUrl((String) additionalProperties.get(PACKAGE_URL));
|
||||||
|
}
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("tox.mustache", "", "tox.ini"));
|
||||||
|
supportingFiles.add(new SupportingFile("test-requirements.mustache", "", "test-requirements.txt"));
|
||||||
|
supportingFiles.add(new SupportingFile("requirements.mustache", "", "requirements.txt"));
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("configuration.mustache", packageName, "configuration.py"));
|
||||||
|
supportingFiles.add(new SupportingFile("__init__package.mustache", packageName, "__init__.py"));
|
||||||
|
supportingFiles.add(new SupportingFile("__init__model.mustache", packageName + File.separatorChar + modelPackage, "__init__.py"));
|
||||||
|
supportingFiles.add(new SupportingFile("__init__api.mustache", packageName + File.separatorChar + apiPackage, "__init__.py"));
|
||||||
|
|
||||||
|
if(Boolean.FALSE.equals(excludeTests)) {
|
||||||
|
supportingFiles.add(new SupportingFile("__init__test.mustache", testFolder, "__init__.py"));
|
||||||
|
}
|
||||||
|
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
|
||||||
|
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
|
||||||
|
supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml"));
|
||||||
|
supportingFiles.add(new SupportingFile("setup.mustache", "", "setup.py"));
|
||||||
|
supportingFiles.add(new SupportingFile("api_client.mustache", packageName, "api_client.py"));
|
||||||
|
|
||||||
|
if ("asyncio".equals(getLibrary())) {
|
||||||
|
supportingFiles.add(new SupportingFile("asyncio/rest.mustache", packageName, "rest.py"));
|
||||||
|
additionalProperties.put("asyncio", "true");
|
||||||
|
} else if ("tornado".equals(getLibrary())) {
|
||||||
|
supportingFiles.add(new SupportingFile("tornado/rest.mustache", packageName, "rest.py"));
|
||||||
|
additionalProperties.put("tornado", "true");
|
||||||
|
} else {
|
||||||
|
supportingFiles.add(new SupportingFile("rest.mustache", packageName, "rest.py"));
|
||||||
|
}
|
||||||
|
|
||||||
|
modelPackage = packageName + "." + modelPackage;
|
||||||
|
apiPackage = packageName + "." + apiPackage;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String dropDots(String str) {
|
||||||
|
return str.replaceAll("\\.", "_");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelImport(String name) {
|
||||||
|
String modelImport;
|
||||||
|
if (StringUtils.startsWithAny(name,"import", "from")) {
|
||||||
|
modelImport = name;
|
||||||
|
} else {
|
||||||
|
modelImport = "from ";
|
||||||
|
if (!"".equals(modelPackage())) {
|
||||||
|
modelImport += modelPackage() + ".";
|
||||||
|
}
|
||||||
|
modelImport += toModelFilename(name)+ " import " + name;
|
||||||
|
}
|
||||||
|
return modelImport;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||||
|
// process enum in models
|
||||||
|
return postProcessModelsEnum(objs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcessParameter(CodegenParameter parameter){
|
||||||
|
postProcessPattern(parameter.pattern, parameter.vendorExtensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
|
||||||
|
postProcessPattern(property.pattern, property.vendorExtensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The swagger pattern spec follows the Perl convention and style of modifiers. Python
|
||||||
|
* does not support this in as natural a way so it needs to convert it. See
|
||||||
|
* https://docs.python.org/2/howto/regex.html#compilation-flags for details.
|
||||||
|
*/
|
||||||
|
public void postProcessPattern(String pattern, Map<String, Object> vendorExtensions){
|
||||||
|
if(pattern != null) {
|
||||||
|
int i = pattern.lastIndexOf('/');
|
||||||
|
|
||||||
|
//Must follow Perl /pattern/modifiers convention
|
||||||
|
if(pattern.charAt(0) != '/' || i < 2) {
|
||||||
|
throw new IllegalArgumentException("Pattern must follow the Perl "
|
||||||
|
+ "/pattern/modifiers convention. "+pattern+" is not valid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
String regex = pattern.substring(1, i).replace("'", "\\'");
|
||||||
|
List<String> modifiers = new ArrayList<String>();
|
||||||
|
|
||||||
|
for(char c : pattern.substring(i).toCharArray()) {
|
||||||
|
if(regexModifiers.containsKey(c)) {
|
||||||
|
String modifier = regexModifiers.get(c);
|
||||||
|
modifiers.add(modifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vendorExtensions.put("x-regex", regex);
|
||||||
|
vendorExtensions.put("x-modifiers", modifiers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.CLIENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "python";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates a Python client library.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeReservedWord(String name) {
|
||||||
|
if(this.reservedWordsMappings().containsKey(name)) {
|
||||||
|
return this.reservedWordsMappings().get(name);
|
||||||
|
}
|
||||||
|
return "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiDocFileFolder() {
|
||||||
|
return (outputFolder + "/" + apiDocPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelDocFileFolder() {
|
||||||
|
return (outputFolder + "/" + modelDocPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelDocFilename(String name) {
|
||||||
|
return toModelName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiDocFilename(String name) {
|
||||||
|
return toApiName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiFileFolder() {
|
||||||
|
return outputFolder + File.separatorChar + apiPackage().replace('.', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelFileFolder() {
|
||||||
|
return outputFolder + File.separatorChar + modelPackage().replace('.', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiTestFileFolder() {
|
||||||
|
return outputFolder + File.separatorChar + testFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelTestFileFolder() {
|
||||||
|
return outputFolder + File.separatorChar + testFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(Schema p) {
|
||||||
|
if (p instanceof ArraySchema) {
|
||||||
|
ArraySchema ap = (ArraySchema) p;
|
||||||
|
Schema inner = ap.getItems();
|
||||||
|
return getSchemaType(p) + "[" + getTypeDeclaration(inner) + "]";
|
||||||
|
} else if (p instanceof MapSchema) {
|
||||||
|
MapSchema mp = (MapSchema) p;
|
||||||
|
Schema inner = (Schema) mp.getAdditionalProperties();
|
||||||
|
|
||||||
|
return getSchemaType(p) + "(str, " + getTypeDeclaration(inner) + ")";
|
||||||
|
}
|
||||||
|
return super.getTypeDeclaration(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSchemaType(Schema p) {
|
||||||
|
String swaggerType = super.getSchemaType(p);
|
||||||
|
String type = null;
|
||||||
|
if (typeMapping.containsKey(swaggerType)) {
|
||||||
|
type = typeMapping.get(swaggerType);
|
||||||
|
if (languageSpecificPrimitives.contains(type)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
type = toModelName(swaggerType);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toVarName(String name) {
|
||||||
|
// sanitize name
|
||||||
|
name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
|
||||||
|
// remove dollar sign
|
||||||
|
name = name.replaceAll("$", "");
|
||||||
|
|
||||||
|
// if it's all uppper case, convert to lower case
|
||||||
|
if (name.matches("^[A-Z_]*$")) {
|
||||||
|
name = name.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
// underscore the variable name
|
||||||
|
// petId => pet_id
|
||||||
|
name = underscore(name);
|
||||||
|
|
||||||
|
// remove leading underscore
|
||||||
|
name = name.replaceAll("^_*", "");
|
||||||
|
|
||||||
|
// for reserved word or word starting with number, append _
|
||||||
|
if (isReservedWord(name) || name.matches("^\\d.*")) {
|
||||||
|
name = escapeReservedWord(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toParamName(String name) {
|
||||||
|
// to avoid conflicts with 'callback' parameter for async call
|
||||||
|
if ("callback".equals(name)) {
|
||||||
|
return "param_callback";
|
||||||
|
}
|
||||||
|
|
||||||
|
// should be the same as variable name
|
||||||
|
return toVarName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelName(String name) {
|
||||||
|
name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
// remove dollar sign
|
||||||
|
name = name.replaceAll("$", "");
|
||||||
|
|
||||||
|
// model name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + camelize("model_" + name));
|
||||||
|
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// model name starts with number
|
||||||
|
if (name.matches("^\\d.*")) {
|
||||||
|
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + camelize("model_" + name));
|
||||||
|
name = "model_" + name; // e.g. 200Response => Model200Response (after camelize)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(modelNamePrefix)) {
|
||||||
|
name = modelNamePrefix + "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(modelNameSuffix)) {
|
||||||
|
name = name + "_" + modelNameSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize the model name
|
||||||
|
// phone_number => PhoneNumber
|
||||||
|
return camelize(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelFilename(String name) {
|
||||||
|
// underscore the model file name
|
||||||
|
// PhoneNumber => phone_number
|
||||||
|
return underscore(dropDots(toModelName(name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelTestFilename(String name) {
|
||||||
|
return "test_" + toModelFilename(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiFilename(String name) {
|
||||||
|
// replace - with _ e.g. created-at => created_at
|
||||||
|
name = name.replaceAll("-", "_");
|
||||||
|
|
||||||
|
// e.g. PhoneNumberApi.py => phone_number_api.py
|
||||||
|
return underscore(name) + "_api";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiTestFilename(String name) {
|
||||||
|
return "test_" + toApiFilename(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiName(String name) {
|
||||||
|
if (name.length() == 0) {
|
||||||
|
return "DefaultApi";
|
||||||
|
}
|
||||||
|
// e.g. phone_number_api => PhoneNumberApi
|
||||||
|
return camelize(name) + "Api";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiVarName(String name) {
|
||||||
|
if (name.length() == 0) {
|
||||||
|
return "default_api";
|
||||||
|
}
|
||||||
|
return underscore(name) + "_api";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toOperationId(String operationId) {
|
||||||
|
// throw exception if method name is empty (should not occur as an auto-generated method name will be used)
|
||||||
|
if (StringUtils.isEmpty(operationId)) {
|
||||||
|
throw new RuntimeException("Empty method name (operationId) not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// method name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(operationId)) {
|
||||||
|
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + underscore(sanitizeName("call_" + operationId)));
|
||||||
|
operationId = "call_" + operationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return underscore(sanitizeName(operationId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPackageName(String packageName) {
|
||||||
|
this.packageName = packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProjectName(String projectName) {
|
||||||
|
this.projectName= projectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPackageVersion(String packageVersion) {
|
||||||
|
this.packageVersion = packageVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPackageUrl(String packageUrl) {
|
||||||
|
this.packageUrl = packageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate Python package name from String `packageName`
|
||||||
|
*
|
||||||
|
* (PEP 0008) Python packages should also have short, all-lowercase names,
|
||||||
|
* although the use of underscores is discouraged.
|
||||||
|
*
|
||||||
|
* @param packageName Package name
|
||||||
|
* @return Python package name that conforms to PEP 0008
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("static-method")
|
||||||
|
public String generatePackageName(String packageName) {
|
||||||
|
return underscore(packageName.replaceAll("[^\\w]+", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the default value of the property
|
||||||
|
*
|
||||||
|
* @param p Swagger property object
|
||||||
|
* @return string presentation of the default value of the property
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toDefaultValue(Schema p) {
|
||||||
|
if (p instanceof StringSchema) {
|
||||||
|
StringSchema dp = (StringSchema) p;
|
||||||
|
if (dp.getDefault() != null) {
|
||||||
|
if (Pattern.compile("\r\n|\r|\n").matcher(dp.getDefault()).find())
|
||||||
|
return "'''" + dp.getDefault() + "'''";
|
||||||
|
else
|
||||||
|
return "'" + dp.getDefault() + "'";
|
||||||
|
}
|
||||||
|
} else if (p instanceof BooleanSchema) {
|
||||||
|
BooleanSchema dp = (BooleanSchema) p;
|
||||||
|
if (dp.getDefault() != null) {
|
||||||
|
if (dp.getDefault().toString().equalsIgnoreCase("false"))
|
||||||
|
return "False";
|
||||||
|
else
|
||||||
|
return "True";
|
||||||
|
}
|
||||||
|
} else if (p instanceof DateSchema) {
|
||||||
|
// TODO
|
||||||
|
} else if (p instanceof DateTimeSchema) {
|
||||||
|
// TODO
|
||||||
|
} else if (p instanceof NumberSchema) {
|
||||||
|
NumberSchema dp = (NumberSchema) p;
|
||||||
|
if (dp.getDefault() != null) {
|
||||||
|
return dp.getDefault().toString();
|
||||||
|
}
|
||||||
|
} else if (p instanceof IntegerSchema) {
|
||||||
|
IntegerSchema dp = (IntegerSchema) p;
|
||||||
|
if (dp.getDefault() != null) {
|
||||||
|
return dp.getDefault().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setParameterExampleValue(CodegenParameter p) {
|
||||||
|
String example;
|
||||||
|
|
||||||
|
if (p.defaultValue == null) {
|
||||||
|
example = p.example;
|
||||||
|
} else {
|
||||||
|
example = p.defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String type = p.baseType;
|
||||||
|
if (type == null) {
|
||||||
|
type = p.dataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("String".equalsIgnoreCase(type) || "str".equalsIgnoreCase(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = p.paramName + "_example";
|
||||||
|
}
|
||||||
|
example = "'" + escapeText(example) + "'";
|
||||||
|
} else if ("Integer".equals(type) || "int".equals(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "56";
|
||||||
|
}
|
||||||
|
} else if ("Float".equalsIgnoreCase(type) || "Double".equalsIgnoreCase(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "3.4";
|
||||||
|
}
|
||||||
|
} else if ("BOOLEAN".equalsIgnoreCase(type) || "bool".equalsIgnoreCase(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "True";
|
||||||
|
}
|
||||||
|
} else if ("file".equalsIgnoreCase(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "/path/to/file";
|
||||||
|
}
|
||||||
|
example = "'" + escapeText(example) + "'";
|
||||||
|
} else if ("Date".equalsIgnoreCase(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "2013-10-20";
|
||||||
|
}
|
||||||
|
example = "'" + escapeText(example) + "'";
|
||||||
|
} else if ("DateTime".equalsIgnoreCase(type)) {
|
||||||
|
if (example == null) {
|
||||||
|
example = "2013-10-20T19:20:30+01:00";
|
||||||
|
}
|
||||||
|
example = "'" + escapeText(example) + "'";
|
||||||
|
} else if (!languageSpecificPrimitives.contains(type)) {
|
||||||
|
// type is a model class, e.g. User
|
||||||
|
example = this.packageName + "." + type + "()";
|
||||||
|
} else {
|
||||||
|
LOGGER.warn("Type " + type + " not handled properly in setParameterExampleValue");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (example == null) {
|
||||||
|
example = "NULL";
|
||||||
|
} else if (Boolean.TRUE.equals(p.isListContainer)) {
|
||||||
|
example = "[" + example + "]";
|
||||||
|
} else if (Boolean.TRUE.equals(p.isMapContainer)) {
|
||||||
|
example = "{'key': " + example + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
p.example = example;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sanitizeTag(String tag) {
|
||||||
|
return sanitizeName(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeQuotationMark(String input) {
|
||||||
|
// remove ' to avoid code injection
|
||||||
|
return input.replace("'", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeUnsafeCharacters(String input) {
|
||||||
|
// remove multiline comment
|
||||||
|
return input.replace("'''", "'_'_'");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,453 @@
|
|||||||
|
package org.openapitools.codegen.languages;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.*;
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.Operation;
|
||||||
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class RClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||||
|
static Logger LOGGER = LoggerFactory.getLogger(RClientCodegen.class);
|
||||||
|
|
||||||
|
protected String packageName = "swagger";
|
||||||
|
protected String packageVersion = "1.0.0";
|
||||||
|
protected String apiDocPath = "docs/";
|
||||||
|
protected String modelDocPath = "docs/";
|
||||||
|
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.CLIENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return "r";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates a R client library (beta).";
|
||||||
|
}
|
||||||
|
|
||||||
|
public RClientCodegen() {
|
||||||
|
super();
|
||||||
|
outputFolder = "generated-code/r";
|
||||||
|
modelTemplateFiles.put("model.mustache", ".r");
|
||||||
|
apiTemplateFiles.put("api.mustache", ".r");
|
||||||
|
|
||||||
|
modelDocTemplateFiles.put("model_doc.mustache", ".md");
|
||||||
|
apiDocTemplateFiles.put("api_doc.mustache", ".md");
|
||||||
|
|
||||||
|
embeddedTemplateDir = templateDir = "r";
|
||||||
|
|
||||||
|
setReservedWordsLowerCase(
|
||||||
|
Arrays.asList(
|
||||||
|
// reserved words: https://stat.ethz.ch/R-manual/R-devel/library/base/html/Reserved.html
|
||||||
|
"if", "else", "repeat", "while", "function", "for", "in",
|
||||||
|
"next", "break", "TRUE", "FALSE", "NULL", "Inf", "NaN",
|
||||||
|
"NA", "NA_integer_", "NA_real_", "NA_complex_", "NA_character_"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
defaultIncludes = new HashSet<String>(
|
||||||
|
Arrays.asList(
|
||||||
|
"map",
|
||||||
|
"array")
|
||||||
|
);
|
||||||
|
|
||||||
|
languageSpecificPrimitives = new HashSet<String>(
|
||||||
|
Arrays.asList(
|
||||||
|
"Integer",
|
||||||
|
"Numeric",
|
||||||
|
"Character")
|
||||||
|
);
|
||||||
|
|
||||||
|
instantiationTypes.clear();
|
||||||
|
|
||||||
|
typeMapping.clear();
|
||||||
|
typeMapping.put("integer", "Integer");
|
||||||
|
typeMapping.put("long", "Integer");
|
||||||
|
typeMapping.put("number", "Numeric");
|
||||||
|
typeMapping.put("float", "Numeric");
|
||||||
|
typeMapping.put("double", "Numeric");
|
||||||
|
typeMapping.put("boolean", "Character");
|
||||||
|
typeMapping.put("string", "Character");
|
||||||
|
typeMapping.put("UUID", "Character");
|
||||||
|
typeMapping.put("date", "Character");
|
||||||
|
typeMapping.put("DateTime", "Character");
|
||||||
|
typeMapping.put("password", "Character");
|
||||||
|
typeMapping.put("file", "TODO_FILE_MAPPING");
|
||||||
|
// map binary to string as a workaround
|
||||||
|
// the correct solution is to use []byte
|
||||||
|
typeMapping.put("binary", "Character");
|
||||||
|
typeMapping.put("ByteArray", "Character");
|
||||||
|
typeMapping.put("object", "TODO_OBJECT_MAPPING");
|
||||||
|
|
||||||
|
cliOptions.clear();
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "R package name (convention: lowercase).")
|
||||||
|
.defaultValue("swagger"));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_VERSION, "R package version.")
|
||||||
|
.defaultValue("1.0.0"));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "hides the timestamp when files were generated")
|
||||||
|
.defaultValue(Boolean.TRUE.toString()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processOpts() {
|
||||||
|
super.processOpts();
|
||||||
|
|
||||||
|
// default HIDE_GENERATION_TIMESTAMP to true
|
||||||
|
if (!additionalProperties.containsKey(CodegenConstants.HIDE_GENERATION_TIMESTAMP)) {
|
||||||
|
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, Boolean.TRUE.toString());
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP,
|
||||||
|
Boolean.valueOf(additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP).toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
|
||||||
|
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
|
||||||
|
} else {
|
||||||
|
setPackageName("swagger");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
|
||||||
|
setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
|
||||||
|
} else {
|
||||||
|
setPackageVersion("1.0.0");
|
||||||
|
}
|
||||||
|
|
||||||
|
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
|
||||||
|
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
|
||||||
|
|
||||||
|
additionalProperties.put("apiDocPath", apiDocPath);
|
||||||
|
additionalProperties.put("modelDocPath", modelDocPath);
|
||||||
|
|
||||||
|
apiTestTemplateFiles.clear(); // TODO: add api test template
|
||||||
|
modelTestTemplateFiles.clear(); // TODO: add model test template
|
||||||
|
|
||||||
|
apiDocTemplateFiles.clear(); // TODO: add api doc template
|
||||||
|
modelDocTemplateFiles.clear(); // TODO: add model doc template
|
||||||
|
|
||||||
|
modelPackage = packageName;
|
||||||
|
apiPackage = packageName;
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||||
|
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
|
||||||
|
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
|
||||||
|
supportingFiles.add(new SupportingFile("description.mustache", "", "DESCRIPTION"));
|
||||||
|
supportingFiles.add(new SupportingFile("Rbuildignore.mustache", "", ".Rbuildignore"));
|
||||||
|
supportingFiles.add(new SupportingFile(".travis.yml", "", ".travis.yml"));
|
||||||
|
supportingFiles.add(new SupportingFile("response.mustache", "/R", "Response.r"));
|
||||||
|
supportingFiles.add(new SupportingFile("element.mustache", "/R", "Element.r"));
|
||||||
|
supportingFiles.add(new SupportingFile("api_client.mustache", "/R", "ApiClient.r"));
|
||||||
|
supportingFiles.add(new SupportingFile("NAMESPACE.mustache", "", "NAMESPACE"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeReservedWord(String name)
|
||||||
|
{
|
||||||
|
// Can't start with an underscore, as our fields need to start with an
|
||||||
|
// UppercaseLetter so that R treats them as public/visible.
|
||||||
|
|
||||||
|
// Options?
|
||||||
|
// - MyName
|
||||||
|
// - AName
|
||||||
|
// - TheName
|
||||||
|
// - XName
|
||||||
|
// - X_Name
|
||||||
|
// ... or maybe a suffix?
|
||||||
|
// - Name_ ... think this will work.
|
||||||
|
if(this.reservedWordsMappings().containsKey(name)) {
|
||||||
|
return this.reservedWordsMappings().get(name);
|
||||||
|
}
|
||||||
|
return camelize(name) + '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiFileFolder() {
|
||||||
|
return outputFolder + File.separator + "R" + File.separator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String modelFileFolder() {
|
||||||
|
return outputFolder + File.separator + "R" + File.separator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toVarName(String name) {
|
||||||
|
// replace - with _ e.g. created-at => created_at
|
||||||
|
name = sanitizeName(name.replaceAll("-", "_"));
|
||||||
|
|
||||||
|
// if it's all uppper case, do nothing
|
||||||
|
if (name.matches("^[A-Z_]*$"))
|
||||||
|
return name;
|
||||||
|
|
||||||
|
// convert variable name to snake case
|
||||||
|
// PetId => pet_id
|
||||||
|
name = underscore(name);
|
||||||
|
|
||||||
|
// for reserved word or word starting with number, append _
|
||||||
|
if (isReservedWord(name))
|
||||||
|
name = escapeReservedWord(name);
|
||||||
|
|
||||||
|
// for reserved word or word starting with number, append _
|
||||||
|
if (name.matches("^\\d.*"))
|
||||||
|
name = "Var" + name;
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toParamName(String name) {
|
||||||
|
return toVarName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelName(String name) {
|
||||||
|
return toModelFilename(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelFilename(String name) {
|
||||||
|
if (!StringUtils.isEmpty(modelNamePrefix)) {
|
||||||
|
name = modelNamePrefix + "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(modelNameSuffix)) {
|
||||||
|
name = name + "_" + modelNameSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = sanitizeName(name);
|
||||||
|
|
||||||
|
// model name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + camelize("model_" + name));
|
||||||
|
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// model name starts with number
|
||||||
|
if (name.matches("^\\d.*")) {
|
||||||
|
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + camelize("model_" + name));
|
||||||
|
name = "model_" + name; // e.g. 200Response => Model200Response (after camelize)
|
||||||
|
}
|
||||||
|
|
||||||
|
return camelize(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiFilename(String name) {
|
||||||
|
// replace - with _ e.g. created-at => created_at
|
||||||
|
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
|
||||||
|
// e.g. PetApi.r => pet_api.r
|
||||||
|
return camelize(name + "_api");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiDocFileFolder() {
|
||||||
|
return (outputFolder + "/" + apiDocPath).replace('/', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelDocFileFolder() {
|
||||||
|
return (outputFolder + "/" + modelDocPath).replace('/', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelDocFilename(String name) {
|
||||||
|
return toModelName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiDocFilename(String name) {
|
||||||
|
return toApiName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiName(String name) {
|
||||||
|
return camelize(super.toApiName(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(Schema p) {
|
||||||
|
if(p instanceof ArraySchema) {
|
||||||
|
ArraySchema ap = (ArraySchema) p;
|
||||||
|
Schema inner = ap.getItems();
|
||||||
|
return getTypeDeclaration(inner);
|
||||||
|
} else if (p instanceof MapSchema) {
|
||||||
|
MapSchema mp = (MapSchema) p;
|
||||||
|
Schema inner = (Schema) mp.getAdditionalProperties();
|
||||||
|
return getTypeDeclaration(inner);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not using the supertype invocation, because we want to UpperCamelize
|
||||||
|
// the type.
|
||||||
|
String openAPIType = getSchemaType(p);
|
||||||
|
if (typeMapping.containsKey(openAPIType)) {
|
||||||
|
return typeMapping.get(openAPIType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeMapping.containsValue(openAPIType)) {
|
||||||
|
return openAPIType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (languageSpecificPrimitives.contains(openAPIType)) {
|
||||||
|
return openAPIType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return toModelName(openAPIType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSchemaType(Schema p) {
|
||||||
|
String openAPIType = super.getSchemaType(p);
|
||||||
|
String type = null;
|
||||||
|
if (typeMapping.containsKey(openAPIType)) {
|
||||||
|
type = typeMapping.get(openAPIType);
|
||||||
|
if (languageSpecificPrimitives.contains(type))
|
||||||
|
return (type);
|
||||||
|
} else {
|
||||||
|
type = openAPIType;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toOperationId(String operationId) {
|
||||||
|
String sanitizedOperationId = sanitizeName(operationId);
|
||||||
|
|
||||||
|
// method name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(sanitizedOperationId)) {
|
||||||
|
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + underscore("call_" + operationId));
|
||||||
|
sanitizedOperationId = "call_" + sanitizedOperationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return underscore(sanitizedOperationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||||
|
// remove model imports to avoid error
|
||||||
|
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports");
|
||||||
|
final String prefix = modelPackage();
|
||||||
|
Iterator<Map<String, String>> iterator = imports.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
String _import = iterator.next().get("import");
|
||||||
|
if (_import.startsWith(prefix))
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// recursively add import for mapping one type to multiple imports
|
||||||
|
List<Map<String, String>> recursiveImports = (List<Map<String, String>>) objs.get("imports");
|
||||||
|
if (recursiveImports == null)
|
||||||
|
return objs;
|
||||||
|
|
||||||
|
ListIterator<Map<String, String>> listIterator = imports.listIterator();
|
||||||
|
while (listIterator.hasNext()) {
|
||||||
|
String _import = listIterator.next().get("import");
|
||||||
|
// if the import package happens to be found in the importMapping (key)
|
||||||
|
// add the corresponding import package to the list
|
||||||
|
if (importMapping.containsKey(_import)) {
|
||||||
|
listIterator.add(createMapping("import", importMapping.get(_import)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return postProcessModelsEnum(objs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needToImport(String type) {
|
||||||
|
return !defaultIncludes.contains(type)
|
||||||
|
&& !languageSpecificPrimitives.contains(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPackageName(String packageName) {
|
||||||
|
this.packageName = packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPackageVersion(String packageVersion) {
|
||||||
|
this.packageVersion = packageVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeQuotationMark(String input) {
|
||||||
|
// remove " to avoid code injection
|
||||||
|
return input.replace("\"", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeUnsafeCharacters(String input) {
|
||||||
|
return input.replace("]]", "] ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> createMapping(String key, String value){
|
||||||
|
Map<String, String> customImport = new HashMap<String, String>();
|
||||||
|
customImport.put(key, value);
|
||||||
|
|
||||||
|
return customImport;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toEnumValue(String value, String datatype) {
|
||||||
|
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return escapeText(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toEnumDefaultValue(String value, String datatype) {
|
||||||
|
return datatype + "_" + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toEnumVarName(String name, String datatype) {
|
||||||
|
if (name.length() == 0) {
|
||||||
|
return "EMPTY";
|
||||||
|
}
|
||||||
|
|
||||||
|
// number
|
||||||
|
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
|
||||||
|
String varName = name;
|
||||||
|
varName = varName.replaceAll("-", "MINUS_");
|
||||||
|
varName = varName.replaceAll("\\+", "PLUS_");
|
||||||
|
varName = varName.replaceAll("\\.", "_DOT_");
|
||||||
|
return varName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for symbol, e.g. $, #
|
||||||
|
if (getSymbolName(name) != null) {
|
||||||
|
return getSymbolName(name).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
// string
|
||||||
|
String enumName = sanitizeName(underscore(name).toUpperCase());
|
||||||
|
enumName = enumName.replaceFirst("^_", "");
|
||||||
|
enumName = enumName.replaceFirst("_$", "");
|
||||||
|
|
||||||
|
if (isReservedWord(enumName) || enumName.matches("\\d.*")) { // reserved word or starts with number
|
||||||
|
return escapeReservedWord(enumName);
|
||||||
|
} else {
|
||||||
|
return enumName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toEnumName(CodegenProperty property) {
|
||||||
|
String enumName = underscore(toModelName(property.name)).toUpperCase();
|
||||||
|
|
||||||
|
// remove [] for array or map of enum
|
||||||
|
enumName = enumName.replace("[]", "");
|
||||||
|
|
||||||
|
if (enumName.matches("\\d.*")) { // starts with number
|
||||||
|
return "_" + enumName;
|
||||||
|
} else {
|
||||||
|
return enumName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,339 @@
|
|||||||
|
package org.openapitools.codegen.languages;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.CodegenType;
|
||||||
|
import org.openapitools.codegen.DefaultCodegen;
|
||||||
|
import org.openapitools.codegen.SupportingFile;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.Operation;
|
||||||
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
import io.swagger.v3.core.util.Yaml;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class Rails5ServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(Rails5ServerCodegen.class);
|
||||||
|
private static final SimpleDateFormat MIGRATE_FILE_NAME_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||||
|
|
||||||
|
protected String gemName;
|
||||||
|
protected String moduleName;
|
||||||
|
protected String gemVersion = "1.0.0";
|
||||||
|
protected String appFolder = "app";
|
||||||
|
protected String channelsFolder = appFolder + File.separator + "channels";
|
||||||
|
protected String applicationCableFolder = channelsFolder + File.separator + "application_cable";
|
||||||
|
protected String controllersFolder = appFolder + File.separator + "controllers";
|
||||||
|
protected String jobsFolder = appFolder + File.separator + "jobs";
|
||||||
|
protected String mailersFolder = appFolder + File.separator + "mailers";
|
||||||
|
protected String modelsFolder = appFolder + File.separator + "models";
|
||||||
|
protected String viewsFolder = appFolder + File.separator + "views";
|
||||||
|
protected String layoutsFolder = viewsFolder + File.separator + "layouts";
|
||||||
|
protected String binFolder = "bin";
|
||||||
|
protected String configFolder = "config";
|
||||||
|
protected String environmentsFolder = configFolder + File.separator + "environments";
|
||||||
|
protected String initializersFolder = configFolder + File.separator + "initializers";
|
||||||
|
protected String localesFolder = configFolder + File.separator + "locales";
|
||||||
|
protected String dbFolder = "db";
|
||||||
|
protected String migrateFolder = dbFolder + File.separator + "migrate";
|
||||||
|
protected String libFolder = "lib";
|
||||||
|
protected String tasksFolder = libFolder + File.separator + "tasks";
|
||||||
|
protected String logFolder = "log";
|
||||||
|
protected String publicFolder = "public";
|
||||||
|
protected String testFolder = "test";
|
||||||
|
protected String tmpFolder = "tmp";
|
||||||
|
protected String cacheFolder = tmpFolder + File.separator + "cache";
|
||||||
|
protected String pidFolder = tmpFolder + File.separator + "pids";
|
||||||
|
protected String socketsFolder = tmpFolder + File.separator + "sockets";
|
||||||
|
protected String vendorFolder = "vendor";
|
||||||
|
|
||||||
|
public Rails5ServerCodegen() {
|
||||||
|
super();
|
||||||
|
outputFolder = "generated-code" + File.separator + "rails5";
|
||||||
|
apiPackage = "app/controllers";
|
||||||
|
apiTemplateFiles.put("controller.mustache", ".rb");
|
||||||
|
|
||||||
|
modelPackage = "app/models";
|
||||||
|
modelTemplateFiles.put("model.mustache", ".rb");
|
||||||
|
|
||||||
|
embeddedTemplateDir = templateDir = "rails5";
|
||||||
|
|
||||||
|
typeMapping.clear();
|
||||||
|
languageSpecificPrimitives.clear();
|
||||||
|
|
||||||
|
setReservedWordsLowerCase(
|
||||||
|
Arrays.asList(
|
||||||
|
"__FILE__", "and", "def", "end", "in", "or", "self", "unless", "__LINE__",
|
||||||
|
"begin", "defined?", "ensure", "module", "redo", "super", "until", "BEGIN",
|
||||||
|
"break", "do", "false", "next", "rescue", "then", "when", "END", "case",
|
||||||
|
"else", "for", "nil", "retry", "true", "while", "alias", "class", "elsif",
|
||||||
|
"if", "not", "return", "undef", "yield")
|
||||||
|
);
|
||||||
|
|
||||||
|
typeMapping.put("string", "string");
|
||||||
|
typeMapping.put("char", "string");
|
||||||
|
typeMapping.put("int", "integer");
|
||||||
|
typeMapping.put("integer", "integer");
|
||||||
|
typeMapping.put("long", "integer");
|
||||||
|
typeMapping.put("short", "integer");
|
||||||
|
typeMapping.put("float", "float");
|
||||||
|
typeMapping.put("double", "decimal");
|
||||||
|
typeMapping.put("number", "float");
|
||||||
|
typeMapping.put("date", "date");
|
||||||
|
typeMapping.put("DateTime", "datetime");
|
||||||
|
typeMapping.put("boolean", "boolean");
|
||||||
|
typeMapping.put("binary", "string");
|
||||||
|
typeMapping.put("ByteArray", "string");
|
||||||
|
typeMapping.put("UUID", "string");
|
||||||
|
|
||||||
|
// remove modelPackage and apiPackage added by default
|
||||||
|
cliOptions.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processOpts() {
|
||||||
|
super.processOpts();
|
||||||
|
|
||||||
|
// use constant model/api package (folder path)
|
||||||
|
//setModelPackage("models");
|
||||||
|
setApiPackage("app/controllers");
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("Gemfile", "", "Gemfile"));
|
||||||
|
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
|
||||||
|
supportingFiles.add(new SupportingFile("Rakefile", "", "Rakefile"));
|
||||||
|
supportingFiles.add(new SupportingFile("config.ru", "", "config.ru"));
|
||||||
|
supportingFiles.add(new SupportingFile("channel.rb", applicationCableFolder, "channel.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("connection.rb", applicationCableFolder, "connection.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("application_controller.rb", controllersFolder, "application_controller.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("application_job.rb", jobsFolder, "application_job.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("application_mailer.rb", mailersFolder, "application_mailer.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("application_record.rb", modelsFolder, "application_record.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("mailer.html.erb", layoutsFolder, "mailer.html.erb"));
|
||||||
|
supportingFiles.add(new SupportingFile("mailer.text.erb", layoutsFolder, "mailer.text.erb"));
|
||||||
|
supportingFiles.add(new SupportingFile("bundle", binFolder, "bundle"));
|
||||||
|
supportingFiles.add(new SupportingFile("rails", binFolder, "rails"));
|
||||||
|
supportingFiles.add(new SupportingFile("rake", binFolder, "rake"));
|
||||||
|
supportingFiles.add(new SupportingFile("setup", binFolder, "setup"));
|
||||||
|
supportingFiles.add(new SupportingFile("update", binFolder, "update"));
|
||||||
|
supportingFiles.add(new SupportingFile("development.rb", environmentsFolder, "development.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("production.rb", environmentsFolder, "production.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("active_record_belongs_to_required_by_default.rb", initializersFolder, "active_record_belongs_to_required_by_default.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("application_controller_renderer.rb", initializersFolder, "application_controller_renderer.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("backtrace_silencers.rb", initializersFolder, "backtrace_silencers.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("callback_terminator.rb", initializersFolder, "callback_terminator.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("cors.rb", initializersFolder, "cors.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("filter_parameter_logging.rb", initializersFolder, "filter_parameter_logging.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("inflections.rb", initializersFolder, "inflections.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("mime_types.rb", initializersFolder, "mime_types.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("ssl_options.rb", initializersFolder, "ssl_options.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("to_time_preserves_timezone.rb", initializersFolder, "to_time_preserves_timezone.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("en.yml", localesFolder, "en.yml"));
|
||||||
|
supportingFiles.add(new SupportingFile("application.rb", configFolder, "application.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("boot.rb", configFolder, "boot.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("cable.yml", configFolder, "cable.yml"));
|
||||||
|
supportingFiles.add(new SupportingFile("database.yml", configFolder, "database.yml"));
|
||||||
|
supportingFiles.add(new SupportingFile("environment.rb", configFolder, "environment.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("puma.rb", configFolder, "puma.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("routes.mustache", configFolder, "routes.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("secrets.yml", configFolder, "secrets.yml"));
|
||||||
|
supportingFiles.add(new SupportingFile("spring.rb", configFolder, "spring.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile(".keep", migrateFolder, ".keep"));
|
||||||
|
supportingFiles.add(new SupportingFile("migrate.mustache", migrateFolder, "0_init_tables.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("schema.rb", dbFolder, "schema.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("seeds.rb", dbFolder, "seeds.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile(".keep", tasksFolder, ".keep"));
|
||||||
|
supportingFiles.add(new SupportingFile(".keep", logFolder, ".keep"));
|
||||||
|
supportingFiles.add(new SupportingFile("404.html", publicFolder, "404.html"));
|
||||||
|
supportingFiles.add(new SupportingFile("422.html", publicFolder, "422.html"));
|
||||||
|
supportingFiles.add(new SupportingFile("500.html", publicFolder, "500.html"));
|
||||||
|
supportingFiles.add(new SupportingFile("apple-touch-icon-precomposed.png", publicFolder, "apple-touch-icon-precomposed.png"));
|
||||||
|
supportingFiles.add(new SupportingFile("apple-touch-icon.png", publicFolder, "apple-touch-icon.png"));
|
||||||
|
supportingFiles.add(new SupportingFile("favicon.ico", publicFolder, "favicon.ico"));
|
||||||
|
supportingFiles.add(new SupportingFile("robots.txt", publicFolder, "robots.txt"));
|
||||||
|
supportingFiles.add(new SupportingFile("robots.txt", publicFolder, "robots.txt"));
|
||||||
|
supportingFiles.add(new SupportingFile("test_helper.rb", testFolder, "test_helper.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile(".keep", cacheFolder, ".keep"));
|
||||||
|
supportingFiles.add(new SupportingFile(".keep", pidFolder, ".keep"));
|
||||||
|
supportingFiles.add(new SupportingFile(".keep", socketsFolder, ".keep"));
|
||||||
|
supportingFiles.add(new SupportingFile("restart.txt", tmpFolder, "restart.txt"));
|
||||||
|
supportingFiles.add(new SupportingFile(".keep", vendorFolder, ".keep"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.SERVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "rails5";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates a Rails5 server library.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeReservedWord(String name) {
|
||||||
|
if(this.reservedWordsMappings().containsKey(name)) {
|
||||||
|
return this.reservedWordsMappings().get(name);
|
||||||
|
}
|
||||||
|
return "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiFileFolder() {
|
||||||
|
return outputFolder + File.separator + apiPackage.replace("/", File.separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(Schema p) {
|
||||||
|
if (p instanceof ArraySchema) {
|
||||||
|
ArraySchema ap = (ArraySchema) p;
|
||||||
|
Schema inner = ap.getItems();
|
||||||
|
return getSchemaType(p) + "[" + getTypeDeclaration(inner) + "]";
|
||||||
|
} else if (p instanceof MapSchema) {
|
||||||
|
MapSchema mp = (MapSchema) p;
|
||||||
|
Schema inner = (Schema) mp.getAdditionalProperties();
|
||||||
|
return getSchemaType(p) + "[string," + getTypeDeclaration(inner) + "]";
|
||||||
|
}
|
||||||
|
return super.getTypeDeclaration(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toDefaultValue(Schema p) {
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toVarName(String name) {
|
||||||
|
// replace - with _ e.g. created-at => created_at
|
||||||
|
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
|
||||||
|
// if it's all uppper case, convert to lower case
|
||||||
|
if (name.matches("^[A-Z_]*$")) {
|
||||||
|
name = name.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize (lower first character) the variable name
|
||||||
|
// petId => pet_id
|
||||||
|
name = underscore(name);
|
||||||
|
|
||||||
|
// for reserved word or word starting with number, append _
|
||||||
|
if (isReservedWord(name) || name.matches("^\\d.*")) {
|
||||||
|
name = escapeReservedWord(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSchemaType(Schema p) {
|
||||||
|
String swaggerType = super.getSchemaType(p);
|
||||||
|
String type = null;
|
||||||
|
if (typeMapping.containsKey(swaggerType)) {
|
||||||
|
return typeMapping.get(swaggerType);
|
||||||
|
}
|
||||||
|
return "string";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toParamName(String name) {
|
||||||
|
// should be the same as variable name
|
||||||
|
return toVarName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelName(String name) {
|
||||||
|
// model name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
String modelName = camelize("Model" + name);
|
||||||
|
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + modelName);
|
||||||
|
return modelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize the model name
|
||||||
|
// phone_number => PhoneNumber
|
||||||
|
return camelize(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelFilename(String name) {
|
||||||
|
// model name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
String filename = underscore("model_" + name);
|
||||||
|
LOGGER.warn(name + " (reserved word) cannot be used as model filename. Renamed to " + filename);
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
// underscore the model file name
|
||||||
|
// PhoneNumber.rb => phone_number.rb
|
||||||
|
return underscore(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiFilename(String name) {
|
||||||
|
// replace - with _ e.g. created-at => created_at
|
||||||
|
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
|
||||||
|
// e.g. DefaultController => defaults_controller.rb
|
||||||
|
return underscore(name) + "_controller";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiName(String name) {
|
||||||
|
if (name.length() == 0) {
|
||||||
|
return "ApiController";
|
||||||
|
}
|
||||||
|
// e.g. phone_number_api => PhoneNumberApi
|
||||||
|
return camelize(name) + "Controller";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toOperationId(String operationId) {
|
||||||
|
// method name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(operationId)) {
|
||||||
|
String newOperationId = underscore("call_" + operationId);
|
||||||
|
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + newOperationId);
|
||||||
|
return newOperationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return underscore(operationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
|
||||||
|
OpenAPI openAPI = (OpenAPI) objs.get("swagger");
|
||||||
|
if(openAPI != null) {
|
||||||
|
try {
|
||||||
|
objs.put("swagger-yaml", Yaml.mapper().writeValueAsString(openAPI));
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
LOGGER.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.postProcessSupportingFileData(objs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeQuotationMark(String input) {
|
||||||
|
// remove ' to avoid code injection
|
||||||
|
return input.replace("'", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeUnsafeCharacters(String input) {
|
||||||
|
return input.replace("=end", "=_end").replace("=begin", "=_begin");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,246 @@
|
|||||||
|
package org.openapitools.codegen.languages;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
import org.openapitools.codegen.CodegenType;
|
||||||
|
import org.openapitools.codegen.CodegenOperation;
|
||||||
|
import org.openapitools.codegen.DefaultCodegen;
|
||||||
|
import org.openapitools.codegen.SupportingFile;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.Operation;
|
||||||
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
public class SilexServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||||
|
protected String invokerPackage;
|
||||||
|
protected String groupId = "io.swagger";
|
||||||
|
protected String artifactId = "swagger-server";
|
||||||
|
protected String artifactVersion = "1.0.0";
|
||||||
|
|
||||||
|
public SilexServerCodegen() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
invokerPackage = camelize("SwaggerServer");
|
||||||
|
|
||||||
|
String packagePath = "SwaggerServer";
|
||||||
|
|
||||||
|
modelPackage = packagePath + "/lib/models";
|
||||||
|
apiPackage = packagePath + "/lib";
|
||||||
|
outputFolder = "generated-code/php-silex";
|
||||||
|
|
||||||
|
// no model, api files
|
||||||
|
modelTemplateFiles.clear();
|
||||||
|
apiTemplateFiles.clear();
|
||||||
|
|
||||||
|
embeddedTemplateDir = templateDir = "php-silex";
|
||||||
|
|
||||||
|
setReservedWordsLowerCase(
|
||||||
|
Arrays.asList(
|
||||||
|
"__halt_compiler", "abstract", "and", "array", "as", "break", "callable", "case", "catch", "class", "clone", "const", "continue", "declare", "default", "die", "do", "echo", "else", "elseif", "empty", "enddeclare", "endfor", "endforeach", "endif", "endswitch", "endwhile", "eval", "exit", "extends", "final", "for", "foreach", "function", "global", "goto", "if", "implements", "include", "include_once", "instanceof", "insteadof", "interface", "isset", "list", "namespace", "new", "or", "print", "private", "protected", "public", "require", "require_once", "return", "static", "switch", "throw", "trait", "try", "unset", "use", "var", "while", "xor")
|
||||||
|
);
|
||||||
|
|
||||||
|
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||||
|
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||||
|
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||||
|
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||||
|
|
||||||
|
// ref: http://php.net/manual/en/language.types.intro.php
|
||||||
|
languageSpecificPrimitives = new HashSet<String>(
|
||||||
|
Arrays.asList(
|
||||||
|
"boolean",
|
||||||
|
"int",
|
||||||
|
"integer",
|
||||||
|
"double",
|
||||||
|
"float",
|
||||||
|
"string",
|
||||||
|
"object",
|
||||||
|
"DateTime",
|
||||||
|
"mixed",
|
||||||
|
"number")
|
||||||
|
);
|
||||||
|
|
||||||
|
instantiationTypes.put("array", "array");
|
||||||
|
instantiationTypes.put("map", "map");
|
||||||
|
|
||||||
|
// ref: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types
|
||||||
|
typeMapping = new HashMap<String, String>();
|
||||||
|
typeMapping.put("integer", "int");
|
||||||
|
typeMapping.put("long", "int");
|
||||||
|
typeMapping.put("float", "float");
|
||||||
|
typeMapping.put("double", "double");
|
||||||
|
typeMapping.put("string", "string");
|
||||||
|
typeMapping.put("byte", "int");
|
||||||
|
typeMapping.put("boolean", "boolean");
|
||||||
|
typeMapping.put("date", "DateTime");
|
||||||
|
typeMapping.put("datetime", "DateTime");
|
||||||
|
typeMapping.put("file", "string");
|
||||||
|
typeMapping.put("map", "map");
|
||||||
|
typeMapping.put("array", "array");
|
||||||
|
typeMapping.put("list", "array");
|
||||||
|
typeMapping.put("object", "object");
|
||||||
|
//TODO binary should be mapped to byte array
|
||||||
|
// mapped to String as a workaround
|
||||||
|
typeMapping.put("binary", "string");
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("README.mustache", packagePath.replace('/', File.separatorChar), "README.md"));
|
||||||
|
supportingFiles.add(new SupportingFile("composer.json", packagePath.replace('/', File.separatorChar), "composer.json"));
|
||||||
|
supportingFiles.add(new SupportingFile("index.mustache", packagePath.replace('/', File.separatorChar), "index.php"));
|
||||||
|
supportingFiles.add(new SupportingFile(".htaccess", packagePath.replace('/', File.separatorChar), ".htaccess"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.SERVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "php-silex";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates a PHP Silex server library.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeReservedWord(String name) {
|
||||||
|
if(this.reservedWordsMappings().containsKey(name)) {
|
||||||
|
return this.reservedWordsMappings().get(name);
|
||||||
|
}
|
||||||
|
return "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiFileFolder() {
|
||||||
|
return (outputFolder + "/" + apiPackage()).replace('/', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelFileFolder() {
|
||||||
|
return (outputFolder + "/" + modelPackage()).replace('/', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(Schema p) {
|
||||||
|
if (p instanceof ArraySchema) {
|
||||||
|
ArraySchema ap = (ArraySchema) p;
|
||||||
|
Schema inner = ap.getItems();
|
||||||
|
return getSchemaType(p) + "[" + getTypeDeclaration(inner) + "]";
|
||||||
|
} else if (p instanceof MapSchema) {
|
||||||
|
MapSchema mp = (MapSchema) p;
|
||||||
|
Schema inner = (Schema) mp.getAdditionalProperties();
|
||||||
|
return getSchemaType(p) + "[string," + getTypeDeclaration(inner) + "]";
|
||||||
|
}
|
||||||
|
return super.getTypeDeclaration(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSchemaType(Schema p) {
|
||||||
|
String swaggerType = super.getSchemaType(p);
|
||||||
|
String type = null;
|
||||||
|
if (typeMapping.containsKey(swaggerType)) {
|
||||||
|
type = typeMapping.get(swaggerType);
|
||||||
|
if (languageSpecificPrimitives.contains(type)) {
|
||||||
|
return type;
|
||||||
|
} else if (instantiationTypes.containsKey(type)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
type = swaggerType;
|
||||||
|
}
|
||||||
|
if (type == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return toModelName(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toDefaultValue(Schema p) {
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toVarName(String name) {
|
||||||
|
// return the name in underscore style
|
||||||
|
// PhoneNumber => phone_number
|
||||||
|
name = underscore(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
|
||||||
|
// parameter name starting with number won't compile
|
||||||
|
// need to escape it by appending _ at the beginning
|
||||||
|
if (name.matches("^\\d.*")) {
|
||||||
|
name = "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toParamName(String name) {
|
||||||
|
// should be the same as variable name
|
||||||
|
return toVarName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelName(String name) {
|
||||||
|
// model name cannot use reserved keyword
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
escapeReservedWord(name); // e.g. return => _return
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize the model name
|
||||||
|
// phone_number => PhoneNumber
|
||||||
|
return camelize(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelFilename(String name) {
|
||||||
|
// should be the same as the model name
|
||||||
|
return toModelName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeQuotationMark(String input) {
|
||||||
|
// remove ' to avoid code injection
|
||||||
|
return input.replace("'", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeUnsafeCharacters(String input) {
|
||||||
|
return input.replace("*/", "*_/").replace("/*", "/_*");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||||
|
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||||
|
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
|
||||||
|
for (CodegenOperation op : operationList) {
|
||||||
|
String path = new String(op.path);
|
||||||
|
String[] items = path.split("/", -1);
|
||||||
|
String opsPath = "";
|
||||||
|
int pathParamIndex = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < items.length; ++i) {
|
||||||
|
if (items[i].matches("^\\{(.*)\\}$")) { // wrap in {}
|
||||||
|
// camelize path variable
|
||||||
|
items[i] = "{" + camelize(items[i].substring(1, items[i].length()-1), true) + "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
op.path = StringUtils.join(items, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
return objs;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,264 @@
|
|||||||
|
package org.openapitools.codegen.languages;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.CodegenType;
|
||||||
|
import org.openapitools.codegen.DefaultCodegen;
|
||||||
|
import org.openapitools.codegen.SupportingFile;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.Operation;
|
||||||
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
import io.swagger.v3.core.util.Yaml;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class SinatraServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(SinatraServerCodegen.class);
|
||||||
|
|
||||||
|
protected String gemName;
|
||||||
|
protected String moduleName;
|
||||||
|
protected String gemVersion = "1.0.0";
|
||||||
|
protected String libFolder = "lib";
|
||||||
|
|
||||||
|
public SinatraServerCodegen() {
|
||||||
|
super();
|
||||||
|
apiPackage = "lib";
|
||||||
|
outputFolder = "generated-code" + File.separator + "sinatra";
|
||||||
|
|
||||||
|
// no model
|
||||||
|
modelTemplateFiles.clear();
|
||||||
|
apiTemplateFiles.put("api.mustache", ".rb");
|
||||||
|
embeddedTemplateDir = templateDir = "sinatra";
|
||||||
|
|
||||||
|
typeMapping.clear();
|
||||||
|
languageSpecificPrimitives.clear();
|
||||||
|
|
||||||
|
setReservedWordsLowerCase(
|
||||||
|
Arrays.asList(
|
||||||
|
"__FILE__", "and", "def", "end", "in", "or", "self", "unless", "__LINE__",
|
||||||
|
"begin", "defined?", "ensure", "module", "redo", "super", "until", "BEGIN",
|
||||||
|
"break", "do", "false", "next", "rescue", "then", "when", "END", "case",
|
||||||
|
"else", "for", "nil", "retry", "true", "while", "alias", "class", "elsif",
|
||||||
|
"if", "not", "return", "undef", "yield")
|
||||||
|
);
|
||||||
|
|
||||||
|
languageSpecificPrimitives.add("int");
|
||||||
|
languageSpecificPrimitives.add("array");
|
||||||
|
languageSpecificPrimitives.add("map");
|
||||||
|
languageSpecificPrimitives.add("string");
|
||||||
|
languageSpecificPrimitives.add("DateTime");
|
||||||
|
|
||||||
|
typeMapping.put("long", "int");
|
||||||
|
typeMapping.put("integer", "int");
|
||||||
|
typeMapping.put("Array", "array");
|
||||||
|
typeMapping.put("String", "string");
|
||||||
|
typeMapping.put("List", "array");
|
||||||
|
typeMapping.put("map", "map");
|
||||||
|
//TODO binary should be mapped to byte array
|
||||||
|
// mapped to String as a workaround
|
||||||
|
typeMapping.put("binary", "string");
|
||||||
|
typeMapping.put("UUID", "string");
|
||||||
|
|
||||||
|
// remove modelPackage and apiPackage added by default
|
||||||
|
cliOptions.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processOpts() {
|
||||||
|
super.processOpts();
|
||||||
|
|
||||||
|
// use constant model/api package (folder path)
|
||||||
|
//setModelPackage("models");
|
||||||
|
setApiPackage("api");
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("my_app.mustache", "", "my_app.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("Swaggering.rb", libFolder, "swaggering.rb"));
|
||||||
|
supportingFiles.add(new SupportingFile("config.ru", "", "config.ru"));
|
||||||
|
supportingFiles.add(new SupportingFile("Gemfile", "", "Gemfile"));
|
||||||
|
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
|
||||||
|
supportingFiles.add(new SupportingFile("swagger.mustache","","swagger.yaml"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.SERVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "ruby-sinatra";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates a Ruby Sinatra server library.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeReservedWord(String name) {
|
||||||
|
if(this.reservedWordsMappings().containsKey(name)) {
|
||||||
|
return this.reservedWordsMappings().get(name);
|
||||||
|
}
|
||||||
|
return "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiFileFolder() {
|
||||||
|
return outputFolder + File.separator + apiPackage.replace("/", File.separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(Schema p) {
|
||||||
|
if (p instanceof ArraySchema) {
|
||||||
|
ArraySchema ap = (ArraySchema) p;
|
||||||
|
Schema inner = ap.getItems();
|
||||||
|
return getSchemaType(p) + "[" + getTypeDeclaration(inner) + "]";
|
||||||
|
} else if (p instanceof MapSchema) {
|
||||||
|
MapSchema mp = (MapSchema) p;
|
||||||
|
Schema inner = (Schema) mp.getAdditionalProperties();
|
||||||
|
return getSchemaType(p) + "[string," + getTypeDeclaration(inner) + "]";
|
||||||
|
}
|
||||||
|
return super.getTypeDeclaration(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSchemaType(Schema p) {
|
||||||
|
String openAPIType = super.getSchemaType(p);
|
||||||
|
String type = null;
|
||||||
|
if (typeMapping.containsKey(openAPIType)) {
|
||||||
|
type = typeMapping.get(openAPIType);
|
||||||
|
if (languageSpecificPrimitives.contains(type)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
type = openAPIType;
|
||||||
|
}
|
||||||
|
if (type == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toDefaultValue(Schema p) {
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toVarName(String name) {
|
||||||
|
// replace - with _ e.g. created-at => created_at
|
||||||
|
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
|
||||||
|
// if it's all uppper case, convert to lower case
|
||||||
|
if (name.matches("^[A-Z_]*$")) {
|
||||||
|
name = name.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize (lower first character) the variable name
|
||||||
|
// petId => pet_id
|
||||||
|
name = underscore(name);
|
||||||
|
|
||||||
|
// for reserved word or word starting with number, append _
|
||||||
|
if (isReservedWord(name) || name.matches("^\\d.*")) {
|
||||||
|
name = escapeReservedWord(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toParamName(String name) {
|
||||||
|
// should be the same as variable name
|
||||||
|
return toVarName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelName(String name) {
|
||||||
|
// model name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
LOGGER.warn(name + " (reserved word) cannot be used as model filename. Renamed to " + camelize("model_" + name));
|
||||||
|
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize the model name
|
||||||
|
// phone_number => PhoneNumber
|
||||||
|
return camelize(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelFilename(String name) {
|
||||||
|
// model name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
LOGGER.warn(name + " (reserved word) cannot be used as model filename. Renamed to " + underscore("model_" + name));
|
||||||
|
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// underscore the model file name
|
||||||
|
// PhoneNumber.rb => phone_number.rb
|
||||||
|
return underscore(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiFilename(String name) {
|
||||||
|
// replace - with _ e.g. created-at => created_at
|
||||||
|
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
|
||||||
|
// e.g. PhoneNumberApi.rb => phone_number_api.rb
|
||||||
|
return underscore(name) + "_api";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiName(String name) {
|
||||||
|
if (name.length() == 0) {
|
||||||
|
return "DefaultApi";
|
||||||
|
}
|
||||||
|
// e.g. phone_number_api => PhoneNumberApi
|
||||||
|
return camelize(name) + "Api";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toOperationId(String operationId) {
|
||||||
|
// method name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(operationId)) {
|
||||||
|
String newOperationId = underscore("call_" + operationId);
|
||||||
|
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + newOperationId);
|
||||||
|
return newOperationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return underscore(operationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
|
||||||
|
OpenAPI openAPI = (OpenAPI) objs.get("openapi");
|
||||||
|
if (openAPI != null) {
|
||||||
|
try {
|
||||||
|
objs.put("swagger-yaml", Yaml.mapper().writeValueAsString(openAPI));
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
LOGGER.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.postProcessSupportingFileData(objs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeQuotationMark(String input) {
|
||||||
|
// remove ' to avoid code injection
|
||||||
|
return input.replace("'", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeUnsafeCharacters(String input) {
|
||||||
|
return input.replace("=end", "=_end").replace("=begin", "=_begin");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,286 @@
|
|||||||
|
package org.openapitools.codegen.languages;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
import org.openapitools.codegen.CodegenType;
|
||||||
|
import org.openapitools.codegen.DefaultCodegen;
|
||||||
|
import org.openapitools.codegen.SupportingFile;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.Operation;
|
||||||
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
import io.swagger.v3.core.util.Yaml;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
public class SlimFrameworkServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||||
|
protected String invokerPackage;
|
||||||
|
protected String srcBasePath = "lib";
|
||||||
|
protected String groupId = "io.swagger";
|
||||||
|
protected String artifactId = "swagger-server";
|
||||||
|
protected String artifactVersion = "1.0.0";
|
||||||
|
protected String packagePath = ""; // empty packagePath (top folder)
|
||||||
|
|
||||||
|
|
||||||
|
private String variableNamingConvention = "camelCase";
|
||||||
|
|
||||||
|
public SlimFrameworkServerCodegen() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// clear import mapping (from default generator) as slim does not use it
|
||||||
|
// at the moment
|
||||||
|
importMapping.clear();
|
||||||
|
|
||||||
|
invokerPackage = camelize("SwaggerServer");
|
||||||
|
|
||||||
|
//String packagePath = "SwaggerServer";
|
||||||
|
|
||||||
|
modelPackage = packagePath + "\\Models";
|
||||||
|
apiPackage = packagePath;
|
||||||
|
outputFolder = "generated-code" + File.separator + "slim";
|
||||||
|
modelTemplateFiles.put("model.mustache", ".php");
|
||||||
|
|
||||||
|
// no api files
|
||||||
|
apiTemplateFiles.clear();
|
||||||
|
|
||||||
|
embeddedTemplateDir = templateDir = "slim";
|
||||||
|
|
||||||
|
setReservedWordsLowerCase(
|
||||||
|
Arrays.asList(
|
||||||
|
"__halt_compiler", "abstract", "and", "array", "as", "break", "callable", "case", "catch", "class", "clone", "const", "continue", "declare", "default", "die", "do", "echo", "else", "elseif", "empty", "enddeclare", "endfor", "endforeach", "endif", "endswitch", "endwhile", "eval", "exit", "extends", "final", "for", "foreach", "function", "global", "goto", "if", "implements", "include", "include_once", "instanceof", "insteadof", "interface", "isset", "list", "namespace", "new", "or", "print", "private", "protected", "public", "require", "require_once", "return", "static", "switch", "throw", "trait", "try", "unset", "use", "var", "while", "xor")
|
||||||
|
);
|
||||||
|
|
||||||
|
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||||
|
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||||
|
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||||
|
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||||
|
|
||||||
|
// ref: http://php.net/manual/en/language.types.intro.php
|
||||||
|
languageSpecificPrimitives = new HashSet<String>(
|
||||||
|
Arrays.asList(
|
||||||
|
"boolean",
|
||||||
|
"int",
|
||||||
|
"integer",
|
||||||
|
"double",
|
||||||
|
"float",
|
||||||
|
"string",
|
||||||
|
"object",
|
||||||
|
"DateTime",
|
||||||
|
"mixed",
|
||||||
|
"number")
|
||||||
|
);
|
||||||
|
|
||||||
|
instantiationTypes.put("array", "array");
|
||||||
|
instantiationTypes.put("map", "map");
|
||||||
|
|
||||||
|
// ref: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types
|
||||||
|
typeMapping = new HashMap<String, String>();
|
||||||
|
typeMapping.put("integer", "int");
|
||||||
|
typeMapping.put("long", "int");
|
||||||
|
typeMapping.put("float", "float");
|
||||||
|
typeMapping.put("double", "double");
|
||||||
|
typeMapping.put("string", "string");
|
||||||
|
typeMapping.put("byte", "int");
|
||||||
|
typeMapping.put("boolean", "bool");
|
||||||
|
typeMapping.put("date", "\\DateTime");
|
||||||
|
typeMapping.put("datetime", "\\DateTime");
|
||||||
|
typeMapping.put("file", "\\SplFileObject");
|
||||||
|
typeMapping.put("map", "map");
|
||||||
|
typeMapping.put("array", "array");
|
||||||
|
typeMapping.put("list", "array");
|
||||||
|
typeMapping.put("object", "object");
|
||||||
|
//TODO binary should be mapped to byte array
|
||||||
|
// mapped to String as a workaround
|
||||||
|
typeMapping.put("binary", "string");
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("README.mustache", packagePath.replace('/', File.separatorChar), "README.md"));
|
||||||
|
supportingFiles.add(new SupportingFile("composer.json", packagePath.replace('/', File.separatorChar), "composer.json"));
|
||||||
|
supportingFiles.add(new SupportingFile("index.mustache", packagePath.replace('/', File.separatorChar), "index.php"));
|
||||||
|
supportingFiles.add(new SupportingFile(".htaccess", packagePath.replace('/', File.separatorChar), ".htaccess"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.SERVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "php-slim";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates a PHP Slim Framework server library.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeReservedWord(String name) {
|
||||||
|
if(this.reservedWordsMappings().containsKey(name)) {
|
||||||
|
return this.reservedWordsMappings().get(name);
|
||||||
|
}
|
||||||
|
return "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiFileFolder() {
|
||||||
|
return (outputFolder + "/" + toPackagePath(apiPackage, srcBasePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelFileFolder() {
|
||||||
|
return (outputFolder + "/" + toPackagePath(modelPackage, srcBasePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(Schema p) {
|
||||||
|
if (p instanceof ArraySchema) {
|
||||||
|
ArraySchema ap = (ArraySchema) p;
|
||||||
|
Schema inner = ap.getItems();
|
||||||
|
return getTypeDeclaration(inner) + "[]";
|
||||||
|
} else if (p instanceof MapSchema) {
|
||||||
|
MapSchema mp = (MapSchema) p;
|
||||||
|
Schema inner = (Schema) mp.getAdditionalProperties();
|
||||||
|
return getSchemaType(p) + "[string," + getTypeDeclaration(inner) + "]";
|
||||||
|
} else if (!StringUtils.isEmpty(p.get$ref())) {
|
||||||
|
String type = super.getTypeDeclaration(p);
|
||||||
|
return (!languageSpecificPrimitives.contains(type))
|
||||||
|
? "\\" + modelPackage + "\\" + type : type;
|
||||||
|
}
|
||||||
|
return super.getTypeDeclaration(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSchemaType(Schema p) {
|
||||||
|
String openAPIType = super.getSchemaType(p);
|
||||||
|
String type = null;
|
||||||
|
if (typeMapping.containsKey(openAPIType)) {
|
||||||
|
type = typeMapping.get(openAPIType);
|
||||||
|
if (languageSpecificPrimitives.contains(type)) {
|
||||||
|
return type;
|
||||||
|
} else if (instantiationTypes.containsKey(type)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
type = openAPIType;
|
||||||
|
}
|
||||||
|
if (type == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return toModelName(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(String name) {
|
||||||
|
if (!languageSpecificPrimitives.contains(name)) {
|
||||||
|
return "\\" + modelPackage + "\\" + name;
|
||||||
|
}
|
||||||
|
return super.getTypeDeclaration(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toDefaultValue(Schema p) {
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParameterNamingConvention(String variableNamingConvention) {
|
||||||
|
this.variableNamingConvention = variableNamingConvention;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toVarName(String name) {
|
||||||
|
name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
|
||||||
|
if ("camelCase".equals(variableNamingConvention)) {
|
||||||
|
// return the name in camelCase style
|
||||||
|
// phone_number => phoneNumber
|
||||||
|
name = camelize(name, true);
|
||||||
|
} else { // default to snake case
|
||||||
|
// return the name in underscore style
|
||||||
|
// PhoneNumber => phone_number
|
||||||
|
name = underscore(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// parameter name starting with number won't compile
|
||||||
|
// need to escape it by appending _ at the beginning
|
||||||
|
if (name.matches("^\\d.*")) {
|
||||||
|
name = "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toParamName(String name) {
|
||||||
|
// should be the same as variable name
|
||||||
|
return toVarName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelName(String name) {
|
||||||
|
// model name cannot use reserved keyword
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
escapeReservedWord(name); // e.g. return => _return
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize the model name
|
||||||
|
// phone_number => PhoneNumber
|
||||||
|
return camelize(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toModelFilename(String name) {
|
||||||
|
// should be the same as the model name
|
||||||
|
return toModelName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toPackagePath(String packageName, String basePath) {
|
||||||
|
packageName = packageName.replace(invokerPackage, ""); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
if (basePath != null && basePath.length() > 0) {
|
||||||
|
basePath = basePath.replaceAll("[\\\\/]?$", "") + File.separatorChar; // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||||
|
}
|
||||||
|
|
||||||
|
String regFirstPathSeparator;
|
||||||
|
if ("/".equals(File.separator)) { // for mac, linux
|
||||||
|
regFirstPathSeparator = "^/";
|
||||||
|
} else { // for windows
|
||||||
|
regFirstPathSeparator = "^\\\\";
|
||||||
|
}
|
||||||
|
|
||||||
|
String regLastPathSeparator;
|
||||||
|
if ("/".equals(File.separator)) { // for mac, linux
|
||||||
|
regLastPathSeparator = "/$";
|
||||||
|
} else { // for windows
|
||||||
|
regLastPathSeparator = "\\\\$";
|
||||||
|
}
|
||||||
|
|
||||||
|
return (getPackagePath() + File.separatorChar + basePath
|
||||||
|
// Replace period, backslash, forward slash with file separator in package name
|
||||||
|
+ packageName.replaceAll("[\\.\\\\/]", Matcher.quoteReplacement(File.separator))
|
||||||
|
// Trim prefix file separators from package path
|
||||||
|
.replaceAll(regFirstPathSeparator, ""))
|
||||||
|
// Trim trailing file separators from the overall path
|
||||||
|
.replaceAll(regLastPathSeparator+ "$", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPackagePath() {
|
||||||
|
return packagePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeQuotationMark(String input) {
|
||||||
|
// remove ' to avoid code injection
|
||||||
|
return input.replace("'", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeUnsafeCharacters(String input) {
|
||||||
|
return input.replace("*/", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,16 @@
|
|||||||
|
org.openapitools.codegen.languages.AndroidClientCodegen
|
||||||
org.openapitools.codegen.languages.BashClientCodegen
|
org.openapitools.codegen.languages.BashClientCodegen
|
||||||
|
org.openapitools.codegen.languages.DartClientCodegen
|
||||||
|
org.openapitools.codegen.languages.ElixirClientCodegen
|
||||||
org.openapitools.codegen.languages.HaskellServantCodegen
|
org.openapitools.codegen.languages.HaskellServantCodegen
|
||||||
|
org.openapitools.codegen.languages.LumenServerCodegen
|
||||||
org.openapitools.codegen.languages.ObjcClientCodegen
|
org.openapitools.codegen.languages.ObjcClientCodegen
|
||||||
org.openapitools.codegen.languages.PhpClientCodegen
|
org.openapitools.codegen.languages.PhpClientCodegen
|
||||||
|
org.openapitools.codegen.languages.PowerShellClientCodegen
|
||||||
|
org.openapitools.codegen.languages.PythonClientCodegen
|
||||||
|
org.openapitools.codegen.languages.RClientCodegen
|
||||||
|
org.openapitools.codegen.languages.Rails5ServerCodegen
|
||||||
org.openapitools.codegen.languages.RubyClientCodegen
|
org.openapitools.codegen.languages.RubyClientCodegen
|
||||||
|
org.openapitools.codegen.languages.SlimFrameworkServerCodegen
|
||||||
|
org.openapitools.codegen.languages.SilexServerCodegen
|
||||||
|
org.openapitools.codegen.languages.SinatraServerCodegen
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package org.openapitools.codegen.dart;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.AbstractOptionsTest;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.languages.DartClientCodegen;
|
||||||
|
import org.openapitools.codegen.options.DartClientOptionsProvider;
|
||||||
|
|
||||||
|
import mockit.Expectations;
|
||||||
|
import mockit.Tested;
|
||||||
|
|
||||||
|
public class DartClientOptionsTest extends AbstractOptionsTest {
|
||||||
|
|
||||||
|
@Tested
|
||||||
|
private DartClientCodegen clientCodegen;
|
||||||
|
|
||||||
|
public DartClientOptionsTest() {
|
||||||
|
super(new DartClientOptionsProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CodegenConfig getCodegenConfig() {
|
||||||
|
return clientCodegen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Override
|
||||||
|
protected void setExpectations() {
|
||||||
|
new Expectations(clientCodegen) {{
|
||||||
|
clientCodegen.setSortParamsByRequiredFlag(Boolean.valueOf(DartClientOptionsProvider.SORT_PARAMS_VALUE));
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setBrowserClient(Boolean.valueOf(DartClientOptionsProvider.BROWSER_CLIENT_VALUE));
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setPubName(DartClientOptionsProvider.PUB_NAME_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setPubVersion(DartClientOptionsProvider.PUB_VERSION_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setPubDescription(DartClientOptionsProvider.PUB_DESCRIPTION_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setSourceFolder(DartClientOptionsProvider.SOURCE_FOLDER_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setUseEnumExtension(Boolean.valueOf(DartClientOptionsProvider.USE_ENUM_EXTENSION));
|
||||||
|
times = 1;
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package org.openapitools.codegen.elixir;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.AbstractOptionsTest;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.languages.ElixirClientCodegen;
|
||||||
|
import org.openapitools.codegen.options.ElixirClientOptionsProvider;
|
||||||
|
import mockit.Expectations;
|
||||||
|
import mockit.Tested;
|
||||||
|
|
||||||
|
public class ElixirClientOptionsTest extends AbstractOptionsTest {
|
||||||
|
|
||||||
|
@Tested
|
||||||
|
private ElixirClientCodegen clientCodegen;
|
||||||
|
|
||||||
|
public ElixirClientOptionsTest() {
|
||||||
|
super(new ElixirClientOptionsProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CodegenConfig getCodegenConfig() {
|
||||||
|
return clientCodegen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Override
|
||||||
|
protected void setExpectations() {
|
||||||
|
new Expectations(clientCodegen) {{
|
||||||
|
// TODO
|
||||||
|
clientCodegen.setModuleName(ElixirClientOptionsProvider.INVOKER_PACKAGE_VALUE);
|
||||||
|
times = 1;
|
||||||
|
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package org.openapitools.codegen.lumen;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.AbstractOptionsTest;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.languages.LumenServerCodegen;
|
||||||
|
import org.openapitools.codegen.options.LumenServerOptionsProvider;
|
||||||
|
|
||||||
|
import mockit.Expectations;
|
||||||
|
import mockit.Tested;
|
||||||
|
|
||||||
|
public class LumenServerOptionsTest extends AbstractOptionsTest {
|
||||||
|
|
||||||
|
@Tested
|
||||||
|
private LumenServerCodegen clientCodegen;
|
||||||
|
|
||||||
|
public LumenServerOptionsTest() {
|
||||||
|
super(new LumenServerOptionsProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CodegenConfig getCodegenConfig() {
|
||||||
|
return clientCodegen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Override
|
||||||
|
protected void setExpectations() {
|
||||||
|
new Expectations(clientCodegen) {{
|
||||||
|
clientCodegen.setSortParamsByRequiredFlag(Boolean.valueOf(LumenServerOptionsProvider.SORT_PARAMS_VALUE));
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setParameterNamingConvention(LumenServerOptionsProvider.VARIABLE_NAMING_CONVENTION_VALUE);
|
||||||
|
clientCodegen.setModelPackage(LumenServerOptionsProvider.MODEL_PACKAGE_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setApiPackage(LumenServerOptionsProvider.API_PACKAGE_VALUE);
|
||||||
|
times = 1;
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setInvokerPackage(LumenServerOptionsProvider.INVOKER_PACKAGE_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setPackagePath(LumenServerOptionsProvider.PACKAGE_PATH_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setSrcBasePath(LumenServerOptionsProvider.SRC_BASE_PATH_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setGitUserId(LumenServerOptionsProvider.GIT_USER_ID_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setGitRepoId(LumenServerOptionsProvider.GIT_REPO_ID_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setArtifactVersion(LumenServerOptionsProvider.ARTIFACT_VERSION_VALUE);
|
||||||
|
times = 1;
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package org.openapitools.codegen.python;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.AbstractOptionsTest;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.languages.PythonClientCodegen;
|
||||||
|
import org.openapitools.codegen.options.PythonClientOptionsProvider;
|
||||||
|
|
||||||
|
import mockit.Expectations;
|
||||||
|
import mockit.Tested;
|
||||||
|
|
||||||
|
public class PythonClientOptionsTest extends AbstractOptionsTest {
|
||||||
|
|
||||||
|
@Tested
|
||||||
|
private PythonClientCodegen clientCodegen;
|
||||||
|
|
||||||
|
public PythonClientOptionsTest() {
|
||||||
|
super(new PythonClientOptionsProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CodegenConfig getCodegenConfig() {
|
||||||
|
return clientCodegen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Override
|
||||||
|
protected void setExpectations() {
|
||||||
|
new Expectations(clientCodegen) {{
|
||||||
|
clientCodegen.setPackageName(PythonClientOptionsProvider.PACKAGE_NAME_VALUE);
|
||||||
|
clientCodegen.setProjectName(PythonClientOptionsProvider.PROJECT_NAME_VALUE);
|
||||||
|
clientCodegen.setPackageVersion(PythonClientOptionsProvider.PACKAGE_VERSION_VALUE);
|
||||||
|
clientCodegen.setPackageUrl(PythonClientOptionsProvider.PACKAGE_URL_VALUE);
|
||||||
|
// clientCodegen.setLibrary(PythonClientCodegen.DEFAULT_LIBRARY);
|
||||||
|
times = 1;
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,275 @@
|
|||||||
|
package org.openapitools.codegen.python;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.CodegenModel;
|
||||||
|
import org.openapitools.codegen.CodegenOperation;
|
||||||
|
import org.openapitools.codegen.CodegenProperty;
|
||||||
|
import org.openapitools.codegen.DefaultCodegen;
|
||||||
|
import org.openapitools.codegen.languages.PythonClientCodegen;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.Operation;
|
||||||
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
import io.swagger.v3.parser.OpenAPIV3Parser;
|
||||||
|
import io.swagger.v3.parser.util.SchemaTypeUtil;
|
||||||
|
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
import org.testng.annotations.ITestAnnotation;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@SuppressWarnings("static-method")
|
||||||
|
public class PythonTest {
|
||||||
|
|
||||||
|
@Test(description = "convert a python model with dots")
|
||||||
|
public void modelTest() {
|
||||||
|
final OpenAPI openAPI= new OpenAPIV3Parser().read("src/test/resources/2_0/v1beta3.json");
|
||||||
|
final DefaultCodegen codegen = new PythonClientCodegen();
|
||||||
|
|
||||||
|
final CodegenModel simpleName = codegen.fromModel("v1beta3.Binding", openAPI.getComponents().getSchemas().get("v1beta3.Binding"));
|
||||||
|
Assert.assertEquals(simpleName.name, "v1beta3.Binding");
|
||||||
|
Assert.assertEquals(simpleName.classname, "V1beta3Binding");
|
||||||
|
Assert.assertEquals(simpleName.classVarName, "v1beta3_binding");
|
||||||
|
|
||||||
|
final CodegenModel compoundName = codegen.fromModel("v1beta3.ComponentStatus", openAPI.getComponents().getSchemas().get("v1beta3.ComponentStatus"));
|
||||||
|
Assert.assertEquals(compoundName.name, "v1beta3.ComponentStatus");
|
||||||
|
Assert.assertEquals(compoundName.classname, "V1beta3ComponentStatus");
|
||||||
|
Assert.assertEquals(compoundName.classVarName, "v1beta3_component_status");
|
||||||
|
|
||||||
|
final String path = "/api/v1beta3/namespaces/{namespaces}/bindings";
|
||||||
|
final Operation operation = openAPI.getPaths().get(path).getPost();
|
||||||
|
final CodegenOperation codegenOperation = codegen.fromOperation(path, "get", operation, openAPI.getComponents().getSchemas());
|
||||||
|
Assert.assertEquals(codegenOperation.returnType, "V1beta3Binding");
|
||||||
|
Assert.assertEquals(codegenOperation.returnBaseType, "V1beta3Binding");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(description = "convert a simple java model")
|
||||||
|
public void simpleModelTest() {
|
||||||
|
final Schema schema = new Schema()
|
||||||
|
.description("a sample model")
|
||||||
|
.addProperties("id", new IntegerSchema().format(SchemaTypeUtil.INTEGER64_FORMAT))
|
||||||
|
.addProperties("name", new StringSchema())
|
||||||
|
.addProperties("createdAt", new DateTimeSchema())
|
||||||
|
.addRequiredItem("id")
|
||||||
|
.addRequiredItem("name");
|
||||||
|
final DefaultCodegen codegen = new PythonClientCodegen();
|
||||||
|
final CodegenModel cm = codegen.fromModel("sample", schema);
|
||||||
|
|
||||||
|
Assert.assertEquals(cm.name, "sample");
|
||||||
|
Assert.assertEquals(cm.classname, "Sample");
|
||||||
|
Assert.assertEquals(cm.description, "a sample model");
|
||||||
|
Assert.assertEquals(cm.vars.size(), 3);
|
||||||
|
|
||||||
|
final CodegenProperty property1 = cm.vars.get(0);
|
||||||
|
Assert.assertEquals(property1.baseName, "id");
|
||||||
|
Assert.assertEquals(property1.datatype, "int");
|
||||||
|
Assert.assertEquals(property1.name, "id");
|
||||||
|
Assert.assertNull(property1.defaultValue);
|
||||||
|
Assert.assertEquals(property1.baseType, "int");
|
||||||
|
Assert.assertTrue(property1.hasMore);
|
||||||
|
Assert.assertTrue(property1.required);
|
||||||
|
Assert.assertTrue(property1.isPrimitiveType);
|
||||||
|
Assert.assertTrue(property1.isNotContainer);
|
||||||
|
|
||||||
|
final CodegenProperty property2 = cm.vars.get(1);
|
||||||
|
Assert.assertEquals(property2.baseName, "name");
|
||||||
|
Assert.assertEquals(property2.datatype, "str");
|
||||||
|
Assert.assertEquals(property2.name, "name");
|
||||||
|
Assert.assertNull(property2.defaultValue);
|
||||||
|
Assert.assertEquals(property2.baseType, "str");
|
||||||
|
Assert.assertTrue(property2.hasMore);
|
||||||
|
Assert.assertTrue(property2.required);
|
||||||
|
Assert.assertTrue(property2.isPrimitiveType);
|
||||||
|
Assert.assertTrue(property2.isNotContainer);
|
||||||
|
|
||||||
|
final CodegenProperty property3 = cm.vars.get(2);
|
||||||
|
Assert.assertEquals(property3.baseName, "createdAt");
|
||||||
|
Assert.assertEquals(property3.datatype, "datetime");
|
||||||
|
Assert.assertEquals(property3.name, "created_at");
|
||||||
|
Assert.assertNull(property3.defaultValue);
|
||||||
|
Assert.assertEquals(property3.baseType, "datetime");
|
||||||
|
Assert.assertFalse(property3.hasMore);
|
||||||
|
Assert.assertFalse(property3.required);
|
||||||
|
Assert.assertTrue(property3.isNotContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(description = "convert a model with list property")
|
||||||
|
public void listPropertyTest() {
|
||||||
|
final Schema model = new Schema()
|
||||||
|
.description("a sample model")
|
||||||
|
.addProperties("id", new IntegerSchema().format(SchemaTypeUtil.INTEGER64_FORMAT))
|
||||||
|
.addProperties("urls", new ArraySchema()
|
||||||
|
.items(new StringSchema()))
|
||||||
|
.addRequiredItem("id");
|
||||||
|
final DefaultCodegen codegen = new PythonClientCodegen();
|
||||||
|
final CodegenModel cm = codegen.fromModel("sample", model);
|
||||||
|
|
||||||
|
Assert.assertEquals(cm.name, "sample");
|
||||||
|
Assert.assertEquals(cm.classname, "Sample");
|
||||||
|
Assert.assertEquals(cm.description, "a sample model");
|
||||||
|
Assert.assertEquals(cm.vars.size(), 2);
|
||||||
|
|
||||||
|
final CodegenProperty property1 = cm.vars.get(0);
|
||||||
|
Assert.assertEquals(property1.baseName, "id");
|
||||||
|
Assert.assertEquals(property1.datatype, "int");
|
||||||
|
Assert.assertEquals(property1.name, "id");
|
||||||
|
Assert.assertNull(property1.defaultValue);
|
||||||
|
Assert.assertEquals(property1.baseType, "int");
|
||||||
|
Assert.assertTrue(property1.hasMore);
|
||||||
|
Assert.assertTrue(property1.required);
|
||||||
|
Assert.assertTrue(property1.isPrimitiveType);
|
||||||
|
Assert.assertTrue(property1.isNotContainer);
|
||||||
|
|
||||||
|
final CodegenProperty property2 = cm.vars.get(1);
|
||||||
|
Assert.assertEquals(property2.baseName, "urls");
|
||||||
|
Assert.assertEquals(property2.datatype, "list[str]");
|
||||||
|
Assert.assertEquals(property2.name, "urls");
|
||||||
|
Assert.assertNull(property2.defaultValue);
|
||||||
|
Assert.assertEquals(property2.baseType, "list");
|
||||||
|
Assert.assertFalse(property2.hasMore);
|
||||||
|
Assert.assertEquals(property2.containerType, "array");
|
||||||
|
Assert.assertFalse(property2.required);
|
||||||
|
Assert.assertTrue(property2.isPrimitiveType);
|
||||||
|
Assert.assertTrue(property2.isContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(description = "convert a model with a map property")
|
||||||
|
public void mapPropertyTest() {
|
||||||
|
final Schema model = new Schema()
|
||||||
|
.description("a sample model")
|
||||||
|
.addProperties("translations", new MapSchema()
|
||||||
|
.additionalProperties(new StringSchema()))
|
||||||
|
.addRequiredItem("id");
|
||||||
|
final DefaultCodegen codegen = new PythonClientCodegen();
|
||||||
|
final CodegenModel cm = codegen.fromModel("sample", model);
|
||||||
|
|
||||||
|
Assert.assertEquals(cm.name, "sample");
|
||||||
|
Assert.assertEquals(cm.classname, "Sample");
|
||||||
|
Assert.assertEquals(cm.description, "a sample model");
|
||||||
|
Assert.assertEquals(cm.vars.size(), 1);
|
||||||
|
|
||||||
|
final CodegenProperty property1 = cm.vars.get(0);
|
||||||
|
Assert.assertEquals(property1.baseName, "translations");
|
||||||
|
Assert.assertEquals(property1.datatype, "dict(str, str)");
|
||||||
|
Assert.assertEquals(property1.name, "translations");
|
||||||
|
Assert.assertEquals(property1.baseType, "dict");
|
||||||
|
Assert.assertEquals(property1.containerType, "map");
|
||||||
|
Assert.assertFalse(property1.required);
|
||||||
|
Assert.assertTrue(property1.isContainer);
|
||||||
|
Assert.assertTrue(property1.isPrimitiveType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(description = "convert a model with complex property")
|
||||||
|
public void complexPropertyTest() {
|
||||||
|
final Schema model = new Schema()
|
||||||
|
.description("a sample model")
|
||||||
|
.addProperties("children", new Schema().$ref("#/definitions/Children"));
|
||||||
|
final DefaultCodegen codegen = new PythonClientCodegen();
|
||||||
|
final CodegenModel cm = codegen.fromModel("sample", model);
|
||||||
|
|
||||||
|
Assert.assertEquals(cm.name, "sample");
|
||||||
|
Assert.assertEquals(cm.classname, "Sample");
|
||||||
|
Assert.assertEquals(cm.description, "a sample model");
|
||||||
|
Assert.assertEquals(cm.vars.size(), 1);
|
||||||
|
|
||||||
|
final CodegenProperty property1 = cm.vars.get(0);
|
||||||
|
Assert.assertEquals(property1.baseName, "children");
|
||||||
|
Assert.assertEquals(property1.datatype, "Children");
|
||||||
|
Assert.assertEquals(property1.name, "children");
|
||||||
|
Assert.assertEquals(property1.baseType, "Children");
|
||||||
|
Assert.assertFalse(property1.required);
|
||||||
|
Assert.assertTrue(property1.isNotContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(description = "convert a model with complex list property")
|
||||||
|
public void complexListPropertyTest() {
|
||||||
|
final Schema model = new Schema()
|
||||||
|
.description("a sample model")
|
||||||
|
.addProperties("children", new ArraySchema()
|
||||||
|
.items(new Schema().$ref("#/definitions/Children")));
|
||||||
|
final DefaultCodegen codegen = new PythonClientCodegen();
|
||||||
|
final CodegenModel cm = codegen.fromModel("sample", model);
|
||||||
|
|
||||||
|
Assert.assertEquals(cm.name, "sample");
|
||||||
|
Assert.assertEquals(cm.classname, "Sample");
|
||||||
|
Assert.assertEquals(cm.description, "a sample model");
|
||||||
|
Assert.assertEquals(cm.vars.size(), 1);
|
||||||
|
|
||||||
|
final CodegenProperty property1 = cm.vars.get(0);
|
||||||
|
Assert.assertEquals(property1.baseName, "children");
|
||||||
|
Assert.assertEquals(property1.complexType, "Children");
|
||||||
|
Assert.assertEquals(property1.datatype, "list[Children]");
|
||||||
|
Assert.assertEquals(property1.name, "children");
|
||||||
|
Assert.assertEquals(property1.baseType, "list");
|
||||||
|
Assert.assertEquals(property1.containerType, "array");
|
||||||
|
Assert.assertFalse(property1.required);
|
||||||
|
Assert.assertTrue(property1.isContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(description = "convert a model with complex map property")
|
||||||
|
public void complexMapPropertyTest() {
|
||||||
|
final Schema model = new Schema()
|
||||||
|
.description("a sample model")
|
||||||
|
.addProperties("children", new MapSchema()
|
||||||
|
.additionalProperties(new Schema().$ref("#/definitions/Children")));
|
||||||
|
final DefaultCodegen codegen = new PythonClientCodegen();
|
||||||
|
final CodegenModel cm = codegen.fromModel("sample", model);
|
||||||
|
|
||||||
|
Assert.assertEquals(cm.name, "sample");
|
||||||
|
Assert.assertEquals(cm.classname, "Sample");
|
||||||
|
Assert.assertEquals(cm.description, "a sample model");
|
||||||
|
Assert.assertEquals(cm.vars.size(), 1);
|
||||||
|
Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("Children")).size(), 1);
|
||||||
|
|
||||||
|
final CodegenProperty property1 = cm.vars.get(0);
|
||||||
|
Assert.assertEquals(property1.baseName, "children");
|
||||||
|
Assert.assertEquals(property1.complexType, "Children");
|
||||||
|
Assert.assertEquals(property1.datatype, "dict(str, Children)");
|
||||||
|
Assert.assertEquals(property1.name, "children");
|
||||||
|
Assert.assertEquals(property1.baseType, "dict");
|
||||||
|
Assert.assertEquals(property1.containerType, "map");
|
||||||
|
Assert.assertFalse(property1.required);
|
||||||
|
Assert.assertTrue(property1.isContainer);
|
||||||
|
Assert.assertFalse(property1.isNotContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// should not start with 'null'. need help from the community to investigate further
|
||||||
|
@Test(enabled = false, description = "convert an array model")
|
||||||
|
public void arrayModelTest() {
|
||||||
|
final Schema model = new ArraySchema()
|
||||||
|
//.description()
|
||||||
|
.items(new Schema().$ref("#/definitions/Children"))
|
||||||
|
.description("an array model");
|
||||||
|
final DefaultCodegen codegen = new PythonClientCodegen();
|
||||||
|
final CodegenModel cm = codegen.fromModel("sample", model);
|
||||||
|
|
||||||
|
Assert.assertEquals(cm.name, "sample");
|
||||||
|
Assert.assertEquals(cm.classname, "Sample");
|
||||||
|
Assert.assertEquals(cm.description, "an array model");
|
||||||
|
Assert.assertEquals(cm.vars.size(), 0);
|
||||||
|
Assert.assertEquals(cm.parent, "null<Children>");
|
||||||
|
Assert.assertEquals(cm.imports.size(), 1);
|
||||||
|
Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("Children")).size(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// should not start with 'null'. need help from the community to investigate further
|
||||||
|
@Test(enabled = false, description = "convert an map model")
|
||||||
|
public void mapModelTest() {
|
||||||
|
final Schema model = new Schema()
|
||||||
|
.description("a map model")
|
||||||
|
.additionalProperties(new Schema().$ref("#/definitions/Children"));
|
||||||
|
final DefaultCodegen codegen = new PythonClientCodegen();
|
||||||
|
final CodegenModel cm = codegen.fromModel("sample", model);
|
||||||
|
|
||||||
|
Assert.assertEquals(cm.name, "sample");
|
||||||
|
Assert.assertEquals(cm.classname, "Sample");
|
||||||
|
Assert.assertEquals(cm.description, "a map model");
|
||||||
|
Assert.assertEquals(cm.vars.size(), 0);
|
||||||
|
Assert.assertEquals(cm.parent, "null<String, Children>");
|
||||||
|
Assert.assertEquals(cm.imports.size(), 2); // TODO: need to verify
|
||||||
|
Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("Children")).size(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package org.openapitools.codegen.ruby;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.ClientOpts;
|
||||||
|
import org.openapitools.codegen.ClientOptInput;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.DefaultGenerator;
|
||||||
|
import org.openapitools.codegen.languages.RubyClientCodegen;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.Operation;
|
||||||
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
import io.swagger.v3.parser.OpenAPIV3Parser;
|
||||||
|
import io.swagger.v3.parser.util.SchemaTypeUtil;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.junit.rules.TemporaryFolder;
|
||||||
|
import org.testng.annotations.AfterMethod;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for RubyClientCodegen-generated templates
|
||||||
|
*/
|
||||||
|
public class RubyClientCodegenTest {
|
||||||
|
|
||||||
|
public TemporaryFolder folder = new TemporaryFolder();
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
folder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterMethod
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
folder.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGenerateRubyClientWithHtmlEntity() throws Exception {
|
||||||
|
final File output = folder.getRoot();
|
||||||
|
|
||||||
|
final OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/2_0/pathWithHtmlEntity.yaml");
|
||||||
|
CodegenConfig codegenConfig = new RubyClientCodegen();
|
||||||
|
codegenConfig.setOutputDir(output.getAbsolutePath());
|
||||||
|
|
||||||
|
ClientOptInput clientOptInput = new ClientOptInput().opts(new ClientOpts()).openAPI(openAPI).config(codegenConfig);
|
||||||
|
|
||||||
|
DefaultGenerator generator = new DefaultGenerator();
|
||||||
|
List<File> files = generator.opts(clientOptInput).generate();
|
||||||
|
boolean apiFileGenerated = false;
|
||||||
|
for (File file : files) {
|
||||||
|
if (file.getName().equals("default_api.rb")) {
|
||||||
|
apiFileGenerated = true;
|
||||||
|
// Ruby client should set the path unescaped in the api file
|
||||||
|
assertTrue(FileUtils.readFileToString(file, StandardCharsets.UTF_8).contains("local_var_path = '/foo=bar'"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!apiFileGenerated) {
|
||||||
|
fail("Default api file is not generated!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package org.openapitools.codegen.ruby;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.AbstractOptionsTest;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.languages.RubyClientCodegen;
|
||||||
|
import org.openapitools.codegen.options.RubyClientOptionsProvider;
|
||||||
|
|
||||||
|
import mockit.Expectations;
|
||||||
|
import mockit.Tested;
|
||||||
|
|
||||||
|
public class RubyClientOptionsTest extends AbstractOptionsTest {
|
||||||
|
|
||||||
|
@Tested
|
||||||
|
private RubyClientCodegen clientCodegen;
|
||||||
|
|
||||||
|
public RubyClientOptionsTest() {
|
||||||
|
super(new RubyClientOptionsProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CodegenConfig getCodegenConfig() {
|
||||||
|
return clientCodegen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Override
|
||||||
|
protected void setExpectations() {
|
||||||
|
new Expectations(clientCodegen) {{
|
||||||
|
clientCodegen.setGemName(RubyClientOptionsProvider.GEM_NAME_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setModuleName(RubyClientOptionsProvider.MODULE_NAME_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setGemVersion(RubyClientOptionsProvider.GEM_VERSION_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setGemLicense(RubyClientOptionsProvider.GEM_LICENSE_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setGemRequiredRubyVersion(RubyClientOptionsProvider.GEM_REQUIRED_RUBY_VERSION_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setGemHomepage(RubyClientOptionsProvider.GEM_HOMEPAGE_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setGemDescription(RubyClientOptionsProvider.GEM_DESCRIPTION_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setGemSummary(RubyClientOptionsProvider.GEM_SUMMARY_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setGemAuthor(RubyClientOptionsProvider.GEM_AUTHOR_VALUE);
|
||||||
|
times = 1;
|
||||||
|
clientCodegen.setGemAuthorEmail(RubyClientOptionsProvider.GEM_AUTHOR_EMAIL_VALUE);
|
||||||
|
times = 1;
|
||||||
|
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package org.openapitools.codegen.silex;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.AbstractOptionsTest;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.languages.SilexServerCodegen;
|
||||||
|
import org.openapitools.codegen.options.SilexServerOptionsProvider;
|
||||||
|
|
||||||
|
import mockit.Expectations;
|
||||||
|
import mockit.Tested;
|
||||||
|
|
||||||
|
public class SilexServerOptionsTest extends AbstractOptionsTest {
|
||||||
|
|
||||||
|
@Tested
|
||||||
|
private SilexServerCodegen clientCodegen;
|
||||||
|
|
||||||
|
public SilexServerOptionsTest() {
|
||||||
|
super(new SilexServerOptionsProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CodegenConfig getCodegenConfig() {
|
||||||
|
return clientCodegen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Override
|
||||||
|
protected void setExpectations() {
|
||||||
|
new Expectations(clientCodegen) {{
|
||||||
|
clientCodegen.setSortParamsByRequiredFlag(Boolean.valueOf(SilexServerOptionsProvider.SORT_PARAMS_VALUE));
|
||||||
|
times = 1;
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package org.openapitools.codegen.sinatra;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.AbstractOptionsTest;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.languages.SinatraServerCodegen;
|
||||||
|
import org.openapitools.codegen.options.SinatraServerOptionsProvider;
|
||||||
|
|
||||||
|
import mockit.Expectations;
|
||||||
|
import mockit.Tested;
|
||||||
|
|
||||||
|
public class SinatraServerOptionsTest extends AbstractOptionsTest {
|
||||||
|
|
||||||
|
@Tested
|
||||||
|
private SinatraServerCodegen clientCodegen;
|
||||||
|
|
||||||
|
public SinatraServerOptionsTest() {
|
||||||
|
super(new SinatraServerOptionsProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CodegenConfig getCodegenConfig() {
|
||||||
|
return clientCodegen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Override
|
||||||
|
protected void setExpectations() {
|
||||||
|
new Expectations(clientCodegen) {{
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package org.openapitools.codegen.slim;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.AbstractOptionsTest;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.languages.SlimFrameworkServerCodegen;
|
||||||
|
import org.openapitools.codegen.options.SlimFrameworkServerOptionsProvider;
|
||||||
|
|
||||||
|
import mockit.Expectations;
|
||||||
|
import mockit.Tested;
|
||||||
|
|
||||||
|
public class SlimFrameworkServerOptionsTest extends AbstractOptionsTest {
|
||||||
|
|
||||||
|
@Tested
|
||||||
|
private SlimFrameworkServerCodegen clientCodegen;
|
||||||
|
|
||||||
|
public SlimFrameworkServerOptionsTest() {
|
||||||
|
super(new SlimFrameworkServerOptionsProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CodegenConfig getCodegenConfig() {
|
||||||
|
return clientCodegen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Override
|
||||||
|
protected void setExpectations() {
|
||||||
|
new Expectations(clientCodegen) {{
|
||||||
|
clientCodegen.setSortParamsByRequiredFlag(Boolean.valueOf(SlimFrameworkServerOptionsProvider.SORT_PARAMS_VALUE));
|
||||||
|
times = 1;
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package org.openapitools.codegen.options;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
import org.openapitools.codegen.languages.DartClientCodegen;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class DartClientOptionsProvider implements OptionsProvider {
|
||||||
|
public static final String SORT_PARAMS_VALUE = "true";
|
||||||
|
public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true";
|
||||||
|
public static final String BROWSER_CLIENT_VALUE = "true";
|
||||||
|
public static final String PUB_NAME_VALUE = "swagger";
|
||||||
|
public static final String PUB_VERSION_VALUE = "1.0.0-SNAPSHOT";
|
||||||
|
public static final String PUB_DESCRIPTION_VALUE = "Swagger API client dart";
|
||||||
|
public static final String SOURCE_FOLDER_VALUE = "src";
|
||||||
|
public static final String USE_ENUM_EXTENSION = "true";
|
||||||
|
public static final String ALLOW_UNICODE_IDENTIFIERS_VALUE = "false";
|
||||||
|
public static final String PREPEND_FORM_OR_BODY_PARAMETERS_VALUE = "true";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLanguage() {
|
||||||
|
return "dart";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> createOptions() {
|
||||||
|
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
|
||||||
|
return builder.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_VALUE)
|
||||||
|
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE)
|
||||||
|
.put(DartClientCodegen.BROWSER_CLIENT, BROWSER_CLIENT_VALUE)
|
||||||
|
.put(DartClientCodegen.PUB_NAME, PUB_NAME_VALUE)
|
||||||
|
.put(DartClientCodegen.PUB_VERSION, PUB_VERSION_VALUE)
|
||||||
|
.put(DartClientCodegen.PUB_DESCRIPTION, PUB_DESCRIPTION_VALUE)
|
||||||
|
.put(CodegenConstants.SOURCE_FOLDER, SOURCE_FOLDER_VALUE)
|
||||||
|
.put(DartClientCodegen.USE_ENUM_EXTENSION, USE_ENUM_EXTENSION)
|
||||||
|
.put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, ALLOW_UNICODE_IDENTIFIERS_VALUE)
|
||||||
|
.put(CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS, PREPEND_FORM_OR_BODY_PARAMETERS_VALUE)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isServer() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package org.openapitools.codegen.options;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ElixirClientOptionsProvider implements OptionsProvider {
|
||||||
|
public static final String INVOKER_PACKAGE_VALUE = "Yay.Pets";
|
||||||
|
public static final String PREPEND_FORM_OR_BODY_PARAMETERS_VALUE = "true";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLanguage() {
|
||||||
|
return "elixir";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> createOptions() {
|
||||||
|
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
|
||||||
|
return builder
|
||||||
|
.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, "false")
|
||||||
|
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, "false")
|
||||||
|
.put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, "false")
|
||||||
|
.put(CodegenConstants.INVOKER_PACKAGE, "Yay.Pets")
|
||||||
|
.put("licenseHeader", "# Copyright 2017 Me\n#\n# Licensed under the Apache License")
|
||||||
|
.put(CodegenConstants.PACKAGE_NAME, "yay_pets")
|
||||||
|
.put(CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS, PREPEND_FORM_OR_BODY_PARAMETERS_VALUE)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isServer() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package org.openapitools.codegen.options;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
import org.openapitools.codegen.languages.AbstractPhpCodegen;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class LumenServerOptionsProvider implements OptionsProvider {
|
||||||
|
public static final String MODEL_PACKAGE_VALUE = "package";
|
||||||
|
public static final String API_PACKAGE_VALUE = "apiPackage";
|
||||||
|
public static final String SORT_PARAMS_VALUE = "false";
|
||||||
|
public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true";
|
||||||
|
public static final String VARIABLE_NAMING_CONVENTION_VALUE = "snake_case";
|
||||||
|
public static final String INVOKER_PACKAGE_VALUE = "lumen";
|
||||||
|
public static final String PACKAGE_PATH_VALUE = "php";
|
||||||
|
public static final String SRC_BASE_PATH_VALUE = "libPhp";
|
||||||
|
public static final String GIT_USER_ID_VALUE = "gitSwaggerPhp";
|
||||||
|
public static final String GIT_REPO_ID_VALUE = "git-swagger-php";
|
||||||
|
public static final String ARTIFACT_VERSION_VALUE = "1.0.0-SNAPSHOT";
|
||||||
|
public static final String ALLOW_UNICODE_IDENTIFIERS_VALUE = "false";
|
||||||
|
public static final String PREPEND_FORM_OR_BODY_PARAMETERS_VALUE = "true";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLanguage() {
|
||||||
|
return "php-lumen";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> createOptions() {
|
||||||
|
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
|
||||||
|
return builder.put(CodegenConstants.MODEL_PACKAGE, MODEL_PACKAGE_VALUE)
|
||||||
|
.put(AbstractPhpCodegen.VARIABLE_NAMING_CONVENTION, VARIABLE_NAMING_CONVENTION_VALUE)
|
||||||
|
.put(AbstractPhpCodegen.PACKAGE_PATH, PACKAGE_PATH_VALUE)
|
||||||
|
.put(AbstractPhpCodegen.SRC_BASE_PATH, SRC_BASE_PATH_VALUE)
|
||||||
|
.put(CodegenConstants.API_PACKAGE, API_PACKAGE_VALUE)
|
||||||
|
.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_VALUE)
|
||||||
|
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE)
|
||||||
|
.put(CodegenConstants.INVOKER_PACKAGE, INVOKER_PACKAGE_VALUE)
|
||||||
|
.put(CodegenConstants.GIT_USER_ID, GIT_USER_ID_VALUE)
|
||||||
|
.put(CodegenConstants.GIT_REPO_ID, GIT_REPO_ID_VALUE)
|
||||||
|
.put(CodegenConstants.ARTIFACT_VERSION, ARTIFACT_VERSION_VALUE)
|
||||||
|
.put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, ALLOW_UNICODE_IDENTIFIERS_VALUE)
|
||||||
|
.put(CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS, PREPEND_FORM_OR_BODY_PARAMETERS_VALUE)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isServer() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package org.openapitools.codegen.options;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
import org.openapitools.codegen.languages.PythonClientCodegen;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class PythonClientOptionsProvider implements OptionsProvider {
|
||||||
|
public static final String PACKAGE_NAME_VALUE = "swagger_client_python";
|
||||||
|
public static final String PROJECT_NAME_VALUE = "swagger-client-python";
|
||||||
|
public static final String PACKAGE_VERSION_VALUE = "1.0.0-SNAPSHOT";
|
||||||
|
public static final String PACKAGE_URL_VALUE = "";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLanguage() {
|
||||||
|
return "python";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> createOptions() {
|
||||||
|
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
|
||||||
|
return builder.put(PythonClientCodegen.PACKAGE_URL, PACKAGE_URL_VALUE)
|
||||||
|
.put(CodegenConstants.PACKAGE_NAME, PACKAGE_NAME_VALUE)
|
||||||
|
.put(CodegenConstants.PROJECT_NAME, PROJECT_NAME_VALUE)
|
||||||
|
.put(CodegenConstants.PACKAGE_VERSION, PACKAGE_VERSION_VALUE)
|
||||||
|
.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, "true")
|
||||||
|
.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "true")
|
||||||
|
.put(CodegenConstants.LIBRARY, "urllib3")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isServer() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package org.openapitools.codegen.options;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
import org.openapitools.codegen.languages.RubyClientCodegen;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class RubyClientOptionsProvider implements OptionsProvider {
|
||||||
|
public static final String GEM_NAME_VALUE = "swagger_client_ruby";
|
||||||
|
public static final String MODULE_NAME_VALUE = "SwaggerClientRuby";
|
||||||
|
public static final String GEM_VERSION_VALUE = "1.0.0-SNAPSHOT";
|
||||||
|
public static final String SORT_PARAMS_VALUE = "false";
|
||||||
|
public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true";
|
||||||
|
public static final String GEM_LICENSE_VALUE = "MIT";
|
||||||
|
public static final String GEM_REQUIRED_RUBY_VERSION_VALUE = ">= 1.9";
|
||||||
|
public static final String GEM_HOMEPAGE_VALUE = "homepage";
|
||||||
|
public static final String GEM_SUMMARY_VALUE = "summary";
|
||||||
|
public static final String GEM_DESCRIPTION_VALUE = "description";
|
||||||
|
public static final String GEM_AUTHOR_VALUE = "foo";
|
||||||
|
public static final String GEM_AUTHOR_EMAIL_VALUE = "foo";
|
||||||
|
public static final String ALLOW_UNICODE_IDENTIFIERS_VALUE = "false";
|
||||||
|
public static final String PREPEND_FORM_OR_BODY_PARAMETERS_VALUE = "true";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLanguage() {
|
||||||
|
return "ruby";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> createOptions() {
|
||||||
|
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
|
||||||
|
return builder.put(RubyClientCodegen.GEM_NAME, GEM_NAME_VALUE)
|
||||||
|
.put(RubyClientCodegen.MODULE_NAME, MODULE_NAME_VALUE)
|
||||||
|
.put(RubyClientCodegen.GEM_VERSION, GEM_VERSION_VALUE)
|
||||||
|
.put(RubyClientCodegen.GEM_LICENSE, GEM_LICENSE_VALUE)
|
||||||
|
.put(RubyClientCodegen.GEM_REQUIRED_RUBY_VERSION, GEM_REQUIRED_RUBY_VERSION_VALUE)
|
||||||
|
.put(RubyClientCodegen.GEM_DESCRIPTION, GEM_DESCRIPTION_VALUE)
|
||||||
|
.put(RubyClientCodegen.GEM_HOMEPAGE, GEM_HOMEPAGE_VALUE)
|
||||||
|
.put(RubyClientCodegen.GEM_SUMMARY, GEM_SUMMARY_VALUE)
|
||||||
|
.put(RubyClientCodegen.GEM_AUTHOR, GEM_AUTHOR_VALUE)
|
||||||
|
.put(RubyClientCodegen.GEM_AUTHOR_EMAIL, GEM_AUTHOR_EMAIL_VALUE)
|
||||||
|
.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_VALUE)
|
||||||
|
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE)
|
||||||
|
.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "true")
|
||||||
|
.put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, ALLOW_UNICODE_IDENTIFIERS_VALUE)
|
||||||
|
.put(CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS, PREPEND_FORM_OR_BODY_PARAMETERS_VALUE)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isServer() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package org.openapitools.codegen.options;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SilexServerOptionsProvider implements OptionsProvider {
|
||||||
|
public static final String SORT_PARAMS_VALUE = "false";
|
||||||
|
public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true";
|
||||||
|
public static final String ALLOW_UNICODE_IDENTIFIERS_VALUE = "false";
|
||||||
|
public static final String PREPEND_FORM_OR_BODY_PARAMETERS_VALUE = "true";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLanguage() {
|
||||||
|
return "php-silex";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> createOptions() {
|
||||||
|
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
|
||||||
|
return builder.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_VALUE)
|
||||||
|
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE)
|
||||||
|
.put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, ALLOW_UNICODE_IDENTIFIERS_VALUE)
|
||||||
|
.put(CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS, PREPEND_FORM_OR_BODY_PARAMETERS_VALUE)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isServer() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package org.openapitools.codegen.options;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SinatraServerOptionsProvider implements OptionsProvider {
|
||||||
|
@Override
|
||||||
|
public String getLanguage() {
|
||||||
|
return "ruby-sinatra";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> createOptions() {
|
||||||
|
//SinatraServerCodegen doesn't have its own options and base options are cleared
|
||||||
|
return ImmutableMap.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isServer() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package org.openapitools.codegen.options;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SlimFrameworkServerOptionsProvider implements OptionsProvider {
|
||||||
|
public static final String SORT_PARAMS_VALUE = "false";
|
||||||
|
public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true";
|
||||||
|
public static final String ALLOW_UNICODE_IDENTIFIERS_VALUE = "false";
|
||||||
|
public static final String PREPEND_FORM_OR_BODY_PARAMETERS_VALUE = "true";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLanguage() {
|
||||||
|
return "slim";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> createOptions() {
|
||||||
|
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
|
||||||
|
return builder.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_VALUE)
|
||||||
|
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE)
|
||||||
|
.put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, ALLOW_UNICODE_IDENTIFIERS_VALUE)
|
||||||
|
.put(CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS, PREPEND_FORM_OR_BODY_PARAMETERS_VALUE)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isServer() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,18 @@
|
|||||||
---
|
---
|
||||||
swagger: "2.0"
|
swagger: "2.0"
|
||||||
basePath: "/"
|
basePath: /
|
||||||
paths:
|
info:
|
||||||
/foo=bar:
|
description: "Test for response code default"
|
||||||
get:
|
title: "path with html entity test"
|
||||||
parameters: []
|
version: "1.0.0"
|
||||||
responses:
|
paths:
|
||||||
200:
|
/foo=bar:
|
||||||
description: "success"
|
get:
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: "successful operation"
|
||||||
|
default:
|
||||||
|
description: "Internal server error"
|
||||||
|
summary: Test
|
||||||
|
Loading…
x
Reference in New Issue
Block a user