diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpNancyFXServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpNancyFXServerCodegen.java new file mode 100644 index 00000000000..07819c98d75 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpNancyFXServerCodegen.java @@ -0,0 +1,418 @@ +package org.openapitools.codegen.languages; + +import static com.google.common.base.Strings.isNullOrEmpty; +import static org.apache.commons.lang3.StringUtils.capitalize; +import static org.openapitools.codegen.CodegenConstants.*; +import static org.openapitools.codegen.CodegenType.SERVER; +import static java.util.Arrays.asList; +import static java.util.UUID.randomUUID; + +import org.openapitools.codegen.*; +import org.openapitools.codegen.utils.*; +import org.openapitools.codegen.mustache.*; +import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.oas.models.*; +import io.swagger.v3.oas.models.media.*; +import io.swagger.v3.oas.models.responses.ApiResponse; +import io.swagger.v3.oas.models.parameters.*; +import io.swagger.v3.core.util.Yaml; +import io.swagger.v3.parser.util.SchemaTypeUtil; + +import java.io.File; +import java.net.URL; +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 CSharpNancyFXServerCodegen extends AbstractCSharpCodegen { + private static final Logger LOGGER = LoggerFactory.getLogger(CSharpNancyFXServerCodegen.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> propertyToOpenAPITypeMapping = + createPropertyToOpenAPITypeMapping(); + + 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 CSharpNancyFXServerCodegen() { + 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 "csharp-nancyfx"; + } + + @Override + public String getHelp() { + return "Generates a C# 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())) { + LOGGER.info("Using mutable model template"); + modelTemplateFiles.put("modelMutable.mustache", ".cs"); + } else { + LOGGER.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)) { + LOGGER.warn(String.format("Could not import: '%s' - invalid namespace: '%s'", model, entry.getValue())); + importMapping.remove(model); + } else { + LOGGER.info(String.format("Importing: '%s' from '%s' namespace.", model, namespaceName)); + importMapping.put(model, namespaceName); + } + if (!isNullOrEmpty(modelClass)) { + LOGGER.info(String.format("Mapping: '%s' class to '%s'", model, modelClass)); + modelNameMapping.put(model, modelClass); + } + if (assembly != null && assemblyVersion != null) { + LOGGER.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> listOfDependencies = new ArrayList<>(); + for (final Entry dependency : dependencies.entrySet()) { + final Map dependencyInfo = new HashMap<>(); + dependencyInfo.put("dependency", dependency.getKey()); + dependencyInfo.put("dependencyVersion", dependency.getValue().version); + dependencyInfo.put("dependencyFramework", dependency.getValue().framework); + listOfDependencies.add(dependencyInfo); + } + additionalProperties.put("dependencies", listOfDependencies); + } + + private String sourceFolder() { + return "src" + File.separator + packageName; + } + + private String sourceFile(final String fileName) { + return sourceFolder() + File.separator + fileName; + } + + public void setPackageGuid(String packageGuid) { + this.packageGuid = packageGuid; + } + + public void setAsyncServer(boolean asyncServer) { + this.asyncServer = asyncServer; + } + + @Override + public String apiFileFolder() { + return outputFolder + File.separator + sourceFolder() + File.separator + API_NAMESPACE; + } + + @Override + public String modelFileFolder() { + return outputFolder + File.separator + sourceFolder() + File.separator + MODEL_NAMESPACE; + } + + @Override + protected void processOperation(final CodegenOperation operation) { + super.processOperation(operation); + if (!isNullOrEmpty(operation.path) && operation.path.contains("?")) { + operation.path = operation.path.replace("?", "/"); + } + if (!isNullOrEmpty(operation.httpMethod)) { + operation.httpMethod = capitalize(operation.httpMethod.toLowerCase()); + } + } + + @Override + public Map postProcessAllModels(final Map models) { + final Map processed = super.postProcessAllModels(models); + postProcessParentModels(models); + return processed; + } + + private void postProcessParentModels(final Map models) { + LOGGER.debug("Processing parents: " + parentModels); + for (final String parent : parentModels) { + final CodegenModel parentModel = ModelUtils.getModelByName(parent, models); + parentModel.hasChildren = true; + final Collection childrenModels = childrenByParent.get(parent); + for (final CodegenModel child : childrenModels) { + processParentPropertiesInChildModel(parentModel, child); + } + } + } + + private void processParentPropertiesInChildModel(final CodegenModel parent, final CodegenModel child) { + final Map childPropertiesByName = new HashMap<>(child.vars.size()); + for (final CodegenProperty property : child.vars) { + childPropertiesByName.put(property.name, property); + } + CodegenProperty previousParentVar = null; + for (final CodegenProperty property : parent.vars) { + final CodegenProperty duplicatedByParent = childPropertiesByName.get(property.name); + if (duplicatedByParent != null) { + LOGGER.info(String.format("Property: '%s' in '%s' model is inherited from '%s'" , + property.name, child.classname, parent.classname)); + duplicatedByParent.isInherited = true; + final CodegenProperty parentVar = duplicatedByParent.clone(); + parentVar.hasMore = false; + child.parentVars.add(parentVar); + if (previousParentVar != null) { + previousParentVar.hasMore = true; + } + previousParentVar = parentVar; + } + } + } + + @Override + public void postProcessModelProperty(final CodegenModel model, final CodegenProperty property) { + super.postProcessModelProperty(model, property); + if (!isNullOrEmpty(model.parent)) { + parentModels.add(model.parent); + if (!childrenByParent.containsEntry(model.parent, model)) { + childrenByParent.put(model.parent, model); + } + } + } + + @Override + public String toEnumVarName(final String name, final String datatype) { + if (name.length() == 0) { + return "Empty"; + } + + final String enumName = camelize( + sanitizeName(name) + .replaceFirst("^_", "") + .replaceFirst("_$", "") + .replaceAll("-", "_")); + final String result; + if (enumName.matches("\\d.*")) { + result = "_" + enumName; + } else { + result = enumName; + } + LOGGER.debug(String.format("toEnumVarName('%s', %s) = '%s'", name, datatype, enumName)); + return result; + } + + @Override + public String toApiName(final String name) { + final String apiName; + if (isNullOrEmpty(name)) { + apiName = "Default"; + } else { + apiName = capitalize(name); + } + LOGGER.debug(String.format("toApiName('%s') = '%s'", name, apiName)); + return apiName; + } + + @Override + public String toApiFilename(final String name) { + return super.toApiFilename(name) + "Module"; + } + + @Override + public String toModelImport(final String name) { + final String result; + if (modelNameMapping.containsValue(name)) { + final String modelName = modelNameMapping.inverse().get(name); + result = importMapping.containsKey(modelName) ? + importMapping.get(modelName) : super.toModelImport(name); + } else if (importMapping.containsKey(name)) { + result = importMapping.get(name); + } else { + result = null; + } + LOGGER.debug(String.format("toModelImport('%s') = '%s'", name, result)); + return result; + } + + @Override + public String toModelName(final String name) { + final String modelName = super.toModelName(name); + final String mappedModelName = modelNameMapping.get(modelName); + return isNullOrEmpty(mappedModelName) ? modelName: mappedModelName; + } + + @Override + public void preprocessOpenAPI(final OpenAPI openAPI) { + URL url = URLPathUtil.getServerURL(openAPI); + String path = "/"; + if(url != null) { + path = url.getPath(); + } + final String packageContextOption = (String) additionalProperties.get(PACKAGE_CONTEXT); + additionalProperties.put("packageContext", packageContextOption == null ? sanitizeName(path) : packageContextOption); + final Object basePathOption = additionalProperties.get(USE_BASE_PATH); + additionalProperties.put("baseContext", basePathOption == null ? path : "/"); + } + + @Override + public String toEnumName(final CodegenProperty property) { + return sanitizeName(camelize(property.name)) + "Enum"; + } + + @Override + public String getSchemaType(final Schema property) { + for (Entry> entry : propertyToOpenAPITypeMapping.entrySet()) { + if (entry.getValue().apply(property)) { + return entry.getKey(); + } + } + return super.getSchemaType(property); + } + + private static Map> createPropertyToOpenAPITypeMapping() { + final ImmutableMap.Builder> mapping = ImmutableMap.builder(); + mapping.put("time", timeProperty()); + return mapping.build(); + } + + private static Predicate timeProperty() { + return new Predicate() { + @Override + public boolean apply(Schema property) { + return property instanceof StringSchema && "time".equalsIgnoreCase(property.getFormat()); + } + }; + } + private static Map nodaTimeTypesMappings() { + return ImmutableMap.of( + "time", "LocalTime?", + "date", "LocalDate?", + "datetime", "ZonedDateTime?"); + } + + private static Set nodaTimePrimitiveTypes() { + return ImmutableSet.of("LocalTime?", "LocalDate?","ZonedDateTime?"); + } + + private class DependencyInfo { + private final String version; + private final String framework; + + private DependencyInfo(final String version, final String framework) { + this.version = version; + this.framework = framework; + } + } +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/utils/URLPathUtil.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/URLPathUtil.java similarity index 99% rename from modules/openapi-generator/src/main/java/org/openapitools/utils/URLPathUtil.java rename to modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/URLPathUtil.java index 895229a4257..5626c646d5d 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/utils/URLPathUtil.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/URLPathUtil.java @@ -55,4 +55,4 @@ public class URLPathUtil { } return LOCAL_HOST; } -} +} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig index 98f89a93030..e38ab05690c 100644 --- a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig +++ b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig @@ -10,6 +10,7 @@ org.openapitools.codegen.languages.CppRestClientCodegen org.openapitools.codegen.languages.CppPistacheServerCodegen org.openapitools.codegen.languages.CSharpClientCodegen org.openapitools.codegen.languages.CSharpDotNet2ClientCodegen +org.openapitools.codegen.languages.CSharpNancyFXServerCodegen org.openapitools.codegen.languages.DartClientCodegen org.openapitools.codegen.languages.ElixirClientCodegen org.openapitools.codegen.languages.KotlinClientCodegen @@ -29,7 +30,6 @@ org.openapitools.codegen.languages.PhpZendExpressivePathHandlerServerCodegen org.openapitools.codegen.languages.PowerShellClientCodegen org.openapitools.codegen.languages.PythonClientCodegen org.openapitools.codegen.languages.PythonFlaskConnexionServerCodegen -org.openapitools.codegen.languages.Qt5CPPClientCodegen org.openapitools.codegen.languages.RClientCodegen org.openapitools.codegen.languages.RubyOnRailsServerCodegen org.openapitools.codegen.languages.RubyClientCodegen diff --git a/modules/openapi-generator/src/main/resources/nancyfx/Project.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/Project.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/Project.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/Project.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/Solution.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/Solution.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/Solution.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/Solution.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/api.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/api.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/api.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/api.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/innerApiEnum.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/innerApiEnum.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/innerApiEnum.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/innerApiEnum.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/innerApiEnumName.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/innerApiEnumName.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/innerApiEnumName.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/innerApiEnumName.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/innerModelEnum.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/innerModelEnum.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/innerModelEnum.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/innerModelEnum.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/innerParameterType.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/innerParameterType.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/innerParameterType.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/innerParameterType.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/innerParameterValueOfArgs.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/innerParameterValueOfArgs.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/innerParameterValueOfArgs.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/innerParameterValueOfArgs.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/localDateConverter.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/localDateConverter.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/localDateConverter.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/localDateConverter.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/model.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/model.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/model.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/model.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/modelEnum.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/modelEnum.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/modelEnum.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/modelEnum.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/modelGeneric.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/modelGeneric.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/modelGeneric.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/modelGeneric.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/modelMutable.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/modelMutable.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/modelMutable.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/modelMutable.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/nullableDataType.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/nullableDataType.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/nullableDataType.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/nullableDataType.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/nuspec.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/nuspec.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/nuspec.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/nuspec.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/packages.config.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/packages.config.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/packages.config.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/packages.config.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/parameters.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/parameters.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/parameters.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/parameters.mustache diff --git a/modules/openapi-generator/src/main/resources/nancyfx/paramsList.mustache b/modules/openapi-generator/src/main/resources/csharp-nancyfx/paramsList.mustache similarity index 100% rename from modules/openapi-generator/src/main/resources/nancyfx/paramsList.mustache rename to modules/openapi-generator/src/main/resources/csharp-nancyfx/paramsList.mustache