io.swagger.codegen.languages.NancyFXServerCodegen Maven / Gradle / Ivy
package io.swagger.codegen.languages;
import static com.google.common.base.Strings.isNullOrEmpty;
import static io.swagger.codegen.CodegenConstants.*;
import static io.swagger.codegen.CodegenType.SERVER;
import static java.util.Arrays.asList;
import static java.util.UUID.randomUUID;
import static org.apache.commons.lang3.StringUtils.capitalize;
import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.SupportingFile;
import io.swagger.codegen.utils.ModelUtils;
import io.swagger.models.Swagger;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.StringProperty;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Predicate;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
public class NancyFXServerCodegen extends AbstractCSharpCodegen {
private static final Logger log = LoggerFactory.getLogger(NancyFXServerCodegen.class);
private static final String API_NAMESPACE = "Modules";
private static final String MODEL_NAMESPACE = "Models";
private static final String IMMUTABLE_OPTION = "immutable";
private static final String USE_BASE_PATH = "writeModulePath";
private static final String PACKAGE_CONTEXT = "packageContext";
private static final String ASYNC_SERVER = "asyncServer";
private static final Map> propertyToSwaggerTypeMapping =
createPropertyToSwaggerTypeMapping();
private String packageGuid = "{" + randomUUID().toString().toUpperCase() + "}";
private final Map dependencies = new HashMap<>();
private final Set parentModels = new HashSet<>();
private final Multimap childrenByParent = ArrayListMultimap.create();
private final BiMap modelNameMapping = HashBiMap.create();
/** If set to true, we will generate c# async endpoints and service interfaces */
private boolean asyncServer = false;
public NancyFXServerCodegen() {
outputFolder = "generated-code" + File.separator + getName();
apiTemplateFiles.put("api.mustache", ".cs");
// Early versions use no prefix for interfaces. Defaulting to I- common practice would break existing users.
setInterfacePrefix("");
// contextually reserved words
setReservedWordsLowerCase(
asList("var", "async", "await", "dynamic", "yield")
);
cliOptions.clear();
// CLI options
addOption(PACKAGE_NAME, "C# package name (convention: Title.Case).", packageName);
addOption(PACKAGE_VERSION, "C# package version.", packageVersion);
addOption(SOURCE_FOLDER, SOURCE_FOLDER_DESC, sourceFolder);
addOption(INTERFACE_PREFIX, INTERFACE_PREFIX_DESC, interfacePrefix);
addOption(OPTIONAL_PROJECT_GUID,OPTIONAL_PROJECT_GUID_DESC, null);
addOption(PACKAGE_CONTEXT, "Optionally overrides the PackageContext which determines the namespace (namespace=packageName.packageContext). If not set, packageContext will default to basePath.", null);
// CLI Switches
addSwitch(SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_BY_REQUIRED_FLAG_DESC, sortParamsByRequiredFlag);
addSwitch(OPTIONAL_PROJECT_FILE, OPTIONAL_PROJECT_FILE_DESC, optionalProjectFileFlag);
addSwitch(USE_DATETIME_OFFSET, USE_DATETIME_OFFSET_DESC, useDateTimeOffsetFlag);
addSwitch(USE_COLLECTION, USE_COLLECTION_DESC, useCollection);
addSwitch(RETURN_ICOLLECTION, RETURN_ICOLLECTION_DESC, returnICollection);
addSwitch(IMMUTABLE_OPTION, "Enabled by default. If disabled generates model classes with setters", true);
addSwitch(USE_BASE_PATH, "Enabled by default. If disabled, module paths will not mirror api base path", true);
addSwitch(ASYNC_SERVER, "Set to true to enable the generation of async routes/endpoints.", this.asyncServer);
typeMapping.putAll(nodaTimeTypesMappings());
languageSpecificPrimitives.addAll(nodaTimePrimitiveTypes());
importMapping.clear();
}
@Override
public CodegenType getTag() {
return SERVER;
}
@Override
public String getName() {
return "nancyfx";
}
@Override
public String getHelp() {
return "Generates a NancyFX Web API server.";
}
@Override
public void processOpts() {
super.processOpts();
apiPackage = isNullOrEmpty(packageName) ? API_NAMESPACE : packageName + "." + API_NAMESPACE;
modelPackage = isNullOrEmpty(packageName) ? MODEL_NAMESPACE : packageName + "." + MODEL_NAMESPACE;
supportingFiles.add(new SupportingFile("parameters.mustache", sourceFile("Utils"), "Parameters.cs"));
supportingFiles.add(new SupportingFile("localDateConverter.mustache", sourceFile("Utils"), "LocalDateConverter.cs"));
supportingFiles.add(new SupportingFile("packages.config.mustache", sourceFolder(), "packages.config"));
supportingFiles.add(new SupportingFile("nuspec.mustache", sourceFolder(), packageName + ".nuspec"));
if (optionalProjectFileFlag) {
supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln"));
supportingFiles.add(new SupportingFile("Project.mustache", sourceFolder(), packageName + ".csproj"));
}
if (additionalProperties.containsKey(OPTIONAL_PROJECT_GUID)) {
setPackageGuid((String) additionalProperties.get(OPTIONAL_PROJECT_GUID));
}
if (additionalProperties.containsKey(ASYNC_SERVER)) {
setAsyncServer(convertPropertyToBooleanAndWriteBack(ASYNC_SERVER));
} else {
additionalProperties.put(ASYNC_SERVER, this.asyncServer);
}
additionalProperties.put("packageGuid", packageGuid);
setupModelTemplate();
processImportedMappings();
appendDependencies();
}
private void setupModelTemplate() {
final Object immutableOption = additionalProperties.get(IMMUTABLE_OPTION);
if (immutableOption != null && "false".equalsIgnoreCase(immutableOption.toString())) {
log.info("Using mutable model template");
modelTemplateFiles.put("modelMutable.mustache", ".cs");
} else {
log.info("Using immutable model template");
modelTemplateFiles.put("model.mustache", ".cs");
}
}
private void processImportedMappings() {
for (final Entry entry : ImmutableSet.copyOf(importMapping.entrySet())) {
final String model = entry.getKey();
final String[] namespaceInfo = entry.getValue().split("\\s");
final String[] namespace = (namespaceInfo.length > 0 ? namespaceInfo[0].trim() : "").split(":");
final String namespaceName = namespace.length > 0 ? namespace[0].trim() : null;
final String modelClass = namespace.length > 1 ? namespace[1].trim() : null;
final String assembly = namespaceInfo.length > 1 ? namespaceInfo[1].trim() : null;
final String assemblyVersion = namespaceInfo.length > 2 ? namespaceInfo[2].trim() : null;
final String assemblyFramework = namespaceInfo.length > 3 ? namespaceInfo[3].trim() : "net45";
if (isNullOrEmpty(model) || isNullOrEmpty(namespaceName)) {
log.warn(String.format("Could not import: '%s' - invalid namespace: '%s'", model, entry.getValue()));
importMapping.remove(model);
} else {
log.info(String.format("Importing: '%s' from '%s' namespace.", model, namespaceName));
importMapping.put(model, namespaceName);
}
if (!isNullOrEmpty(modelClass)) {
log.info(String.format("Mapping: '%s' class to '%s'", model, modelClass));
modelNameMapping.put(model, modelClass);
}
if (assembly != null && assemblyVersion != null) {
log.info(String.format("Adding dependency: '%s', version: '%s', framework: '%s'",
assembly, assemblyVersion, assemblyVersion));
dependencies.put(assembly, new DependencyInfo(assemblyVersion, assemblyFramework));
}
}
}
private void appendDependencies() {
final List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy