diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractPhpCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractPhpCodegen.java new file mode 100644 index 00000000000..f826f55d82c --- /dev/null +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractPhpCodegen.java @@ -0,0 +1,641 @@ +package io.swagger.codegen.languages; + +import io.swagger.codegen.CliOption; +import io.swagger.codegen.CodegenConfig; +import io.swagger.codegen.CodegenConstants; +import io.swagger.codegen.CodegenOperation; +import io.swagger.codegen.CodegenParameter; +import io.swagger.codegen.CodegenProperty; +import io.swagger.codegen.CodegenType; +import io.swagger.codegen.DefaultCodegen; +import io.swagger.codegen.SupportingFile; +import io.swagger.models.properties.*; + +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 + "/" + apiDirName; + protected String modelDocPath = docsBasePath + "/" + 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( + 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(); + 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 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) { + 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+ "$", ""); + } + + @Override + public String escapeReservedWord(String name) { + return "_" + name; + } + + @Override + public String apiFileFolder() { + return (outputFolder + "/" + toPackagePath(apiPackage, srcBasePath)); + } + + @Override + public String modelFileFolder() { + return (outputFolder + "/" + toPackagePath(modelPackage, srcBasePath)); + } + + @Override + public String apiTestFileFolder() { + return (outputFolder + "/" + getPackagePath() + "/" + testBasePath + "/" + apiDirName); + } + + @Override + public String modelTestFileFolder() { + return (outputFolder + "/" + getPackagePath() + "/" + testBasePath + "/" + modelDirName); + } + + @Override + public String apiDocFileFolder() { + return (outputFolder + "/" + getPackagePath() + "/" + apiDocPath); + } + + @Override + public String modelDocFileFolder() { + return (outputFolder + "/" + getPackagePath() + "/" + modelDocPath); + } + + @Override + public String toModelDocFilename(String name) { + return toModelName(name); + } + + @Override + public String toApiDocFilename(String name) { + return toApiName(name); + } + + @Override + public String getTypeDeclaration(Property p) { + if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + Property inner = ap.getItems(); + return getTypeDeclaration(inner) + "[]"; + } else if (p instanceof MapProperty) { + MapProperty mp = (MapProperty) p; + Property inner = mp.getAdditionalProperties(); + return getSwaggerType(p) + "[string," + getTypeDeclaration(inner) + "]"; + } else if (p instanceof RefProperty) { + 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 getSwaggerType(Property p) { + String swaggerType = super.getSwaggerType(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); + } + + 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(Property p) { + if (p instanceof StringProperty) { + StringProperty dp = (StringProperty) p; + if (dp.getDefault() != null) { + return "'" + dp.getDefault().toString() + "'"; + } + } else if (p instanceof BooleanProperty) { + BooleanProperty dp = (BooleanProperty) p; + if (dp.getDefault() != null) { + return dp.getDefault().toString(); + } + } else if (p instanceof DateProperty) { + // TODO + } else if (p instanceof DateTimeProperty) { + // TODO + } else if (p instanceof DoubleProperty) { + DoubleProperty dp = (DoubleProperty) p; + if (dp.getDefault() != null) { + return dp.getDefault().toString(); + } + } else if (p instanceof FloatProperty) { + FloatProperty dp = (FloatProperty) p; + if (dp.getDefault() != null) { + return dp.getDefault().toString(); + } + } else if (p instanceof IntegerProperty) { + IntegerProperty dp = (IntegerProperty) p; + if (dp.getDefault() != null) { + return dp.getDefault().toString(); + } + } else if (p instanceof LongProperty) { + LongProperty dp = (LongProperty) 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 " + 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) { + // number + if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) { + String varName = new String(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 postProcessModels(Map objs) { + // process enum in models + return postProcessModelsEnum(objs); + } + + @Override + public Map postProcessOperations(Map objs) { + Map operations = (Map) objs.get("operations"); + List operationList = (List) 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("*/", ""); + } + +} diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/LumenServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/LumenServerCodegen.java index bd52bbf9b25..b2a2db3def3 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/LumenServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/LumenServerCodegen.java @@ -10,10 +10,9 @@ import java.util.Map; import java.util.TreeMap; -public class LumenServerCodegen extends DefaultCodegen implements CodegenConfig { - - // source folder where to write the files - protected String sourceFolder = ""; +public class LumenServerCodegen extends AbstractPhpCodegen +{ + @SuppressWarnings("hiding") protected String apiVersion = "1.0.0"; /** @@ -43,47 +42,19 @@ public String getName() { * @return A string value for the help message */ public String getHelp() { - return "Generates a LumenServerCodegen client library."; + return "Generates a LumenServerCodegen server library."; } public LumenServerCodegen() { super(); - // set the output folder here - outputFolder = "lumen"; - String packagePath = ""; - - /** - * 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 - // ".sample"); // 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 - // ".sample"); // the extension for each file to write - - - // no api files - // apiTemplateFiles.clear(); - apiTemplateFiles.put("api.mustache", ".php"); - - // embeddedTemplateDir = templateDir = "slim"; + embeddedTemplateDir = templateDir = "lumen"; /** - * 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. + * packPath */ - templateDir = "lumen"; + invokerPackage = "lumen"; + packagePath = ""; /** * Api Package. Optional, if needed, this can be used in templates @@ -95,14 +66,11 @@ public LumenServerCodegen() { */ modelPackage = "models"; - /** - * Reserved words. Override this with reserved words specific to your language - */ - reservedWords = new HashSet ( - Arrays.asList( - "sample1", // replace with static values - "sample2") - ); + // 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 @@ -115,55 +83,18 @@ public LumenServerCodegen() { * 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, "composer.json")); - supportingFiles.add(new SupportingFile("readme.md", packagePath, "readme.md")); - supportingFiles.add(new SupportingFile("app.php", packagePath + File.separator + "bootstrap", "app.php")); - supportingFiles.add(new SupportingFile("index.php", packagePath + File.separator + "public", "index.php")); - supportingFiles.add(new SupportingFile("User.php", packagePath + File.separator + "app", "User.php")); - supportingFiles.add(new SupportingFile("Kernel.php", packagePath + File.separator + "app" + File.separator + "Console", "Kernel.php")); - supportingFiles.add(new SupportingFile("Handler.php", packagePath + File.separator + "app" + File.separator + "Exceptions", "Handler.php")); - supportingFiles.add(new SupportingFile("routes.mustache", packagePath + File.separator + "app" + File.separator + "Http", "routes.php")); + 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 + "app" + File.separator + "Http" + File.separator + "Controllers" + File.separator, "Controller.php")); - supportingFiles.add(new SupportingFile("Authenticate.php", packagePath + File.separator + "app" + File.separator + "Http" + File.separator + "Middleware" + File.separator, "Authenticate.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")); - /** - * Language Specific Primitives. These types will not trigger imports by - * the client generator - */ - languageSpecificPrimitives = new HashSet( - Arrays.asList( - "Type1", // replace these with your types - "Type2") - ); - } - - /** - * 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 reseved words - * - * @return the escaped term - */ - @Override - public String escapeReservedWord(String name) { - return "_" + name; // add an underscore to the name - } - - /** - * Location to write model files. You can use the modelPackage() as defined when the class is - * instantiated - */ - public String modelFileFolder() { - return outputFolder + "/" + modelPackage().replace('.', File.separatorChar); - } - - /** - * Location to write api files. You can use the apiPackage() as defined when the class is - * instantiated - */ - @Override - public String apiFileFolder() { - return outputFolder + "/" + apiPackage().replace('.', File.separatorChar);//"/app/Http/controllers"; } // override with any special post-processing @@ -185,57 +116,4 @@ public int compare(CodegenOperation lhs, CodegenOperation rhs) { return objs; } - /** - * 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(Property p) { - if(p instanceof ArrayProperty) { - ArrayProperty ap = (ArrayProperty) p; - Property inner = ap.getItems(); - return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]"; - } - else if (p instanceof MapProperty) { - MapProperty mp = (MapProperty) p; - Property inner = mp.getAdditionalProperties(); - return getSwaggerType(p) + "[String, " + getTypeDeclaration(inner) + "]"; - } - return super.getTypeDeclaration(p); - } - - /** - * Optional - swagger type conversion. This is used to map swagger types in a `Property` 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 - * @see io.swagger.models.properties.Property - */ - @Override - public String getSwaggerType(Property p) { - String swaggerType = super.getSwaggerType(p); - String type = null; - if(typeMapping.containsKey(swaggerType)) { - type = typeMapping.get(swaggerType); - if(languageSpecificPrimitives.contains(type)) - return toModelName(type); - } - else - type = swaggerType; - return toModelName(type); - } - - @Override - public String escapeQuotationMark(String input) { - // remove ' to avoid code injection - return input.replace("'", ""); - } - - @Override - public String escapeUnsafeCharacters(String input) { - return input.replace("*/", "*_/").replace("/*", "/_*"); - } - } diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/lumen/LumenServerOptionsTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/lumen/LumenServerOptionsTest.java index dcb89d263cc..434e318f593 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/lumen/LumenServerOptionsTest.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/lumen/LumenServerOptionsTest.java @@ -28,6 +28,24 @@ 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; }}; } } diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/LumenServerOptionsProvider.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/LumenServerOptionsProvider.java index 1ffc290ee46..6edc611b59e 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/LumenServerOptionsProvider.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/LumenServerOptionsProvider.java @@ -1,14 +1,24 @@ package io.swagger.codegen.options; import io.swagger.codegen.CodegenConstants; +import io.swagger.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"; @Override public String getLanguage() { @@ -18,8 +28,17 @@ public String getLanguage() { @Override public Map createOptions() { ImmutableMap.Builder builder = new ImmutableMap.Builder(); - return builder.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_VALUE) + 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) .build(); } diff --git a/samples/server/petstore/lumen/.swagger-codegen-ignore b/samples/server/petstore/lumen/.swagger-codegen-ignore index 19d3377182e..c5fa491b4c5 100644 --- a/samples/server/petstore/lumen/.swagger-codegen-ignore +++ b/samples/server/petstore/lumen/.swagger-codegen-ignore @@ -14,7 +14,7 @@ # You can recursively match patterns against a directory, file or extension with a double asterisk (**): #foo/**/qux -# Thsi matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux # You can also negate patterns with an exclamation (!). # For example, you can ignore all files in a docs folder with the file extension .md: diff --git a/samples/server/petstore/lumen/app/Console/Kernel.php b/samples/server/petstore/lumen/lib/app/Console/Kernel.php similarity index 100% rename from samples/server/petstore/lumen/app/Console/Kernel.php rename to samples/server/petstore/lumen/lib/app/Console/Kernel.php diff --git a/samples/server/petstore/lumen/app/Exceptions/Handler.php b/samples/server/petstore/lumen/lib/app/Exceptions/Handler.php similarity index 100% rename from samples/server/petstore/lumen/app/Exceptions/Handler.php rename to samples/server/petstore/lumen/lib/app/Exceptions/Handler.php diff --git a/samples/server/petstore/lumen/app/Http/controllers/Controller.php b/samples/server/petstore/lumen/lib/app/Http/Controllers/Controller.php similarity index 100% rename from samples/server/petstore/lumen/app/Http/controllers/Controller.php rename to samples/server/petstore/lumen/lib/app/Http/Controllers/Controller.php diff --git a/samples/server/petstore/lumen/app/Http/controllers/FakeApi.php b/samples/server/petstore/lumen/lib/app/Http/Controllers/FakeApi.php similarity index 96% rename from samples/server/petstore/lumen/app/Http/controllers/FakeApi.php rename to samples/server/petstore/lumen/lib/app/Http/Controllers/FakeApi.php index a55492b90f1..919b6f1bac2 100644 --- a/samples/server/petstore/lumen/app/Http/controllers/FakeApi.php +++ b/samples/server/petstore/lumen/lib/app/Http/Controllers/FakeApi.php @@ -140,7 +140,7 @@ public function testEndpointParameters() $date = $input['date']; - $dateTime = $input['dateTime']; + $date_time = $input['date_time']; if (strlen($input['password']) > 64) { throw new \InvalidArgumentException('invalid length for $password when calling FakeApi.testEndpointParameters, must be smaller than or equal to 64.'); @@ -169,11 +169,11 @@ public function testEnumQueryParameters() //not path params validation - $enumQueryString = $input['enumQueryString']; + $enum_query_string = $input['enum_query_string']; - $enumQueryInteger = $input['enumQueryInteger']; + $enum_query_integer = $input['enum_query_integer']; - $enumQueryDouble = $input['enumQueryDouble']; + $enum_query_double = $input['enum_query_double']; return response('How about implementing testEnumQueryParameters as a GET method ?'); diff --git a/samples/server/petstore/lumen/app/Http/controllers/PetApi.php b/samples/server/petstore/lumen/lib/app/Http/Controllers/PetApi.php similarity index 92% rename from samples/server/petstore/lumen/app/Http/controllers/PetApi.php rename to samples/server/petstore/lumen/lib/app/Http/Controllers/PetApi.php index bd06e75fa6e..107f8892bf6 100644 --- a/samples/server/petstore/lumen/app/Http/controllers/PetApi.php +++ b/samples/server/petstore/lumen/lib/app/Http/Controllers/PetApi.php @@ -139,11 +139,11 @@ public function findPetsByTags() * * Deletes a pet. * - * @param Long $petId Pet id to delete (required) + * @param int $pet_id Pet id to delete (required) * * @return Http response */ - public function deletePet($petId) + public function deletePet($pet_id) { $input = Request::all(); @@ -159,11 +159,11 @@ public function deletePet($petId) * * Find pet by ID. * - * @param Long $petId ID of pet to return (required) + * @param int $pet_id ID of pet to return (required) * * @return Http response */ - public function getPetById($petId) + public function getPetById($pet_id) { $input = Request::all(); @@ -179,11 +179,11 @@ public function getPetById($petId) * * Updates a pet in the store with form data. * - * @param Long $petId ID of pet that needs to be updated (required) + * @param int $pet_id ID of pet that needs to be updated (required) * * @return Http response */ - public function updatePetWithForm($petId) + public function updatePetWithForm($pet_id) { $input = Request::all(); @@ -199,11 +199,11 @@ public function updatePetWithForm($petId) * * uploads an image. * - * @param Long $petId ID of pet to update (required) + * @param int $pet_id ID of pet to update (required) * * @return Http response */ - public function uploadFile($petId) + public function uploadFile($pet_id) { $input = Request::all(); diff --git a/samples/server/petstore/lumen/app/Http/controllers/StoreApi.php b/samples/server/petstore/lumen/lib/app/Http/Controllers/StoreApi.php similarity index 84% rename from samples/server/petstore/lumen/app/Http/controllers/StoreApi.php rename to samples/server/petstore/lumen/lib/app/Http/Controllers/StoreApi.php index 4eae1e17c9f..24cd6936225 100644 --- a/samples/server/petstore/lumen/app/Http/controllers/StoreApi.php +++ b/samples/server/petstore/lumen/lib/app/Http/Controllers/StoreApi.php @@ -86,17 +86,17 @@ public function placeOrder() * * Delete purchase order by ID. * - * @param String $orderId ID of the order that needs to be deleted (required) + * @param string $order_id ID of the order that needs to be deleted (required) * * @return Http response */ - public function deleteOrder($orderId) + public function deleteOrder($order_id) { $input = Request::all(); //path params validation - if ($orderId] < 1.0) { - throw new \InvalidArgumentException('invalid value for $orderId when calling StoreApi.deleteOrder, must be bigger than or equal to 1.0.'); + if ($order_id] < 1.0) { + throw new \InvalidArgumentException('invalid value for $order_id when calling StoreApi.deleteOrder, must be bigger than or equal to 1.0.'); } @@ -109,20 +109,20 @@ public function deleteOrder($orderId) * * Find purchase order by ID. * - * @param Long $orderId ID of pet that needs to be fetched (required) + * @param int $order_id ID of pet that needs to be fetched (required) * * @return Http response */ - public function getOrderById($orderId) + public function getOrderById($order_id) { $input = Request::all(); //path params validation - if ($orderId] > 5.0) { - throw new \InvalidArgumentException('invalid value for $orderId when calling StoreApi.getOrderById, must be smaller than or equal to 5.0.'); + if ($order_id] > 5.0) { + throw new \InvalidArgumentException('invalid value for $order_id when calling StoreApi.getOrderById, must be smaller than or equal to 5.0.'); } - if ($orderId] < 1.0) { - throw new \InvalidArgumentException('invalid value for $orderId when calling StoreApi.getOrderById, must be bigger than or equal to 1.0.'); + if ($order_id] < 1.0) { + throw new \InvalidArgumentException('invalid value for $order_id when calling StoreApi.getOrderById, must be bigger than or equal to 1.0.'); } diff --git a/samples/server/petstore/lumen/app/Http/controllers/UserApi.php b/samples/server/petstore/lumen/lib/app/Http/Controllers/UserApi.php similarity index 96% rename from samples/server/petstore/lumen/app/Http/controllers/UserApi.php rename to samples/server/petstore/lumen/lib/app/Http/Controllers/UserApi.php index 331c90525e9..92869eddab4 100644 --- a/samples/server/petstore/lumen/app/Http/controllers/UserApi.php +++ b/samples/server/petstore/lumen/lib/app/Http/Controllers/UserApi.php @@ -163,7 +163,7 @@ public function logoutUser() * * Delete user. * - * @param String $username The name that needs to be deleted (required) + * @param string $username The name that needs to be deleted (required) * * @return Http response */ @@ -183,7 +183,7 @@ public function deleteUser($username) * * Get user by user name. * - * @param String $username The name that needs to be fetched. Use user1 for testing. (required) + * @param string $username The name that needs to be fetched. Use user1 for testing. (required) * * @return Http response */ @@ -203,7 +203,7 @@ public function getUserByName($username) * * Updated user. * - * @param String $username name that need to be deleted (required) + * @param string $username name that need to be deleted (required) * * @return Http response */ diff --git a/samples/server/petstore/lumen/app/Http/Middleware/Authenticate.php b/samples/server/petstore/lumen/lib/app/Http/Middleware/Authenticate.php similarity index 100% rename from samples/server/petstore/lumen/app/Http/Middleware/Authenticate.php rename to samples/server/petstore/lumen/lib/app/Http/Middleware/Authenticate.php diff --git a/samples/server/petstore/lumen/app/Http/routes.php b/samples/server/petstore/lumen/lib/app/Http/routes.php similarity index 100% rename from samples/server/petstore/lumen/app/Http/routes.php rename to samples/server/petstore/lumen/lib/app/Http/routes.php diff --git a/samples/server/petstore/lumen/app/User.php b/samples/server/petstore/lumen/lib/app/User.php similarity index 100% rename from samples/server/petstore/lumen/app/User.php rename to samples/server/petstore/lumen/lib/app/User.php diff --git a/samples/server/petstore/lumen/bootstrap/app.php b/samples/server/petstore/lumen/lib/bootstrap/app.php similarity index 100% rename from samples/server/petstore/lumen/bootstrap/app.php rename to samples/server/petstore/lumen/lib/bootstrap/app.php diff --git a/samples/server/petstore/lumen/composer.json b/samples/server/petstore/lumen/lib/composer.json similarity index 100% rename from samples/server/petstore/lumen/composer.json rename to samples/server/petstore/lumen/lib/composer.json diff --git a/samples/server/petstore/lumen/public/index.php b/samples/server/petstore/lumen/lib/public/index.php similarity index 100% rename from samples/server/petstore/lumen/public/index.php rename to samples/server/petstore/lumen/lib/public/index.php diff --git a/samples/server/petstore/lumen/readme.md b/samples/server/petstore/lumen/lib/readme.md similarity index 100% rename from samples/server/petstore/lumen/readme.md rename to samples/server/petstore/lumen/lib/readme.md