io.swagger.codegen.languages.SymfonyServerCodegen Maven / Gradle / Ivy
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenConfig {
@SuppressWarnings("hiding")
static Logger LOGGER = LoggerFactory.getLogger(SymfonyServerCodegen.class);
public static final String BUNDLE_NAME = "bundleName";
public static final String COMPOSER_VENDOR_NAME = "composerVendorName";
public static final String COMPOSER_PROJECT_NAME = "composerProjectName";
public static final String PHP_LEGACY_SUPPORT = "phpLegacySupport";
public static final Map SYMFONY_EXCEPTIONS;
protected String testsPackage;
protected String apiTestsPackage;
protected String modelTestsPackage;
protected String composerVendorName = "swagger";
protected String composerProjectName = "server-bundle";
protected String testsDirName = "Tests";
protected String bundleName;
protected String bundleClassName;
protected String bundleExtensionName;
protected String bundleAlias;
protected String controllerDirName = "Controller";
protected String serviceDirName = "Service";
protected String controllerPackage;
protected String servicePackage;
protected Boolean phpLegacySupport = Boolean.TRUE;
protected HashSet typeHintable;
static {
SYMFONY_EXCEPTIONS = new HashMap<>();
SYMFONY_EXCEPTIONS.put("400", "Symfony\\Component\\HttpKernel\\Exception\\BadRequestHttpException");
SYMFONY_EXCEPTIONS.put("401", "Symfony\\Component\\HttpKernel\\Exception\\UnauthorizedHttpException");
SYMFONY_EXCEPTIONS.put("403", "Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException");
SYMFONY_EXCEPTIONS.put("404", "Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException");
SYMFONY_EXCEPTIONS.put("405", "Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException");
SYMFONY_EXCEPTIONS.put("406", "Symfony\\Component\\HttpKernel\\Exception\\NotAcceptableHttpException");
SYMFONY_EXCEPTIONS.put("409", "Symfony\\Component\\HttpKernel\\Exception\\ConflictHttpException");
SYMFONY_EXCEPTIONS.put("410", "Symfony\\Component\\HttpKernel\\Exception\\GoneHttpException");
SYMFONY_EXCEPTIONS.put("411", "Symfony\\Component\\HttpKernel\\Exception\\LengthRequiredHttpException");
SYMFONY_EXCEPTIONS.put("412", "Symfony\\Component\\HttpKernel\\Exception\\PreconditionFailedHttpException");
SYMFONY_EXCEPTIONS.put("415", "Symfony\\Component\\HttpKernel\\Exception\\UnsupportedMediaTypeHttpException");
SYMFONY_EXCEPTIONS.put("422", "Symfony\\Component\\HttpKernel\\Exception\\UnprocessableEntityHttpException");
SYMFONY_EXCEPTIONS.put("428", "Symfony\\Component\\HttpKernel\\Exception\\PreconditionRequiredHttpException");
SYMFONY_EXCEPTIONS.put("429", "Symfony\\Component\\HttpKernel\\Exception\\TooManyRequestsHttpException");
SYMFONY_EXCEPTIONS.put("503", "Symfony\\Component\\HttpKernel\\Exception\\ServiceUnavailableHttpException");
}
public SymfonyServerCodegen() {
super();
// clear import mapping (from default generator) as php does not use it
// at the moment
importMapping.clear();
supportsInheritance = true;
srcBasePath = ".";
setInvokerPackage("Swagger\\Server");
setBundleName("SwaggerServer");
packagePath = "SymfonyBundle-php";
modelDirName = "Model";
docsBasePath = "Resources" + File.separator + "docs";
apiDocPath = docsBasePath + File.separator + apiDirName;
modelDocPath = docsBasePath + File.separator + modelDirName;
outputFolder = "generated-code" + File.separator + "php";
apiTemplateFiles.put("api_controller.mustache", ".php");
modelTestTemplateFiles.put("testing/model_test.mustache", ".php");
apiTestTemplateFiles = new HashMap();
apiTestTemplateFiles.put("testing/api_test.mustache", ".php");
embeddedTemplateDir = templateDir = "php-symfony";
// default HIDE_GENERATION_TIMESTAMP to true
hideGenerationTimestamp = Boolean.TRUE;
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",
"int",
"double",
"float",
"string",
"object",
"mixed",
"number",
"void",
"byte",
"array"
)
);
defaultIncludes = new HashSet(
Arrays.asList(
"\\DateTime",
"UploadedFile"
)
);
variableNamingConvention = "camelCase";
// provide primitives to mustache template
List sortedLanguageSpecificPrimitives= new ArrayList(languageSpecificPrimitives);
Collections.sort(sortedLanguageSpecificPrimitives);
String primitives = "'" + StringUtils.join(sortedLanguageSpecificPrimitives, "', '") + "'";
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", "UploadedFile");
typeMapping.put("map", "array");
typeMapping.put("array", "array");
typeMapping.put("list", "array");
typeMapping.put("object", "array");
typeMapping.put("binary", "string");
typeMapping.put("ByteArray", "string");
typeMapping.put("UUID", "string");
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(BUNDLE_NAME, "The name of the Symfony bundle. The template uses {{bundleName}}"));
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.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC)
.defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(PHP_LEGACY_SUPPORT, "Should the generated code be compatible with PHP 5.x?").defaultValue(Boolean.TRUE.toString()));
}
public String getBundleName() {
return bundleName;
}
public void setBundleName(String bundleName) {
this.bundleName = bundleName;
this.bundleClassName = bundleName + "Bundle";
this.bundleExtensionName = bundleName + "Extension";
this.bundleAlias = snakeCase(bundleName).replaceAll("([A-Z]+)", "\\_$1").toLowerCase();
}
public void setPhpLegacySupport(Boolean support) {
this.phpLegacySupport = support;
}
public String controllerFileFolder() {
return (outputFolder + File.separator + toPackagePath(controllerPackage, srcBasePath));
}
@Override
public String escapeText(String input) {
if (input != null) {
// Trim the string to avoid leading and trailing spaces.
return super.escapeText(input).trim();
}
return input;
}
@Override
public CodegenType getTag() {
return CodegenType.SERVER;
}
@Override
public String getName() {
return "php-symfony";
}
@Override
public String getHelp() {
return "Generates a Symfony server bundle.";
}
@Override
public String apiFilename(String templateName, String tag) {
String suffix = apiTemplateFiles().get(templateName);
if (templateName.equals("api_controller.mustache"))
return controllerFileFolder() + '/' + toControllerName(tag) + suffix;
return apiFileFolder() + '/' + toApiFilename(tag) + suffix;
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(BUNDLE_NAME)) {
this.setBundleName((String) additionalProperties.get(BUNDLE_NAME));
} else {
additionalProperties.put(BUNDLE_NAME, bundleName);
}
if (additionalProperties.containsKey(COMPOSER_PROJECT_NAME)) {
this.setComposerProjectName((String) additionalProperties.get(COMPOSER_PROJECT_NAME));
} else {
additionalProperties.put(COMPOSER_PROJECT_NAME, composerProjectName);
}
if (additionalProperties.containsKey(COMPOSER_VENDOR_NAME)) {
this.setComposerVendorName((String) additionalProperties.get(COMPOSER_VENDOR_NAME));
} else {
additionalProperties.put(COMPOSER_VENDOR_NAME, composerVendorName);
}
if (additionalProperties.containsKey(PHP_LEGACY_SUPPORT)) {
this.setPhpLegacySupport(Boolean.valueOf((String) additionalProperties.get(PHP_LEGACY_SUPPORT)));
} else {
additionalProperties.put(PHP_LEGACY_SUPPORT, phpLegacySupport);
}
additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\"));
additionalProperties.put("controllerPackage", controllerPackage);
additionalProperties.put("servicePackage", servicePackage);
additionalProperties.put("apiTestsPackage", apiTestsPackage);
additionalProperties.put("modelTestsPackage", modelTestsPackage);
// make Symonfy-specific properties available
additionalProperties.put("bundleName", bundleName);
additionalProperties.put("bundleClassName", bundleClassName);
additionalProperties.put("bundleExtensionName", bundleExtensionName);
additionalProperties.put("bundleAlias", bundleAlias);
// 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("testsSrcPath", "." + File.separator + toSrcPath(testsPackage, srcBasePath));
additionalProperties.put("apiTestsSrcPath", "." + File.separator + toSrcPath(apiTestsPackage, srcBasePath));
additionalProperties.put("modelTestsSrcPath", "." + File.separator + toSrcPath(modelTestsPackage, srcBasePath));
additionalProperties.put("apiTestPath", "." + File.separator + testsDirName + File.separator + apiDirName);
additionalProperties.put("modelTestPath", "." + File.separator + testsDirName + 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("testsDirName", testsDirName);
final String configDir = getPackagePath() + File.separator + "Resources" + File.separator + "config";
final String dependencyInjectionDir = getPackagePath() + File.separator + "DependencyInjection";
supportingFiles.add(new SupportingFile("Controller.mustache", toPackagePath(controllerPackage, srcBasePath), "Controller.php"));
supportingFiles.add(new SupportingFile("Bundle.mustache", getPackagePath(), bundleClassName + ".php"));
supportingFiles.add(new SupportingFile("Extension.mustache", dependencyInjectionDir, bundleExtensionName + ".php"));
supportingFiles.add(new SupportingFile("ApiPass.mustache", dependencyInjectionDir + File.separator + "Compiler", bundleName + "ApiPass.php"));
supportingFiles.add(new SupportingFile("ApiServer.mustache", toPackagePath(apiPackage, srcBasePath), "ApiServer.php"));
// Serialization components
supportingFiles.add(new SupportingFile("serialization/SerializerInterface.mustache", toPackagePath(servicePackage, srcBasePath), "SerializerInterface.php"));
supportingFiles.add(new SupportingFile("serialization/JmsSerializer.mustache", toPackagePath(servicePackage, srcBasePath), "JmsSerializer.php"));
supportingFiles.add(new SupportingFile("serialization/StrictJsonDeserializationVisitor.mustache", toPackagePath(servicePackage, srcBasePath), "StrictJsonDeserializationVisitor.php"));
supportingFiles.add(new SupportingFile("serialization/TypeMismatchException.mustache", toPackagePath(servicePackage, srcBasePath), "TypeMismatchException.php"));
// Validation components
supportingFiles.add(new SupportingFile("validation/ValidatorInterface.mustache", toPackagePath(servicePackage, srcBasePath), "ValidatorInterface.php"));
supportingFiles.add(new SupportingFile("validation/SymfonyValidator.mustache", toPackagePath(servicePackage, srcBasePath), "SymfonyValidator.php"));
// Testing components
supportingFiles.add(new SupportingFile("testing/phpunit.xml.mustache", getPackagePath(), "phpunit.xml.dist"));
supportingFiles.add(new SupportingFile("testing/pom.xml", getPackagePath(), "pom.xml"));
supportingFiles.add(new SupportingFile("testing/AppKernel.php", toPackagePath(testsPackage, srcBasePath), "AppKernel.php"));
supportingFiles.add(new SupportingFile("testing/test_config.yml", toPackagePath(testsPackage, srcBasePath), "test_config.yml"));
supportingFiles.add(new SupportingFile("routing.mustache", configDir, "routing.yml"));
supportingFiles.add(new SupportingFile("services.mustache", configDir, "services.yml"));
supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json"));
supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php"));
supportingFiles.add(new SupportingFile("README.mustache", getPackagePath(), "README.md"));
supportingFiles.add(new SupportingFile(".travis.yml", getPackagePath(), ".travis.yml"));
supportingFiles.add(new SupportingFile(".php_cs", getPackagePath(), ".php_cs"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", getPackagePath(), "git_push.sh"));
// Type-hintable primitive types
// ref: http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration
if (phpLegacySupport) {
typeHintable = new HashSet(
Arrays.asList(
"array"
)
);
} else {
typeHintable = new HashSet(
Arrays.asList(
"array",
"bool",
"float",
"int",
"string"
)
);
}
}
@Override
public Map postProcessOperations(Map objs) {
objs = super.postProcessOperations(objs);
Map operations = (Map) objs.get("operations");
operations.put("controllerName", toControllerName((String) operations.get("pathPrefix")));
operations.put("symfonyService", toSymfonyService((String) operations.get("pathPrefix")));
HashSet authMethods = new HashSet<>();
List operationList = (List) operations.get("operation");
for (CodegenOperation op : operationList) {
// Loop through all input parameters to determine, whether we have to import something to
// make the input type available.
for (CodegenParameter param : op.allParams) {
// Determine if the parameter type is supported as a type hint and make it available
// to the templating engine
String typeHint = getTypeHint(param.dataType);
if (!typeHint.isEmpty()) {
param.vendorExtensions.put("x-parameterType", typeHint);
}
if (param.isContainer) {
param.vendorExtensions.put("x-parameterType", getTypeHint(param.dataType+"[]"));
}
// Create a variable to display the correct data type in comments for interfaces
param.vendorExtensions.put("x-commentType", param.dataType);
if (param.isContainer) {
param.vendorExtensions.put("x-commentType", param.dataType+"[]");
}
// Quote default values for strings
// @todo: The default values for headers, forms and query params are handled
// in DefaultCodegen fromParameter with no real possibility to override
// the functionality. Thus we are handling quoting of string values here
if (param.dataType.equals("string") && param.defaultValue != null && !param.defaultValue.isEmpty()) {
param.defaultValue = "'"+param.defaultValue+"'";
}
}
// Create a variable to display the correct return type in comments for interfaces
if (op.returnType != null) {
op.vendorExtensions.put("x-commentType", op.returnType);
if (!op.returnTypeIsPrimitive) {
op.vendorExtensions.put("x-commentType", op.returnType+"[]");
}
} else {
op.vendorExtensions.put("x-commentType", "void");
}
// Add operation's authentication methods to whole interface
if (op.authMethods != null) {
authMethods.addAll(op.authMethods);
}
}
operations.put("authMethods", authMethods);
return objs;
}
@Override
public Map postProcessModels(Map objs) {
objs = super.postProcessModels(objs);
ArrayList
© 2015 - 2024 Weber Informatics LLC | Privacy Policy