Skip to content

Commit a400d76

Browse files
authored
fix(java-gen): handle multiple colliding enums (#5853)
* [java-gen] Handle multiple colliding enums * CHANGELOG.md * sonar * minor
1 parent 8545034 commit a400d76

File tree

7 files changed

+75
-6
lines changed

7 files changed

+75
-6
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
### 6.12-SNAPSHOT
44

55
#### Bugs
6+
* Fix #5853: [java-generator] Gracefully handle colliding enum definitions
67

78
#### Improvements
89

java-generator/core/src/main/java/io/fabric8/java/generator/nodes/JEnum.java

+16-4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import java.util.ArrayList;
2828
import java.util.Collections;
29+
import java.util.HashSet;
2930
import java.util.LinkedHashSet;
3031
import java.util.List;
3132
import java.util.Locale;
@@ -96,16 +97,27 @@ public GeneratorResult generateJava() {
9697
.setBody(new BlockStmt().addStatement(new ReturnStmt(VALUE)));
9798
getValue.addAnnotation("com.fasterxml.jackson.annotation.JsonValue");
9899

99-
for (String k : this.values) {
100-
String constantName;
100+
Set<String> constantNames = new HashSet<>(values.size());
101+
for (String k : values) {
102+
StringBuilder constantNameBuilder = new StringBuilder();
101103
try {
102104
// If the value can be parsed as an Integer
103105
Integer.valueOf(k);
104106
// Prepend
105-
constantName = "V_" + sanitizeEnumEntry(sanitizeString(k));
107+
constantNameBuilder.append("V_" + sanitizeEnumEntry(sanitizeString(k)));
106108
} catch (Exception e) {
107-
constantName = sanitizeEnumEntry(sanitizeString(k));
109+
constantNameBuilder.append(sanitizeEnumEntry(sanitizeString(k)));
108110
}
111+
// enums with colliding names are bad practice, we should make sure that the resulting code compiles,
112+
// but we don't need fancy heuristics for the naming let's just prepend an underscore until it works
113+
while (constantNames.contains(constantNameBuilder.toString())) {
114+
String tmp = constantNameBuilder.toString();
115+
constantNameBuilder.setLength(0);
116+
constantNameBuilder.append("_" + tmp);
117+
}
118+
String constantName = constantNameBuilder.toString();
119+
constantNames.add(constantName);
120+
109121
String originalName = AbstractJSONSchema2Pojo.escapeQuotes(k);
110122
Expression valueArgument = new StringLiteralExpr(originalName);
111123
if (!underlyingType.equals(JAVA_LANG_STRING)) {

java-generator/core/src/test/java/io/fabric8/java/generator/CompilationTest.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ private static Stream<Arguments> compilationTestData() {
7070
Arguments.of("two-crds.yml", 6),
7171
Arguments.of("folder", 6),
7272
Arguments.of("calico-ippool-crd.yml", 3),
73-
Arguments.of("emissary-crds.yaml", 242));
73+
Arguments.of("emissary-crds.yaml", 242),
74+
Arguments.of("colliding-enums-crd.yml", 2));
7475
}
7576

7677
@ParameterizedTest(name = "{0} should generate {1} source files and compile OK")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#
2+
# Copyright (C) 2015 Red Hat, Inc.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
apiVersion: apiextensions.k8s.io/v1
18+
kind: CustomResourceDefinition
19+
metadata:
20+
name: collidingenums.example.com
21+
spec:
22+
group: example.com
23+
versions:
24+
- name: v1
25+
served: true
26+
storage: true
27+
schema:
28+
openAPIV3Schema:
29+
type: object
30+
properties:
31+
spec:
32+
properties:
33+
myenum:
34+
items:
35+
enum:
36+
- one
37+
- One
38+
- onE
39+
- OnE
40+
- oNe
41+
type: string
42+
type: array
43+
type: object
44+
scope: Namespaced
45+
names:
46+
plural: collidingenums
47+
singular: collidingenum
48+
kind: Collidingenum

java-generator/it/src/it/ser-deser/src/test/java/io/fabric8/it/certmanager/TestSerialization.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,14 @@ void testDeserialization() {
5050
List<CertificateRequestSpec.Usages> usagesList = sample.getSpec().getUsages();
5151

5252
// Assert
53-
assertEquals(5, usagesList.size());
53+
assertEquals(7, usagesList.size());
5454
assertEquals(CertificateRequestSpec.Usages._EMPTY, usagesList.get(0));
5555
assertEquals(CertificateRequestSpec.Usages.SIGNING, usagesList.get(1));
5656
assertEquals(CertificateRequestSpec.Usages.DIGITAL_SIGNATURE, usagesList.get(2));
5757
assertEquals(CertificateRequestSpec.Usages.SERVER_AUTH, usagesList.get(3));
5858
assertEquals(CertificateRequestSpec.Usages.S_MIME, usagesList.get(4));
59+
assertEquals(CertificateRequestSpec.Usages.ANOTHER, usagesList.get(5));
60+
assertEquals(CertificateRequestSpec.Usages.__ANOTHER, usagesList.get(6));
5961

6062
assertEquals(datetimeValue, sample.getSpec().getDatetime());
6163
}

java-generator/it/src/it/ser-deser/src/test/resources/cert-manager.crds.1.7.1.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ spec:
182182
- ocsp signing
183183
- microsoft sgc
184184
- netscape sgc
185+
- another
186+
- Another
187+
- anotheR
185188
username:
186189
description: Username contains the name of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable.
187190
type: string

java-generator/it/src/it/ser-deser/src/test/resources/sample1.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ spec:
2828
- digital signature
2929
- server auth
3030
- s/mime
31+
- another
32+
- anotheR
3133
duration: 2160h
3234
issuerRef:
3335
name: ca-issuer

0 commit comments

Comments
 (0)