org.openapitools.codegen.languages.ScalaPekkoClientCodegen Maven / Gradle / Ivy
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright 2018 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.OperationMap;
import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
public class ScalaPekkoClientCodegen extends AbstractScalaCodegen implements CodegenConfig {
protected String mainPackage = "org.openapitools.client";
protected String groupId = "org.openapitools";
protected String artifactId = "openapi-client";
protected String artifactVersion = "1.0.0";
protected String resourcesFolder = "src/main/resources";
protected String apiDocPath = "docs/";
protected String modelDocPath = "docs/";
protected String configKey = "apiRequest";
protected int defaultTimeoutInMs = 5000;
protected String configKeyPath = mainPackage;
protected boolean registerNonStandardStatusCodes = true;
protected boolean renderJavadoc = true;
protected boolean removeOAuthSecurities = true;
@SuppressWarnings("hiding")
protected final Logger LOGGER = LoggerFactory.getLogger(ScalaPekkoClientCodegen.class);
public ScalaPekkoClientCodegen() {
super();
modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML, WireFormatFeature.Custom))
.securityFeatures(EnumSet.of(
SecurityFeature.BasicAuth,
SecurityFeature.ApiKey,
SecurityFeature.BearerToken
))
.excludeGlobalFeatures(
GlobalFeature.XMLStructureDefinitions,
GlobalFeature.Callbacks,
GlobalFeature.LinkObjects,
GlobalFeature.ParameterStyling
)
.excludeSchemaSupportFeatures(
SchemaSupportFeature.Polymorphism
)
.excludeParameterFeatures(
ParameterFeature.Cookie
)
.includeClientModificationFeatures(
ClientModificationFeature.BasePath,
ClientModificationFeature.UserAgent
)
);
outputFolder = "generated-code/scala-pekko";
modelTemplateFiles.put("model.mustache", ".scala");
apiTemplateFiles.put("api.mustache", ".scala");
apiDocTemplateFiles.put("api_doc.mustache", ".md");
modelDocTemplateFiles.put("model_doc.mustache", ".md");
embeddedTemplateDir = templateDir = "scala-pekko-client";
apiPackage = mainPackage + ".api";
modelPackage = mainPackage + ".model";
invokerPackage = mainPackage + ".core";
setReservedWordsLowerCase(
Arrays.asList(
"abstract", "case", "catch", "class", "def", "do", "else", "extends",
"false", "final", "finally", "for", "forSome", "if", "implicit",
"import", "lazy", "match", "new", "null", "object", "override", "package",
"private", "protected", "return", "sealed", "super", "this", "throw",
"trait", "try", "true", "type", "val", "var", "while", "with", "yield")
);
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
additionalProperties.put("configKey", configKey);
additionalProperties.put("configKeyPath", configKeyPath);
additionalProperties.put("defaultTimeout", defaultTimeoutInMs);
if (renderJavadoc) {
additionalProperties.put("javadocRenderer", new JavadocLambda());
}
additionalProperties.put("fnCapitalize", new CapitalizeLambda());
additionalProperties.put("fnCamelize", new CamelizeLambda(false));
additionalProperties.put("fnEnumEntry", new EnumEntryLambda());
importMapping.remove("Seq");
importMapping.remove("List");
importMapping.remove("Set");
importMapping.remove("Map");
importMapping.put("BigDecimal", "java.math.BigDecimal");
typeMapping = new HashMap<>();
typeMapping.put("array", "Seq");
typeMapping.put("set", "Set");
typeMapping.put("boolean", "Boolean");
typeMapping.put("string", "String");
typeMapping.put("int", "Int");
typeMapping.put("integer", "Int");
typeMapping.put("long", "Long");
typeMapping.put("float", "Float");
typeMapping.put("byte", "Byte");
typeMapping.put("short", "Short");
typeMapping.put("char", "Char");
typeMapping.put("double", "Double");
typeMapping.put("object", "Any");
typeMapping.put("file", "File");
typeMapping.put("binary", "File");
typeMapping.put("number", "BigDecimal");
typeMapping.put("decimal", "BigDecimal");
instantiationTypes.put("array", "ListBuffer");
instantiationTypes.put("map", "Map");
cliOptions.add(new CliOption("mainPackage", "Top-level package name, which defines 'apiPackage', 'modelPackage', 'invokerPackage'").defaultValue("org.openapitools.client"));
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
}
if (additionalProperties.containsKey("mainPackage")) {
setMainPackage((String) additionalProperties.get("mainPackage"));
additionalProperties.replace("configKeyPath", this.configKeyPath);
if (!additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
apiPackage = mainPackage + ".api";
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
}
if (!additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
modelPackage = mainPackage + ".model";
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
}
if (!additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
invokerPackage = mainPackage + ".core";
}
}
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
// make api and model doc path available in mustache template
additionalProperties.put("apiDocPath", apiDocPath);
additionalProperties.put("modelDocPath", modelDocPath);
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("build.sbt.mustache", "", "build.sbt"));
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("reference.mustache", resourcesFolder, "reference.conf"));
final String invokerFolder = (sourceFolder + File.separator + invokerPackage).replace(".", File.separator);
supportingFiles.add(new SupportingFile("apiRequest.mustache", invokerFolder, "ApiRequest.scala"));
supportingFiles.add(new SupportingFile("apiInvoker.mustache", invokerFolder, "ApiInvoker.scala"));
supportingFiles.add(new SupportingFile("requests.mustache", invokerFolder, "requests.scala"));
supportingFiles.add(new SupportingFile("apiSettings.mustache", invokerFolder, "ApiSettings.scala"));
final String apiFolder = (sourceFolder + File.separator + apiPackage).replace(".", File.separator);
supportingFiles.add(new SupportingFile("project/build.properties.mustache", "project", "build.properties"));
supportingFiles.add(new SupportingFile("enumsSerializers.mustache", apiFolder, "EnumsSerializers.scala"));
supportingFiles.add(new SupportingFile("serializers.mustache", invokerFolder, "Serializers.scala"));
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public String getName() {
return "scala-pekko";
}
@Override
public String getHelp() {
return "Generates a Scala client library (beta) base on pekko/Spray.";
}
@Override
public String escapeReservedWord(String name) {
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "`" + name + "`";
}
@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List allModels) {
if (registerNonStandardStatusCodes) {
try {
OperationMap opsMap = objs.getOperations();
HashSet unknownCodes = new HashSet<>();
for (CodegenOperation operation : opsMap.getOperation()) {
for (CodegenResponse response : operation.responses) {
if ("default".equals(response.code)) {
continue;
}
try {
int code = Integer.parseInt(response.code);
if (code >= 600) {
unknownCodes.add(code);
}
} catch (NumberFormatException e) {
LOGGER.error("Status code is not an integer : response.code", e);
}
}
}
if (!unknownCodes.isEmpty()) {
additionalProperties.put("unknownStatusCodes", unknownCodes);
}
} catch (Exception e) {
LOGGER.error("Unable to find operations List", e);
}
}
return super.postProcessOperationsWithModels(objs, allModels);
}
@Override
public List fromSecurity(Map schemes) {
final List codegenSecurities = super.fromSecurity(schemes);
if (!removeOAuthSecurities) {
return codegenSecurities;
}
// Remove OAuth securities
codegenSecurities.removeIf(security -> security.isOAuth);
if (codegenSecurities.isEmpty()) {
return null;
}
return codegenSecurities;
}
@Override
public String toParamName(String name) {
// obtain the name from parameterNameMapping directly if provided
if (parameterNameMapping.containsKey(name)) {
return parameterNameMapping.get(name);
}
return formatIdentifier(name, false);
}
@Override
public String toEnumName(CodegenProperty property) {
return formatIdentifier(property.baseName, true);
}
@Override
public String toDefaultValue(Schema p) {
if (p.getRequired() != null && p.getRequired().contains(p.getName())) {
return "None";
}
if (ModelUtils.isBooleanSchema(p)) {
return null;
} else if (ModelUtils.isDateSchema(p)) {
return null;
} else if (ModelUtils.isDateTimeSchema(p)) {
return null;
} else if (ModelUtils.isNumberSchema(p)) {
return null;
} else if (ModelUtils.isIntegerSchema(p)) {
return null;
} else if (ModelUtils.isMapSchema(p)) {
String inner = getSchemaType(ModelUtils.getAdditionalProperties(p));
return "Map[String, " + inner + "].empty ";
} else if (ModelUtils.isArraySchema(p)) {
String inner = getSchemaType(ModelUtils.getSchemaItems(p));
if (ModelUtils.isSet(p)) {
return "Set[" + inner + "].empty ";
}
return "Seq[" + inner + "].empty ";
} else if (ModelUtils.isStringSchema(p)) {
return null;
} else {
return null;
}
}
private static class JavadocLambda extends CustomLambda {
@Override
public String formatFragment(String fragment) {
final String[] lines = fragment.split("\\r?\\n");
final StringBuilder sb = new StringBuilder();
sb.append(" /**\n");
for (String line : lines) {
sb.append(" * ").append(line).append("\n");
}
sb.append(" */\n");
return sb.toString();
}
}
private static class CapitalizeLambda extends CustomLambda {
@Override
public String formatFragment(String fragment) {
return StringUtils.capitalize(fragment);
}
}
private class EnumEntryLambda extends CustomLambda {
@Override
public String formatFragment(String fragment) {
return formatIdentifier(fragment, true);
}
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
public void setMainPackage(String mainPackage) {
this.configKeyPath = this.mainPackage = mainPackage;
}
@Override
public String apiDocFileFolder() {
return (outputFolder + File.separator + apiDocPath).replace('/', File.separatorChar);
}
@Override
public String modelDocFileFolder() {
return (outputFolder + File.separator + modelDocPath).replace('/', File.separatorChar);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy