All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.swagger.codegen.v3.generators.html.StaticHtml2Codegen Maven / Gradle / Ivy

There is a newer version: 1.0.54
Show newest version
package io.swagger.codegen.v3.generators.html;

import io.swagger.codegen.v3.CliOption;
import io.swagger.codegen.v3.CodegenConfig;
import io.swagger.codegen.v3.CodegenConstants;
import io.swagger.codegen.v3.CodegenOperation;
import io.swagger.codegen.v3.CodegenParameter;
import io.swagger.codegen.v3.CodegenResponse;
import io.swagger.codegen.v3.CodegenType;
import io.swagger.codegen.v3.SupportingFile;
import io.swagger.codegen.v3.generators.DefaultCodegenConfig;
import io.swagger.codegen.v3.utils.Markdown;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.MapSchema;
import io.swagger.v3.oas.models.media.ObjectSchema;
import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import static io.swagger.codegen.v3.generators.handlebars.ExtensionHelper.getBooleanValue;

public class StaticHtml2Codegen extends DefaultCodegenConfig implements CodegenConfig {
    private static final Logger LOGGER = LoggerFactory.getLogger(StaticHtml2Codegen.class);

    protected String invokerPackage = "io.swagger.client"; // default for Java and Android
    protected String phpInvokerPackage = "Swagger\\Client"; // default for PHP
    protected String packageName = "IO.Swagger"; // default for C#
    protected String groupId = "io.swagger";
    protected String artifactId = "swagger-client";
    protected String artifactVersion = "1.0.0";
    protected String jsProjectName;
    protected String jsModuleName;
    protected String perlModuleName = "WWW::SwaggerClient";
    protected String pythonPackageName = "swagger_client";

    public StaticHtml2Codegen() {
        super();
        outputFolder = "docs";

        defaultIncludes = new HashSet();

        cliOptions.add(new CliOption("appName", "short name of the application"));
        cliOptions.add(new CliOption("appDescription", "description of the application"));
        cliOptions.add(new CliOption("infoUrl", "a URL where users can get more information about the application"));
        cliOptions.add(new CliOption("infoEmail", "an email address to contact for inquiries about the application"));
        cliOptions.add(new CliOption("licenseInfo", "a short description of the license"));
        cliOptions.add(new CliOption("licenseUrl", "a URL pointing to the full license"));
        cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, CodegenConstants.INVOKER_PACKAGE_DESC));
        cliOptions.add(new CliOption(CodegenConstants.PHP_INVOKER_PACKAGE, CodegenConstants.PHP_INVOKER_PACKAGE_DESC));
        cliOptions.add(new CliOption(CodegenConstants.PERL_MODULE_NAME, CodegenConstants.PERL_MODULE_NAME_DESC));
        cliOptions.add(new CliOption(CodegenConstants.PYTHON_PACKAGE_NAME, CodegenConstants.PYTHON_PACKAGE_NAME_DESC));
        cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "C# package name"));
        cliOptions.add(new CliOption(CodegenConstants.GROUP_ID, CodegenConstants.GROUP_ID_DESC));
        cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_ID, CodegenConstants.ARTIFACT_ID_DESC));
        cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, CodegenConstants.ARTIFACT_VERSION_DESC));

        additionalProperties.put("appName", "Swagger Sample");
        additionalProperties.put("appDescription", "A sample swagger server");
        additionalProperties.put("infoUrl", "https://helloreverb.com");
        additionalProperties.put("infoEmail", "[email protected]");
        additionalProperties.put("licenseInfo", "All rights reserved");
        additionalProperties.put("licenseUrl", "http://apache.org/licenses/LICENSE-2.0.html");
        additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
        additionalProperties.put(CodegenConstants.PHP_INVOKER_PACKAGE, phpInvokerPackage);
        additionalProperties.put(CodegenConstants.PERL_MODULE_NAME, perlModuleName);
        additionalProperties.put(CodegenConstants.PYTHON_PACKAGE_NAME, pythonPackageName);
        additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
        additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
        additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
        additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);

        supportingFiles.add(new SupportingFile("index.mustache", "", "index.html"));
        reservedWords = new HashSet();

        languageSpecificPrimitives = new HashSet();
        importMapping = new HashMap();
    }

    @Override
    public CodegenType getTag() {
        return CodegenType.DOCUMENTATION;
    }

    @Override
    public String getArgumentsLocation() {
        return "";
    }

    @Override
    public String getDefaultTemplateDir() {
        return "htmlDocs2";
    }

    @Override
    public String getName() {
        return "html2";
    }

    @Override
    public String escapeText(String input) {
        // newline escaping disabled for HTML documentation for markdown to work
        // correctly
        return input;
    }

    @Override
    public String getHelp() {
        return "Generates a static HTML file.";
    }

    @Override
    public String getTypeDeclaration(Schema propertySchema) {
        if (propertySchema instanceof ArraySchema) {
            Schema inner = ((ArraySchema) propertySchema).getItems();
            return String.format("%s[%s]", getSchemaType(propertySchema), getTypeDeclaration(inner));
        }
        else if (propertySchema instanceof MapSchema  && hasSchemaProperties(propertySchema)) {
            Schema inner = (Schema) propertySchema.getAdditionalProperties();
            return String.format("%s[String, %s]", getSchemaType(propertySchema), getTypeDeclaration(inner));
        } else if (propertySchema instanceof MapSchema && hasTrueAdditionalProperties(propertySchema)) {
            Schema inner = new ObjectSchema();
            return String.format("%s[String, %s]", getSchemaType(propertySchema), getTypeDeclaration(inner));
        }
        return super.getTypeDeclaration(propertySchema);
    }

    @Override
    public Map postProcessOperations(Map objs) {
        Map operations = (Map) objs.get("operations");
        List operationList = (List) operations.get("operation");
        for (CodegenOperation op : operationList) {
            op.httpMethod = op.httpMethod.toLowerCase();
            for (CodegenResponse response : op.responses) {
                if ("0".equals(response.code)) {
                    response.code = "default";
                }
            }
            op.formParams = postProcessParameterEnum(op.formParams);
        }
        return objs;
    }

    @Override
    public void preprocessOpenAPI(OpenAPI openAPI) {
        super.preprocessOpenAPI(openAPI);

        if (openAPI.getInfo() != null) {
            Info info = openAPI.getInfo();
            if (StringUtils.isBlank(jsProjectName) && info.getTitle() != null) {
                // when jsProjectName is not specified, generate it from info.title
                jsProjectName = sanitizeName(dashize(info.getTitle()));
            }
        }

        // default values
        if (StringUtils.isBlank(jsProjectName)) {
            jsProjectName = "swagger-js-client";
        }
        if (StringUtils.isBlank(jsModuleName)) {
            jsModuleName = camelize(underscore(jsProjectName));
        }

        additionalProperties.put("jsProjectName", jsProjectName);
        additionalProperties.put("jsModuleName", jsModuleName);

        preparHtmlForGlobalDescription(openAPI);
    }

    @Override
    public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map definitions, OpenAPI ope) {
        CodegenOperation op = super.fromOperation(path, httpMethod, operation, definitions, ope);
        if (op.returnType != null) {
            op.returnType = normalizeType(op.returnType);
        }

        op.operationId = op.operationId.replace(" ", "_");
        op.nickname = op.operationId;

        // path is an unescaped variable in the mustache template api.mustache
        // line 82 '<&path>'
        op.path = sanitizePath(op.path);

        // Set vendor-extension to be used in template:
        // x-codegen-hasMoreRequired
        // x-codegen-hasMoreOptional
        // x-codegen-hasRequiredParams
        CodegenParameter lastRequired = null;
        CodegenParameter lastOptional = null;
        for (CodegenParameter p : op.allParams) {
            if (p.required) {
                lastRequired = p;
            }
            else {
                lastOptional = p;
            }
        }
        for (CodegenParameter p : op.allParams) {
            if (p == lastRequired) {
                p.vendorExtensions.put("x-codegen-hasMoreRequired", false);
            }
            else if (p == lastOptional) {
                p.vendorExtensions.put("x-codegen-hasMoreOptional", false);
            }
            else {
                p.vendorExtensions.put("x-codegen-hasMoreRequired", true);
                p.vendorExtensions.put("x-codegen-hasMoreOptional", true);
            }
        }
        op.vendorExtensions.put("x-codegen-hasRequiredParams", lastRequired != null);

        op.vendorExtensions.put("x-codegen-httpMethodUpperCase", httpMethod.toUpperCase());

        return op;
    }

    /**
     * Parse Markdown to HTML for the main "Description" attribute
     *
     * @param openAPI
     *            The base object containing the global description through
     *            "Info" class
     * @return Void
     */
    private void preparHtmlForGlobalDescription(OpenAPI openAPI) {
        String currentDescription = openAPI.getInfo().getDescription();
        if (currentDescription != null && !currentDescription.isEmpty()) {
            Markdown markInstance = new Markdown();
            openAPI.getInfo().setDescription(markInstance.toHtml(currentDescription));
        }
        else {
            LOGGER.error("Swagger object description is empty [" + openAPI.getInfo().getTitle() + "]");
        }
    }

    /**
     * Format to HTML the enums contained in every operations
     *
     * @param parameterList
     *            The whole parameters contained in one operation
     * @return String | Html formated enum
     */
    public List postProcessParameterEnum(List parameterList) {
        String enumFormatted = "";
        for (CodegenParameter parameter : parameterList) {
            if (getBooleanValue(parameter, CodegenConstants.IS_ENUM_EXT_NAME)) {
                for (int i = 0; i < parameter._enum.size(); i++) {
                    String spacer = (i == (parameter._enum.size() - 1)) ? " " : ", ";

                    if (parameter._enum.get(i) != null)
                        enumFormatted += "`" + parameter._enum.get(i) + "`" + spacer;
                }
                Markdown markInstance = new Markdown();
                if (!enumFormatted.isEmpty())
                    parameter.vendorExtensions.put("x-eumFormatted", markInstance.toHtml(enumFormatted));
            }
        }
        return parameterList;
    }

    private String sanitizePath(String p) {
        // prefer replace a ', instead of a fuLL URL encode for readability
        return p.replaceAll("'", "%27");
    }

    /**
     * Normalize type by wrapping primitive types with single quotes.
     *
     * @param type
     *            Primitive type
     * @return Normalized type
     */
    public String normalizeType(String type) {
        return type.replaceAll("\\b(Boolean|Integer|Number|String|Date)\\b", "'$1'");
    }

    @Override
    public String escapeQuotationMark(String input) {
        // just return the original string
        return input;
    }

    @Override
    public String escapeUnsafeCharacters(String input) {
        // just return the original string
        return input;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy