From 475205ac08ff21c749c763c668d4466059f15119 Mon Sep 17 00:00:00 2001 From: Jim Schubert Date: Sun, 15 Jan 2017 10:53:24 -0500 Subject: [PATCH] [csharp] Support internal access of generated code Allows users to specify 'nonPublicApi' additional property (and C# client CLI switch) to reduce visibility of classes created by the generator. This includes API and Models as well as supporting code like ApiClient and other infrastructure. The requirement is to support codegen generated code to be embedded within other applications where the generated code is not intended to be publicly consumable or publicy exposed. An example would be an SDK which internally consumes an API via the generated code; we wouldn't want the internal API implementation exposed as part of that SDK. Reducing visibility of the classes effectively makes the entire implementation internal, regardless of the public modifier on methods or static members. To fully make all members internal it would require explicit interface implementation, which is not ideal. see #4401 --- .../io/swagger/codegen/CodegenConstants.java | 3 +++ .../languages/CSharpClientCodegen.java | 23 +++++++++++++++++++ .../main/resources/csharp/ApiClient.mustache | 2 +- .../resources/csharp/ApiException.mustache | 2 +- .../resources/csharp/ApiResponse.mustache | 2 +- .../resources/csharp/Configuration.mustache | 2 +- .../csharp/ExceptionFactory.mustache | 4 ++-- .../resources/csharp/IApiAccessor.mustache | 2 +- .../src/main/resources/csharp/api.mustache | 4 ++-- .../main/resources/csharp/enumClass.mustache | 2 +- .../main/resources/csharp/modelEnum.mustache | 2 +- .../resources/csharp/modelGeneric.mustache | 2 +- .../resources/csharp/modelInnerEnum.mustache | 2 +- .../main/resources/csharp/visibility.mustache | 1 + .../csharp/CSharpClientOptionsTest.java | 2 ++ .../options/CSharpClientOptionsProvider.java | 1 + 16 files changed, 43 insertions(+), 13 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/csharp/visibility.mustache 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..e63f0eb8bfe 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 @@ -141,4 +141,7 @@ public static enum MODEL_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case public static final String GENERATE_PROPERTY_CHANGED = "generatePropertyChanged"; public static final String GENERATE_PROPERTY_CHANGED_DESC = "Specifies that models support raising property changed events."; + + public static final String NON_PUBLIC_API = "nonPublicApi"; + public static final String NON_PUBLIC_API_DESC = "Generates code with reduced access modifiers; allows embedding elsewhere without exposing non-public API calls to consumers."; } 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..ae58242347c 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 @@ -45,6 +45,9 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { protected Map regexModifiers; protected final Map frameworks; + // By default, generated code is considered public + protected boolean nonPublicApi = Boolean.FALSE; + public CSharpClientCodegen() { super(); modelTemplateFiles.put("model.mustache", ".cs"); @@ -126,6 +129,14 @@ public CSharpClientCodegen() { CodegenConstants.PACKAGE_DESCRIPTION_DESC, this.generatePropertyChanged); + // NOTE: This will reduce visibility of all public members in templates. Users can use InternalsVisibleTo + // https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute(v=vs.110).aspx + // to expose to shared code if the generated code is not embedded into another project. Otherwise, users of codegen + // should rely on default public visibility. + addSwitch(CodegenConstants.NON_PUBLIC_API, + CodegenConstants.NON_PUBLIC_API_DESC, + this.nonPublicApi); + regexModifiers = new HashMap(); regexModifiers.put('i', "IgnoreCase"); regexModifiers.put('m', "Multiline"); @@ -228,6 +239,10 @@ public void processOpts() { .get(CodegenConstants.OPTIONAL_ASSEMBLY_INFO).toString())); } + if (additionalProperties.containsKey(CodegenConstants.NON_PUBLIC_API)) { + setNonPublicApi(Boolean.valueOf(additionalProperties.get(CodegenConstants.NON_PUBLIC_API).toString())); + } + final String testPackageName = testPackageName(); String packageFolder = sourceFolder + File.separator + packageName; String clientPackageDir = packageFolder + File.separator + clientPackage; @@ -551,6 +566,14 @@ public void setGeneratePropertyChanged(final Boolean generatePropertyChanged){ this.generatePropertyChanged = generatePropertyChanged; } + public boolean isNonPublicApi() { + return nonPublicApi; + } + + public void setNonPublicApi(final boolean nonPublicApi) { + this.nonPublicApi = nonPublicApi; + } + @Override public String toModelDocFilename(String name) { return toModelFilename(name); diff --git a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache index 33b631280c2..8960ccfe59e 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache @@ -19,7 +19,7 @@ namespace {{packageName}}.Client /// /// API client is mainly responsible for making the HTTP call to the API backend. /// - public partial class ApiClient + {{>visibility}} partial class ApiClient { private JsonSerializerSettings serializerSettings = new JsonSerializerSettings { diff --git a/modules/swagger-codegen/src/main/resources/csharp/ApiException.mustache b/modules/swagger-codegen/src/main/resources/csharp/ApiException.mustache index ad7c2264d78..ca8044580f2 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/ApiException.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/ApiException.mustache @@ -6,7 +6,7 @@ namespace {{packageName}}.Client /// /// API Exception /// - public class ApiException : Exception + {{>visibility}} class ApiException : Exception { /// /// Gets or sets the error code (HTTP status code) diff --git a/modules/swagger-codegen/src/main/resources/csharp/ApiResponse.mustache b/modules/swagger-codegen/src/main/resources/csharp/ApiResponse.mustache index d8c1b79e545..d04575d7ad9 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/ApiResponse.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/ApiResponse.mustache @@ -7,7 +7,7 @@ namespace {{packageName}}.Client /// /// API Response /// - public class ApiResponse + {{>visibility}} class ApiResponse { /// /// Gets or sets the status code (HTTP status code) diff --git a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache index 108b85e48f8..0e1856725df 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache @@ -11,7 +11,7 @@ namespace {{packageName}}.Client /// /// Represents a set of configuration settings /// - public class Configuration + {{>visibility}} class Configuration { /// /// Initializes a new instance of the Configuration class with different settings diff --git a/modules/swagger-codegen/src/main/resources/csharp/ExceptionFactory.mustache b/modules/swagger-codegen/src/main/resources/csharp/ExceptionFactory.mustache index c25b88ee614..f0ebb0b31ce 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/ExceptionFactory.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/ExceptionFactory.mustache @@ -10,6 +10,6 @@ namespace {{packageName}}.Client /// /// Method name /// Response - /// Exceptions - public delegate Exception ExceptionFactory(string methodName, IRestResponse response); + /// Exceptions + {{>visibility}} delegate Exception ExceptionFactory(string methodName, IRestResponse response); } diff --git a/modules/swagger-codegen/src/main/resources/csharp/IApiAccessor.mustache b/modules/swagger-codegen/src/main/resources/csharp/IApiAccessor.mustache index df236b8f8c8..290c9b6ffdc 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/IApiAccessor.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/IApiAccessor.mustache @@ -11,7 +11,7 @@ namespace {{packageName}}.Client /// /// Represents configuration aspects required to interact with the API endpoints. /// - public interface IApiAccessor + {{>visibility}} interface IApiAccessor { /// /// Gets or sets the configuration object diff --git a/modules/swagger-codegen/src/main/resources/csharp/api.mustache b/modules/swagger-codegen/src/main/resources/csharp/api.mustache index f62cabe42e0..6ac9cf7fec6 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 + {{>visibility}} interface I{{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}} + {{>visibility}} partial class {{classname}} : I{{classname}} { private {{packageName}}.Client.ExceptionFactory _exceptionFactory = (name, response) => null; diff --git a/modules/swagger-codegen/src/main/resources/csharp/enumClass.mustache b/modules/swagger-codegen/src/main/resources/csharp/enumClass.mustache index 5249d754577..b11d14cdfc0 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/enumClass.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/enumClass.mustache @@ -3,7 +3,7 @@ /// {{#description}} /// {{{description}}}{{/description}} [JsonConverter(typeof(StringEnumConverter))] - public enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} + {{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#enumVars}} /// diff --git a/modules/swagger-codegen/src/main/resources/csharp/modelEnum.mustache b/modules/swagger-codegen/src/main/resources/csharp/modelEnum.mustache index ff007904f46..b0dfa881eb2 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/modelEnum.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/modelEnum.mustache @@ -3,7 +3,7 @@ /// {{#description}} /// {{{description}}}{{/description}} [JsonConverter(typeof(StringEnumConverter))] - public enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} + {{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#enumVars}} /// diff --git a/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache b/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache index 5e1d0721dc2..09c232acefd 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache @@ -5,7 +5,7 @@ {{#generatePropertyChanged}} [ImplementPropertyChanged] {{/generatePropertyChanged}} - public partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}>, IValidatableObject + {{>visibility}} partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}>, IValidatableObject { {{#vars}} {{#isEnum}} diff --git a/modules/swagger-codegen/src/main/resources/csharp/modelInnerEnum.mustache b/modules/swagger-codegen/src/main/resources/csharp/modelInnerEnum.mustache index 855a710c7ed..d851a2dddc6 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/modelInnerEnum.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/modelInnerEnum.mustache @@ -4,7 +4,7 @@ /// {{#description}} /// {{{description}}}{{/description}} [JsonConverter(typeof(StringEnumConverter))] - public enum {{#datatypeWithEnum}}{{&.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} + {{>visibility}} enum {{#datatypeWithEnum}}{{&.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#enumVars}} /// diff --git a/modules/swagger-codegen/src/main/resources/csharp/visibility.mustache b/modules/swagger-codegen/src/main/resources/csharp/visibility.mustache new file mode 100644 index 00000000000..a1d1f4163d4 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/csharp/visibility.mustache @@ -0,0 +1 @@ +{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} \ No newline at end of file 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..04687543213 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 @@ protected void setExpectations() { times = 1; clientCodegen.setGeneratePropertyChanged(true); times = 1; + clientCodegen.setNonPublicApi(true); + 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..1640ae1db2e 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 Map createOptions() { .put(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES, "true") .put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "true") .put(CodegenConstants.GENERATE_PROPERTY_CHANGED, "true") + .put(CodegenConstants.NON_PUBLIC_API, "true") .build(); }