From 5e8108d7861dd6b2e8798292fecf6256d531479d Mon Sep 17 00:00:00 2001 From: Kenneth Aasan Date: Mon, 15 Jul 2024 15:35:10 +0200 Subject: [PATCH] feat!: no setters for enums in interfaces for java when allowInheritance is used (#2068) * feat: fake setter for java when allowInheritance is used with const * feat: change to skip rendering override in class and enum in interface --- docs/migrations/version-3-to-4.md | 8 +- .../java/renderers/ClassRenderer.ts | 14 +-- test/generators/java/JavaGenerator.spec.ts | 12 +-- .../__snapshots__/JavaGenerator.spec.ts.snap | 90 +++++++------------ 4 files changed, 52 insertions(+), 72 deletions(-) diff --git a/docs/migrations/version-3-to-4.md b/docs/migrations/version-3-to-4.md index e21906dd62..fc27a2a0d8 100644 --- a/docs/migrations/version-3-to-4.md +++ b/docs/migrations/version-3-to-4.md @@ -226,7 +226,7 @@ class Address: ### Import style deprecation -All models are from this point onwards imported using explicit styles `from . import ${model.name}` to allow for circular model dependencies to work. This means that the option `importsStyle` is deprecated and is no longer in use. It will be removed at some point in the future. +All models are from this point onwards imported using explicit styles `from . import ${model.name}` to allow for circular model dependencies to work. This means that the option `importsStyle` is deprecated and is no longer in use. It will be removed at some point in the future. ## Go @@ -318,3 +318,9 @@ type info struct { isDevelopment *bool } ``` + +## Java + +### when allowInheritance is true, Modelina now don't render the setter for enums in interfaces because the classes that implement the interface might use a constant value + +In Java, when a class implements an interface, it must implement all the methods of that interface. Because of that, Modelina now doesn't render the setter for enums in interfaces when allowInheritance is true because the classes that implement the interface might use a constant value. diff --git a/src/generators/java/renderers/ClassRenderer.ts b/src/generators/java/renderers/ClassRenderer.ts index 2abd8b8c47..a604528148 100644 --- a/src/generators/java/renderers/ClassRenderer.ts +++ b/src/generators/java/renderers/ClassRenderer.ts @@ -10,6 +10,7 @@ import { FormatHelpers } from '../../../helpers'; import { JavaOptions } from '../JavaGenerator'; import { ClassPresetType } from '../JavaPreset'; import { unionIncludesBuiltInTypes } from '../JavaConstrainer'; +import { isEnum } from '../../csharp/Constants'; /** * Renderer for Java's `class` type @@ -200,20 +201,21 @@ export const JAVA_DEFAULT_CLASS_PRESET: ClassPresetType = { if (property.property.options.const?.value) { return ''; } + const setterName = FormatHelpers.toPascalCase(property.propertyName); if (model.options.isExtended) { - if (isDiscriminatorOrDictionary(model, property)) { + // don't render setters for discriminator, dictionary properties, or enums (because they can be set to constants in the models that extend them) + if (isDiscriminatorOrDictionary(model, property) || isEnum(property)) { return ''; } return `public void set${setterName}(${property.property.type} ${property.propertyName});`; } - return `${getOverride(model, property)}public void set${setterName}(${ - property.property.type - } ${property.propertyName}) { this.${property.propertyName} = ${ - property.propertyName - }; }`; + // don't render override for enums because enum setters in the interfaces are not rendered + const override = !isEnum(property) ? getOverride(model, property) : ''; + + return `${override}public void set${setterName}(${property.property.type} ${property.propertyName}) { this.${property.propertyName} = ${property.propertyName}; }`; } }; diff --git a/test/generators/java/JavaGenerator.spec.ts b/test/generators/java/JavaGenerator.spec.ts index ee88e35b71..3b5b2a3b45 100644 --- a/test/generators/java/JavaGenerator.spec.ts +++ b/test/generators/java/JavaGenerator.spec.ts @@ -343,9 +343,6 @@ describe('JavaGenerator', () => { properties: { type: { const: 'Cat' - }, - test: { - $ref: '#/components/schemas/Test' } } } @@ -379,8 +376,10 @@ describe('JavaGenerator', () => { title: 'Test', type: 'object', properties: { - testProp: { - type: 'string' + testEnum: { + title: 'TestEnum', + type: 'string', + enum: ['FOO', 'BAR'] } } }, @@ -391,6 +390,9 @@ describe('JavaGenerator', () => { { type: 'object', properties: { + testEnum: { + const: 'FOO' + }, testProp2: { type: 'string' } diff --git a/test/generators/java/__snapshots__/JavaGenerator.spec.ts.snap b/test/generators/java/__snapshots__/JavaGenerator.spec.ts.snap index f031f078bf..26725d7cd8 100644 --- a/test/generators/java/__snapshots__/JavaGenerator.spec.ts.snap +++ b/test/generators/java/__snapshots__/JavaGenerator.spec.ts.snap @@ -41,7 +41,6 @@ public interface Pet { @Override public CloudEventDotSequenceType getSequencetype() { return this.sequencetype; } - @Override public void setSequencetype(CloudEventDotSequenceType sequencetype) { this.sequencetype = sequencetype; } public String getData() { return this.data; } @@ -157,18 +156,18 @@ public interface Pet { return String.valueOf(value); } }", - "public class TestAllOf { - @JsonProperty(\\"testProp\\") + "public class TestAllOf implements Test { + @JsonProperty(\\"testEnum\\") @JsonInclude(JsonInclude.Include.NON_NULL) - private String testProp; + private final TestEnum testEnum = TestEnum.FOO; @JsonProperty(\\"testProp2\\") @JsonInclude(JsonInclude.Include.NON_NULL) private String testProp2; @JsonInclude(JsonInclude.Include.NON_NULL) private Map additionalProperties; - public String getTestProp() { return this.testProp; } - public void setTestProp(String testProp) { this.testProp = testProp; } + @Override + public TestEnum getTestEnum() { return this.testEnum; } public String getTestProp2() { return this.testProp2; } public void setTestProp2(String testProp2) { this.testProp2 = testProp2; } @@ -186,20 +185,20 @@ public interface Pet { } TestAllOf self = (TestAllOf) o; return - Objects.equals(this.testProp, self.testProp) && + Objects.equals(this.testEnum, self.testEnum) && Objects.equals(this.testProp2, self.testProp2) && Objects.equals(this.additionalProperties, self.additionalProperties); } @Override public int hashCode() { - return Objects.hash((Object)testProp, (Object)testProp2, (Object)additionalProperties); + return Objects.hash((Object)testEnum, (Object)testProp2, (Object)additionalProperties); } @Override public String toString() { return \\"class TestAllOf {\\\\n\\" + - \\" testProp: \\" + toIndentedString(testProp) + \\"\\\\n\\" + + \\" testEnum: \\" + toIndentedString(testEnum) + \\"\\\\n\\" + \\" testProp2: \\" + toIndentedString(testProp2) + \\"\\\\n\\" + \\" additionalProperties: \\" + toIndentedString(additionalProperties) + \\"\\\\n\\" + \\"}\\"; @@ -216,63 +215,43 @@ public interface Pet { return o.toString().replace(\\"\\\\n\\", \\"\\\\n \\"); } }", - "public class Test { - @JsonProperty(\\"testProp\\") - @JsonInclude(JsonInclude.Include.NON_NULL) - private String testProp; - @JsonInclude(JsonInclude.Include.NON_NULL) - private Map additionalProperties; + "public enum TestEnum { + FOO((String)\\"FOO\\"), BAR((String)\\"BAR\\"); - public String getTestProp() { return this.testProp; } - public void setTestProp(String testProp) { this.testProp = testProp; } + private String value; - public Map getAdditionalProperties() { return this.additionalProperties; } - public void setAdditionalProperties(Map additionalProperties) { this.additionalProperties = additionalProperties; } + TestEnum(String value) { + this.value = value; + } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Test self = (Test) o; - return - Objects.equals(this.testProp, self.testProp) && - Objects.equals(this.additionalProperties, self.additionalProperties); + @JsonValue + public String getValue() { + return value; } - @Override - public int hashCode() { - return Objects.hash((Object)testProp, (Object)additionalProperties); + @JsonCreator + public static TestEnum fromValue(String value) { + for (TestEnum e : TestEnum.values()) { + if (e.value.equals(value)) { + return e; + } + } + throw new IllegalArgumentException(\\"Unexpected value '\\" + value + \\"'\\"); } @Override public String toString() { - return \\"class Test {\\\\n\\" + - \\" testProp: \\" + toIndentedString(testProp) + \\"\\\\n\\" + - \\" additionalProperties: \\" + toIndentedString(additionalProperties) + \\"\\\\n\\" + - \\"}\\"; - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return \\"null\\"; - } - return o.toString().replace(\\"\\\\n\\", \\"\\\\n \\"); + return String.valueOf(value); } +}", + "public interface Test { + public TestEnum getTestEnum(); }", "public interface CloudEvent { public String getId(); public void setId(String id); public CloudEventDotSequenceType getSequencetype(); - public void setSequencetype(CloudEventDotSequenceType sequencetype); }", "public class Cat implements Pet, CloudEvent { @NotNull @@ -284,9 +263,6 @@ public interface Pet { @JsonProperty(\\"sequencetype\\") @JsonInclude(JsonInclude.Include.NON_NULL) private CloudEventDotSequenceType sequencetype; - @JsonProperty(\\"test\\") - @JsonInclude(JsonInclude.Include.NON_NULL) - private Test test; @JsonInclude(JsonInclude.Include.NON_NULL) private Map additionalProperties; @@ -299,12 +275,8 @@ public interface Pet { @Override public CloudEventDotSequenceType getSequencetype() { return this.sequencetype; } - @Override public void setSequencetype(CloudEventDotSequenceType sequencetype) { this.sequencetype = sequencetype; } - public Test getTest() { return this.test; } - public void setTest(Test test) { this.test = test; } - public Map getAdditionalProperties() { return this.additionalProperties; } public void setAdditionalProperties(Map additionalProperties) { this.additionalProperties = additionalProperties; } @@ -321,13 +293,12 @@ public interface Pet { Objects.equals(this.id, self.id) && Objects.equals(this.type, self.type) && Objects.equals(this.sequencetype, self.sequencetype) && - Objects.equals(this.test, self.test) && Objects.equals(this.additionalProperties, self.additionalProperties); } @Override public int hashCode() { - return Objects.hash((Object)id, (Object)type, (Object)sequencetype, (Object)test, (Object)additionalProperties); + return Objects.hash((Object)id, (Object)type, (Object)sequencetype, (Object)additionalProperties); } @Override @@ -336,7 +307,6 @@ public interface Pet { \\" id: \\" + toIndentedString(id) + \\"\\\\n\\" + \\" type: \\" + toIndentedString(type) + \\"\\\\n\\" + \\" sequencetype: \\" + toIndentedString(sequencetype) + \\"\\\\n\\" + - \\" test: \\" + toIndentedString(test) + \\"\\\\n\\" + \\" additionalProperties: \\" + toIndentedString(additionalProperties) + \\"\\\\n\\" + \\"}\\"; }