@@ -12,6 +12,18 @@ private OneOf() {
12
12
}
13
13
14
14
public static void updateModelsOneOf (Map <String , ModelsMap > models , String modelPackage ) {
15
+ // first, propagate the discriminator of allOf to the parent
16
+ for (ModelsMap modelContainer : models .values ()) {
17
+ var model = modelContainer .getModels ().get (0 ).getModel ();
18
+ if (model .getComposedSchemas () != null && model .getComposedSchemas ().getAllOf () != null ) {
19
+ for (CodegenProperty prop : model .getComposedSchemas ().getAllOf ()) {
20
+ if (prop .vendorExtensions .containsKey ("x-discriminator-fields" )) {
21
+ model .vendorExtensions .put ("x-discriminator-fields" , prop .vendorExtensions .get ("x-discriminator-fields" ));
22
+ }
23
+ }
24
+ }
25
+ }
26
+
15
27
for (ModelsMap modelContainer : models .values ()) {
16
28
// modelContainers always have 1 and only 1 model in our specs
17
29
var model = modelContainer .getModels ().get (0 ).getModel ();
@@ -63,7 +75,6 @@ private static void markOneOfChildren(Map<String, ModelsMap> models, CodegenMode
63
75
markCompounds (models , oneOf , oneOfModel , model );
64
76
oneOfList .add (oneOfModel );
65
77
}
66
- oneOfList .sort (comparator ); // have fields with "discriminators" in the start of the list
67
78
model .vendorExtensions .put ("x-one-of-list" , oneOfList );
68
79
}
69
80
@@ -86,8 +97,13 @@ public static void markCompounds(Map<String, ModelsMap> models, String oneOf, Ma
86
97
//noinspection unchecked
87
98
var values = (List <String >) compoundModel .vendorExtensions .get ("x-discriminator-fields" );
88
99
if (values != null ) {
89
- List <Map <String , String >> newValues = values .stream ().map (value -> Collections .singletonMap ("field" , value )).toList ();
90
- oneOfModel .put ("discriminators" , newValues );
100
+ oneOfModel .put ("x-discriminator-fields" , values );
101
+ // find the matching composed schema and assign the discriminator
102
+ for (var m : model .getComposedSchemas ().getOneOf ()) {
103
+ if (m .openApiType .equals (compoundModel .classname )) {
104
+ m .vendorExtensions .put ("x-discriminator-fields" , values );
105
+ }
106
+ }
91
107
}
92
108
}
93
109
@@ -104,29 +120,6 @@ private static boolean isNumberType(String typeName) {
104
120
return typeName .equals ("Int" ) || typeName .equals ("Double" ) || typeName .equals ("Long" );
105
121
}
106
122
107
- public static final Comparator <Map <String , Object >> comparator = (mapA , mapB ) -> {
108
- boolean hasDiscriminatorA = mapA .containsKey ("discriminators" );
109
- boolean hasDiscriminatorB = mapB .containsKey ("discriminators" );
110
- // Maps with "discriminators" come first
111
- if (hasDiscriminatorA && !hasDiscriminatorB ) {
112
- return -1 ;
113
- } else if (!hasDiscriminatorA && hasDiscriminatorB ) {
114
- return 1 ;
115
- } else {
116
- // If both maps have or don't have "discriminators," compare their list lengths
117
- if (hasDiscriminatorA && hasDiscriminatorB ) {
118
- List <?> discriminatorsA = (List <?>) mapA .get ("discriminators" );
119
- List <?> discriminatorsB = (List <?>) mapB .get ("discriminators" );
120
-
121
- // Compare the lengths of the lists
122
- return discriminatorsB .size () - discriminatorsA .size ();
123
- }
124
-
125
- // If the lengths are the same or both maps don't have "discriminators," return 0
126
- return 0 ;
127
- }
128
- };
129
-
130
123
/**
131
124
* Add metadata about oneOfs models (e.g., if it has at least one model, if it has more than one
132
125
* array-subtype, etc.)
@@ -139,6 +132,7 @@ public static void addOneOfMetadata(Map<String, ModelsMap> models) {
139
132
if (isMultiArrayOneOfs (oneOfs )) model .vendorExtensions .put ("x-is-multi-array" , true );
140
133
if (isMultiMapOneOfs (oneOfs )) model .vendorExtensions .put ("x-is-multi-map" , true );
141
134
if (hasAtModelOrEnum (oneOfs )) model .vendorExtensions .put ("x-has-model" , true );
135
+ if (hasDiscriminators (oneOfs )) model .vendorExtensions .put ("x-has-discriminator" , true );
142
136
markOneOfModels (oneOfs );
143
137
sortOneOfs (oneOfs );
144
138
}
@@ -178,6 +172,14 @@ private static boolean hasAtModelOrEnum(List<CodegenProperty> oneOfs) {
178
172
return false ;
179
173
}
180
174
175
+ /** Return true if at least one oneOf has discriminators */
176
+ private static boolean hasDiscriminators (List <CodegenProperty > oneOfs ) {
177
+ for (var prop : oneOfs ) {
178
+ if (prop .vendorExtensions .containsKey ("x-discriminator-fields" )) return true ;
179
+ }
180
+ return false ;
181
+ }
182
+
181
183
/** Mark oneOf models */
182
184
private static void markOneOfModels (List <CodegenProperty > oneOfs ) {
183
185
for (var prop : oneOfs ) {
@@ -201,7 +203,7 @@ private static void sortOneOfs(List<CodegenProperty> oneOfs) {
201
203
return 1 ;
202
204
} else if (hasDiscriminatorA && hasDiscriminatorB ) {
203
205
List <?> discriminatorsA = (List <?>) propA .vendorExtensions .get ("x-discriminator-fields" );
204
- List <?> discriminatorsB = (List <?>) propA .vendorExtensions .get ("x-discriminator-fields" );
206
+ List <?> discriminatorsB = (List <?>) propB .vendorExtensions .get ("x-discriminator-fields" );
205
207
return discriminatorsB .size () - discriminatorsA .size ();
206
208
} else {
207
209
return 0 ;
0 commit comments