org.openapitools.codegen.languages.ElmClientCodegen 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.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.responses.ApiResponse;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.text.Collator;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize;
public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(ElmClientCodegen.class);
private Set customPrimitives = new HashSet();
private ElmVersion elmVersion = ElmVersion.ELM_019;
private Boolean elmPrefixCustomTypeVariants = false;
private static final String ELM_VERSION = "elmVersion";
private static final String ELM_PREFIX_CUSTOM_TYPE_VARIANTS = "elmPrefixCustomTypeVariants";
private static final String ELM_ENABLE_CUSTOM_BASE_PATHS = "elmEnableCustomBasePaths";
private static final String ELM_ENABLE_HTTP_REQUEST_TRACKERS = "elmEnableHttpRequestTrackers";
private static final String ENCODER = "elmEncoder"; // TODO: 5.0 Remove
private static final String VENDOR_EXTENSION_ENCODER = "x-elm-encoder";
private static final String DECODER = "elmDecoder"; // TODO: 5.0 Remove
private static final String VENDOR_EXTENSION_DECODER = "x-elm-decoder";
private static final String DISCRIMINATOR_NAME = "discriminatorName"; // TODO: 5.0 Remove
private static final String VENDOR_EXTENSION_DISCRIMINATOR_NAME = "x-discriminator-name";
private static final String CUSTOM_TYPE = "elmCustomType"; // TODO: 5.0 Remove
private static final String VENDOR_EXTENSION_CUSTOM_TYPE = "x-elm-custom-type";
protected String packageName = "openapi";
protected String packageVersion = "1.0.0";
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public String getName() {
return "elm";
}
public String getHelp() {
return "Generates a Elm client library (beta).";
}
public ElmClientCodegen() {
super();
modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON))
.securityFeatures(EnumSet.noneOf(SecurityFeature.class))
.excludeGlobalFeatures(
GlobalFeature.XMLStructureDefinitions,
GlobalFeature.Callbacks,
GlobalFeature.LinkObjects,
GlobalFeature.ParameterStyling
)
.excludeSchemaSupportFeatures(
SchemaSupportFeature.Polymorphism
)
.excludeParameterFeatures(
ParameterFeature.Cookie
)
.includeClientModificationFeatures(
ClientModificationFeature.BasePath
)
);
outputFolder = "generated-code/elm";
modelTemplateFiles.put("model.mustache", ".elm");
templateDir = "elm";
supportsInheritance = true;
reservedWords = new HashSet<>(
Arrays.asList(
"if", "then", "else",
"case", "of",
"let", "in",
"type",
"module", "where",
"import", "exposing",
"as",
"port")
);
defaultIncludes = new HashSet<>(
Arrays.asList(
"Order",
"Never",
"List",
"Maybe",
"Result",
"Program",
"Cmd",
"Sub")
);
languageSpecificPrimitives = new HashSet<>(
Arrays.asList(
"Bool",
"Dict",
"Float",
"Int",
"List",
"String")
);
customPrimitives = new HashSet<>(
Arrays.asList(
"Byte",
"DateOnly",
"DateTime",
"Uuid")
);
instantiationTypes.clear();
instantiationTypes.put("array", "List");
instantiationTypes.put("map", "Dict");
typeMapping.clear();
typeMapping.put("integer", "Int");
typeMapping.put("long", "Int");
typeMapping.put("number", "Float");
typeMapping.put("float", "Float");
typeMapping.put("double", "Float");
typeMapping.put("boolean", "Bool");
typeMapping.put("string", "String");
typeMapping.put("array", "List");
typeMapping.put("map", "Dict");
typeMapping.put("date", "DateOnly");
typeMapping.put("DateTime", "DateTime");
typeMapping.put("password", "String");
typeMapping.put("ByteArray", "Byte");
typeMapping.put("file", "String");
typeMapping.put("binary", "String");
typeMapping.put("UUID", "Uuid");
typeMapping.put("URI", "String");
importMapping.clear();
cliOptions.clear();
final CliOption elmVersion = new CliOption(ELM_VERSION, "Elm version: 0.18, 0.19").defaultValue("0.19");
final Map supportedVersions = new HashMap<>();
supportedVersions.put("0.18", "Elm 0.18");
supportedVersions.put("0.19", "Elm 0.19");
elmVersion.setEnum(supportedVersions);
cliOptions.add(elmVersion);
final CliOption elmPrefixCustomTypeVariants = CliOption.newBoolean(ELM_PREFIX_CUSTOM_TYPE_VARIANTS, "Prefix custom type variants");
cliOptions.add(elmPrefixCustomTypeVariants);
final CliOption elmEnableCustomBasePaths = CliOption.newBoolean(ELM_ENABLE_CUSTOM_BASE_PATHS, "Enable setting the base path for each request");
cliOptions.add(elmEnableCustomBasePaths);
final CliOption elmEnableHttpRequestTrackers = CliOption.newBoolean(ELM_ENABLE_HTTP_REQUEST_TRACKERS, "Enable adding a tracker to each http request");
cliOptions.add(elmEnableHttpRequestTrackers);
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(ELM_VERSION)) {
final String version = (String) additionalProperties.get(ELM_VERSION);
if ("0.18".equals(version)) {
elmVersion = ElmVersion.ELM_018;
} else {
elmVersion = ElmVersion.ELM_019;
}
}
if (additionalProperties.containsKey(ELM_PREFIX_CUSTOM_TYPE_VARIANTS)) {
elmPrefixCustomTypeVariants = Boolean.TRUE.equals(Boolean.valueOf(additionalProperties.get(ELM_PREFIX_CUSTOM_TYPE_VARIANTS).toString()));
}
if (additionalProperties.containsKey(ELM_ENABLE_CUSTOM_BASE_PATHS)) {
final boolean enable = Boolean.TRUE.equals(Boolean.valueOf(additionalProperties.get(ELM_ENABLE_CUSTOM_BASE_PATHS).toString()));
additionalProperties.put("enableCustomBasePaths", enable);
}
if (additionalProperties.containsKey(ELM_ENABLE_HTTP_REQUEST_TRACKERS)) {
final boolean enable = Boolean.TRUE.equals(Boolean.valueOf(additionalProperties.get(ELM_ENABLE_HTTP_REQUEST_TRACKERS).toString()));
additionalProperties.put("enableHttpRequestTrackers", enable);
}
if (StringUtils.isEmpty(System.getenv("ELM_POST_PROCESS_FILE"))) {
if (elmVersion.equals(ElmVersion.ELM_018)) { // 0.18
LOGGER.info("Environment variable ELM_POST_PROCESS_FILE not defined so the Elm code may not be properly formatted. To define it, try `export ELM_POST_PROCESS_FILE=\"/usr/local/bin/elm-format --elm-version={} --yes\"` (Linux/Mac)", "0.18");
} else { // 0.19
LOGGER.info("Environment variable ELM_POST_PROCESS_FILE not defined so the Elm code may not be properly formatted. To define it, try `export ELM_POST_PROCESS_FILE=\"/usr/local/bin/elm-format --elm-version={} --yes\"` (Linux/Mac)", "0.19");
}
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
switch (elmVersion) {
case ELM_018:
LOGGER.info("Elm version: 0.18");
additionalProperties.put("isElm018", true);
apiTemplateFiles.put("api018.mustache", ".elm");
supportingFiles.add(new SupportingFile("DateOnly018.mustache", "src", "DateOnly.elm"));
supportingFiles.add(new SupportingFile("DateTime018.mustache", "src", "DateTime.elm"));
supportingFiles.add(new SupportingFile("elm-package018.mustache", "", "elm-package.json"));
supportingFiles.add(new SupportingFile("Main018.mustache", "src", "Main.elm"));
break;
case ELM_019:
LOGGER.info("Elm version: 0.19");
additionalProperties.put("isElm019", true);
apiTemplateFiles.put("api.mustache", ".elm");
supportingFiles.add(new SupportingFile("DateOnly.mustache", "src", "DateOnly.elm"));
supportingFiles.add(new SupportingFile("DateTime.mustache", "src", "DateTime.elm"));
supportingFiles.add(new SupportingFile("elm.mustache", "", "elm.json"));
supportingFiles.add(new SupportingFile("Main.mustache", "src", "Main.elm"));
break;
default:
throw new RuntimeException("Undefined Elm version");
}
supportingFiles.add(new SupportingFile("Byte.mustache", "src", "Byte.elm"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String escapeQuotationMark(String input) {
return input.replace("\"", "");
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "Default";
}
return camelize(name);
}
@Override
public String toModelName(String name) {
final String modelName = camelize(name);
return defaultIncludes.contains(modelName) ? modelName + "_" : modelName;
}
@Override
public String toModelFilename(String name) {
return toModelName(name);
}
@Override
public String toEnumName(CodegenProperty property) {
return toModelName(property.name);
}
@Override
public String toVarName(String name) {
final String varName = camelize(name, true);
return isReservedWord(varName) ? escapeReservedWord(name) : varName;
}
@Override
public String toEnumVarName(String value, String datatype) {
String camelized = camelize(value.replace(" ", "_").replace("(", "_").replace(")", "")); // TODO FIXME escape properly
if (camelized.length() == 0) {
LOGGER.error("Unable to determine enum variable name (name: {}, datatype: {}) from empty string. Default to UnknownEnumVariableName", value, datatype);
camelized = "UnknownEnumVariableName";
}
if (!Character.isUpperCase(camelized.charAt(0))) {
return "N" + camelized;
}
return camelized;
}
@Override
public String toInstantiationType(Schema p) {
if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
String inner = getSchemaType(ap.getItems());
return instantiationTypes.get("array") + " " + inner;
} else {
return null;
}
}
@Override
public String escapeReservedWord(String name) {
return name + "_";
}
@Override
public String apiFileFolder() {
return outputFolder + ("/src/Request/" + apiPackage().replace('.', File.separatorChar)).replace("/", File.separator);
}
@Override
public String modelFileFolder() {
return outputFolder + ("/src/Data/" + modelPackage().replace('.', File.separatorChar)).replace("/", File.separator);
}
@Override
public CodegenModel fromModel(String name, Schema schema) {
CodegenModel m = super.fromModel(name, schema);
if (ModelUtils.isArraySchema(schema)) {
ArraySchema am = (ArraySchema) schema;
CodegenProperty codegenProperty = fromProperty(name, (Schema) am.getItems());
m.vendorExtensions.putAll(codegenProperty.vendorExtensions);
}
return m;
}
@SuppressWarnings({"static-method", "unchecked"})
public Map postProcessAllModels(Map objs) {
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
// Index all CodegenModels by model name.
Map allModels = new HashMap<>();
for (Map.Entry entry : objs.entrySet()) {
String modelName = toModelName(entry.getKey());
Map inner = (Map) entry.getValue();
List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy