From 663b471d1a49832b60ada7ffaf98d8e37c84e6ed Mon Sep 17 00:00:00 2001 From: Jim Schubert Date: Sun, 15 Jan 2017 09:35:43 -0600 Subject: [PATCH] [nancyfx/csharp] Customize interface prefix (#4557) Per #4486, this allows user to specify the use of a standard or custom prefix for interfaces. For C# based languages, this follows Microsoft's Framework Design Guidelines and uses an I- prefix. However, to avoid breaking changes with existing nancyfx generated code, the default is unset. The option supports true, false, or a custom prefix. --- bin/nancyfx-petstore-server.sh | 2 +- .../io/swagger/codegen/CodegenConstants.java | 3 +++ .../languages/AbstractCSharpCodegen.java | 22 +++++++++++++++++++ .../languages/CSharpClientCodegen.java | 4 ++++ .../languages/NancyFXServerCodegen.java | 19 +++++----------- .../src/main/resources/csharp/api.mustache | 4 ++-- .../src/main/resources/nancyfx/api.mustache | 4 ++-- .../csharp/CSharpClientOptionsTest.java | 2 ++ .../options/CSharpClientOptionsProvider.java | 1 + .../options/NancyFXServerOptionsProvider.java | 11 +++------- 10 files changed, 45 insertions(+), 27 deletions(-) diff --git a/bin/nancyfx-petstore-server.sh b/bin/nancyfx-petstore-server.sh index 20797fa0c1f..2b9b2994cbf 100755 --- a/bin/nancyfx-petstore-server.sh +++ b/bin/nancyfx-petstore-server.sh @@ -26,6 +26,6 @@ fi # if you've executed sbt assembly previously it will use that instead. export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" -ags="$@ generate -t modules/swagger-codegen/src/main/resources/nancyfx -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l nancyfx -o samples/server/petstore/nancyfx" +ags="generate $@ -t modules/swagger-codegen/src/main/resources/nancyfx -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l nancyfx -o samples/server/petstore/nancyfx" java $JAVA_OPTS -jar $executable $ags diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java index 094ff38e8fd..f5c759d4d04 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java @@ -86,6 +86,9 @@ public class CodegenConstants { public static final String USE_COLLECTION = "useCollection"; public static final String USE_COLLECTION_DESC = "Deserialize array types to Collection instead of List."; + public static final String INTERFACE_PREFIX = "interfacePrefix"; + public static final String INTERFACE_PREFIX_DESC = "Prefix interfaces with a community standard or widely accepted prefix."; + public static final String RETURN_ICOLLECTION = "returnICollection"; public static final String RETURN_ICOLLECTION_DESC = "Return ICollection instead of the concrete type."; diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java index 71c35053988..746edebc9ca 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java @@ -27,6 +27,8 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co protected String packageCompany = "Swagger"; protected String packageCopyright = "No Copyright"; + protected String interfacePrefix = "I"; + protected String sourceFolder = "src"; // TODO: Add option for test folder output location. Nice to allow e.g. ./test instead of ./src. @@ -254,6 +256,18 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES)) { setOptionalEmitDefaultValue(Boolean.valueOf(additionalProperties.get(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES).toString())); } + + if (additionalProperties.containsKey(CodegenConstants.INTERFACE_PREFIX)) { + String useInterfacePrefix = additionalProperties.get(CodegenConstants.INTERFACE_PREFIX).toString(); + if("false".equals(useInterfacePrefix)) { + setInterfacePrefix(""); + } else if(!"true".equals(useInterfacePrefix)) { + // NOTE: if user passes "true" explicitly, we use the default I- prefix. The other supported case here is a custom prefix. + setInterfacePrefix(sanitizeName(useInterfacePrefix)); + } + + additionalProperties.put(CodegenConstants.INTERFACE_PREFIX, interfacePrefix); + } } @Override @@ -616,6 +630,14 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co this.sourceFolder = sourceFolder; } + public String getInterfacePrefix() { + return interfacePrefix; + } + + public void setInterfacePrefix(final String interfacePrefix) { + this.interfacePrefix = interfacePrefix; + } + @Override public String toEnumVarName(String name, String datatype) { if (name.length() == 0) { diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java index c70749392cf..cf4bc656d83 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java @@ -72,6 +72,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { CodegenConstants.OPTIONAL_PROJECT_GUID_DESC, null); + addOption(CodegenConstants.INTERFACE_PREFIX, + CodegenConstants.INTERFACE_PREFIX_DESC, + interfacePrefix); + CliOption framework = new CliOption( CodegenConstants.DOTNET_FRAMEWORK, CodegenConstants.DOTNET_FRAMEWORK_DESC diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index 44f31b25eb6..ace3ccaa4e2 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -1,20 +1,7 @@ package io.swagger.codegen.languages; import static com.google.common.base.Strings.isNullOrEmpty; -import static io.swagger.codegen.CodegenConstants.OPTIONAL_PROJECT_FILE; -import static io.swagger.codegen.CodegenConstants.OPTIONAL_PROJECT_FILE_DESC; -import static io.swagger.codegen.CodegenConstants.PACKAGE_NAME; -import static io.swagger.codegen.CodegenConstants.PACKAGE_VERSION; -import static io.swagger.codegen.CodegenConstants.RETURN_ICOLLECTION; -import static io.swagger.codegen.CodegenConstants.RETURN_ICOLLECTION_DESC; -import static io.swagger.codegen.CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG; -import static io.swagger.codegen.CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC; -import static io.swagger.codegen.CodegenConstants.SOURCE_FOLDER; -import static io.swagger.codegen.CodegenConstants.SOURCE_FOLDER_DESC; -import static io.swagger.codegen.CodegenConstants.USE_COLLECTION; -import static io.swagger.codegen.CodegenConstants.USE_COLLECTION_DESC; -import static io.swagger.codegen.CodegenConstants.USE_DATETIME_OFFSET; -import static io.swagger.codegen.CodegenConstants.USE_DATETIME_OFFSET_DESC; +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; @@ -71,6 +58,9 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { 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") @@ -82,6 +72,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { 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); // CLI Switches addSwitch(SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_BY_REQUIRED_FLAG_DESC, sortParamsByRequiredFlag); diff --git a/modules/swagger-codegen/src/main/resources/csharp/api.mustache b/modules/swagger-codegen/src/main/resources/csharp/api.mustache index f62cabe42e0..18c949980cb 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/api.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/api.mustache @@ -14,7 +14,7 @@ namespace {{packageName}}.{{apiPackage}} /// /// Represents a collection of functions to interact with the API endpoints /// - public interface I{{classname}} : IApiAccessor + public interface {{interfacePrefix}}{{classname}} : IApiAccessor { #region Synchronous Operations {{#operation}} @@ -73,7 +73,7 @@ namespace {{packageName}}.{{apiPackage}} /// /// Represents a collection of functions to interact with the API endpoints /// - public partial class {{classname}} : I{{classname}} + public partial class {{classname}} : {{interfacePrefix}}{{classname}} { private {{packageName}}.Client.ExceptionFactory _exceptionFactory = (name, response) => null; diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index b4213ff2056..3aca8b8855e 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -40,7 +40,7 @@ namespace {{packageName}}.{{packageContext}}.Modules /// /// Service handling {{classname}} requests. /// - public interface {{classname}}Service + public interface {{interfacePrefix}}{{classname}}Service { {{#operation}}/// /// {{notes}} @@ -56,7 +56,7 @@ namespace {{packageName}}.{{packageContext}}.Modules /// /// Abstraction of {{classname}}Service. /// - public abstract class Abstract{{classname}}Service: {{classname}}Service + public abstract class Abstract{{classname}}Service: {{interfacePrefix}}{{classname}}Service { {{#operation}}public virtual {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}(NancyContext context{{#allParams.0}}, {{/allParams.0}}{{>paramsList}}) { diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CSharpClientOptionsTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CSharpClientOptionsTest.java index f53ac5e0626..8bc55f211be 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CSharpClientOptionsTest.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CSharpClientOptionsTest.java @@ -50,6 +50,8 @@ public class CSharpClientOptionsTest extends AbstractOptionsTest { times = 1; clientCodegen.setGeneratePropertyChanged(true); times = 1; + clientCodegen.setInterfacePrefix("X"); + times = 1; }}; } } diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/CSharpClientOptionsProvider.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/CSharpClientOptionsProvider.java index a438a31e2b7..9bbc6512911 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/CSharpClientOptionsProvider.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/CSharpClientOptionsProvider.java @@ -35,6 +35,7 @@ public class CSharpClientOptionsProvider implements OptionsProvider { .put(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES, "true") .put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "true") .put(CodegenConstants.GENERATE_PROPERTY_CHANGED, "true") + .put(CodegenConstants.INTERFACE_PREFIX, "X") .build(); } diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java index 77a374f648e..4185de846c7 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java @@ -1,17 +1,11 @@ package io.swagger.codegen.options; -import static io.swagger.codegen.CodegenConstants.PACKAGE_NAME; -import static io.swagger.codegen.CodegenConstants.PACKAGE_VERSION; -import static io.swagger.codegen.CodegenConstants.RETURN_ICOLLECTION; -import static io.swagger.codegen.CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG; -import static io.swagger.codegen.CodegenConstants.SOURCE_FOLDER; -import static io.swagger.codegen.CodegenConstants.USE_COLLECTION; -import static io.swagger.codegen.CodegenConstants.USE_DATETIME_OFFSET; - import java.util.Map; import com.google.common.collect.ImmutableMap; +import static io.swagger.codegen.CodegenConstants.*; + public class NancyFXServerOptionsProvider implements OptionsProvider { public static final String PACKAGE_NAME_VALUE = "swagger_server_nancyfx"; public static final String PACKAGE_VERSION_VALUE = "1.0.0-SNAPSHOT"; @@ -32,6 +26,7 @@ public class NancyFXServerOptionsProvider implements OptionsProvider { .put(USE_DATETIME_OFFSET, "true") .put(USE_COLLECTION, "false") .put(RETURN_ICOLLECTION, "false") + .put(INTERFACE_PREFIX, "X") .build(); }