@@ -150,82 +150,115 @@ public JType apply(
150
150
ruleFactory .getEnumRule ().apply (nodeName , schemaNode , parent , generatableType , schema );
151
151
} else if (!schemaNode .has ("properties" ) && unionTypes .isEmpty () && refType .isPresent ()) {
152
152
javaType = refType .get ();
153
+ } else if (!unionTypes .isEmpty ()) {
154
+ JPackage container = generatableType .getPackage ();
155
+ JType generatedType =
156
+ ruleFactory .getTypeRule ().apply (nodeName , schemaNode , parent , container , schema );
157
+ try {
158
+ JDefinedClass unionClass ;
159
+ Optional <JType > commonType ;
160
+ if (generatedType instanceof JDefinedClass ) {
161
+ JDefinedClass clazz = (JDefinedClass ) generatedType ;
162
+ if (clazz .methods ().isEmpty ()) {
163
+ unionClass = clazz ;
164
+ commonType = Optional .empty ();
165
+ } else {
166
+ unionClass = container ._class (clazz .name () + "Union" );
167
+ commonType = Optional .of (clazz );
168
+ }
153
169
170
+ } else {
171
+ unionClass =
172
+ container ._class (
173
+ ruleFactory .getNameHelper ().getUniqueClassName (nodeName , schemaNode , container ));
174
+ commonType = Optional .empty ();
175
+ }
176
+ javaType =
177
+ populateRef (populateClass (schema , unionClass , commonType , unionTypes ), refType , schema );
178
+ schema .setJavaTypeIfEmpty (javaType );
179
+ } catch (JClassAlreadyExistsException ex ) {
180
+ throw new IllegalStateException (ex );
181
+ }
154
182
} else {
155
183
javaType =
156
184
ruleFactory
157
185
.getTypeRule ()
158
186
.apply (nodeName , schemaNode , parent , generatableType .getPackage (), schema );
159
187
if (javaType instanceof JDefinedClass ) {
160
- populateClass (schema , (JDefinedClass ) javaType , refType , unionTypes );
161
- } else if (!unionTypes .isEmpty ()) {
162
- javaType =
163
- createUnionClass (
164
- schema , nodeName , schemaNode , generatableType .getPackage (), refType , unionTypes );
188
+ populateRef ((JDefinedClass ) javaType , refType , schema );
165
189
}
166
190
schema .setJavaTypeIfEmpty (javaType );
167
191
}
192
+
168
193
return javaType ;
169
194
}
170
195
171
196
private JDefinedClass populateClass (
172
197
Schema parentSchema ,
173
198
JDefinedClass definedClass ,
174
- Optional <JType > refType ,
199
+ Optional <JType > commonType ,
175
200
Collection <JTypeWrapper > unionTypes ) {
176
- JType clazzClass = definedClass .owner ()._ref (Object .class );
201
+ JFieldVar valueField =
202
+ definedClass .field (
203
+ JMod .PRIVATE ,
204
+ commonType .orElse (definedClass .owner ().ref (Object .class )),
205
+ ruleFactory .getNameHelper ().getPropertyName ("value" , null ),
206
+ null );
177
207
178
- Optional <JFieldVar > valueField ;
179
- if (!unionTypes .isEmpty ()) {
180
- valueField =
181
- Optional .of (
182
- definedClass .field (
183
- JMod .PRIVATE ,
184
- clazzClass ,
185
- ruleFactory .getNameHelper ().getPropertyName ("value" , null ),
186
- null ));
208
+ definedClass ._implements (
209
+ definedClass
210
+ .owner ()
211
+ .ref (GeneratorUtils .ONE_OF_VALUE_PROVIDER_INTERFACE_NAME )
212
+ .narrow (valueField .type ()));
187
213
188
- definedClass ._implements (
189
- definedClass .owner ().ref (GeneratorUtils .ONE_OF_VALUE_PROVIDER_INTERFACE_NAME ));
214
+ GeneratorUtils .implementInterface (definedClass , valueField );
190
215
191
- GeneratorUtils .implementInterface (definedClass , valueField .orElseThrow ());
216
+ try {
217
+ JDefinedClass serializer = generateSerializer (definedClass );
218
+ definedClass .annotate (JsonSerialize .class ).param ("using" , serializer );
219
+ } catch (JClassAlreadyExistsException ex ) {
220
+ // already serialized aware
221
+ }
192
222
193
- try {
194
- JDefinedClass serializer = generateSerializer (definedClass );
195
- definedClass .annotate (JsonSerialize .class ).param ("using" , serializer );
196
- } catch (JClassAlreadyExistsException ex ) {
197
- // already serialized aware
198
- }
223
+ try {
224
+ JDefinedClass deserializer = generateDeserializer (definedClass , unionTypes );
225
+ definedClass .annotate (JsonDeserialize .class ).param ("using" , deserializer );
226
+ } catch (JClassAlreadyExistsException ex ) {
227
+ // already deserialized aware
228
+ }
199
229
200
- try {
201
- JDefinedClass deserializer = generateDeserializer (definedClass , unionTypes );
202
- definedClass .annotate (JsonDeserialize .class ).param ("using" , deserializer );
203
- } catch (JClassAlreadyExistsException ex ) {
204
- // already deserialized aware
205
- }
230
+ Collection <JTypeWrapper > stringTypes = new ArrayList <>();
231
+ for (JTypeWrapper unionType : unionTypes ) {
232
+ if (isStringType (unionType .getType ())) {
233
+ stringTypes .add (unionType );
234
+ } else {
206
235
207
- Collection <JTypeWrapper > stringTypes = new ArrayList <>();
208
- for (JTypeWrapper unionType : unionTypes ) {
209
- if (isStringType (unionType .getType ())) {
210
- stringTypes .add (unionType );
211
- } else {
212
- wrapIt (parentSchema , definedClass , valueField , unionType .getType (), unionType .getNode ());
236
+ if (unionType .getType () instanceof JDefinedClass ) {
237
+ commonType .ifPresent (
238
+ c -> ((JDefinedClass ) unionType .getType ())._extends ((JDefinedClass ) c ));
213
239
}
240
+ wrapIt (
241
+ parentSchema ,
242
+ definedClass ,
243
+ Optional .of (valueField ),
244
+ unionType .getType (),
245
+ unionType .getNode ());
214
246
}
215
- if (!stringTypes .isEmpty ()) {
216
- wrapStrings (parentSchema , definedClass , valueField , stringTypes );
217
- }
218
-
219
- } else {
220
- valueField = Optional .empty ();
221
247
}
248
+ if (!stringTypes .isEmpty ()) {
249
+ wrapStrings (parentSchema , definedClass , valueField , stringTypes );
250
+ }
251
+ return definedClass ;
252
+ }
222
253
254
+ private JDefinedClass populateRef (
255
+ JDefinedClass definedClass , Optional <JType > refType , Schema parentSchema ) {
223
256
refType .ifPresent (
224
257
type -> {
225
258
if (type instanceof JClass ) {
226
259
definedClass ._extends ((JClass ) type );
227
260
} else {
228
- wrapIt (parentSchema , definedClass , valueField , type , null );
261
+ wrapIt (parentSchema , definedClass , Optional . empty () , type , null );
229
262
}
230
263
});
231
264
@@ -280,25 +313,6 @@ private JDefinedClass generateDeserializer(
280
313
return definedClass ;
281
314
}
282
315
283
- private JDefinedClass createUnionClass (
284
- Schema parentSchema ,
285
- String nodeName ,
286
- JsonNode schemaNode ,
287
- JPackage container ,
288
- Optional <JType > refType ,
289
- Collection <JTypeWrapper > unionTypes ) {
290
- try {
291
- return populateClass (
292
- parentSchema ,
293
- container ._class (
294
- ruleFactory .getNameHelper ().getUniqueClassName (nodeName , schemaNode , container )),
295
- refType ,
296
- unionTypes );
297
- } catch (JClassAlreadyExistsException e ) {
298
- throw new IllegalArgumentException (e );
299
- }
300
- }
301
-
302
316
private void wrapIt (
303
317
Schema parentSchema ,
304
318
JDefinedClass definedClass ,
@@ -316,7 +330,7 @@ private void wrapIt(
316
330
private void wrapStrings (
317
331
Schema parentSchema ,
318
332
JDefinedClass definedClass ,
319
- Optional < JFieldVar > valueField ,
333
+ JFieldVar valueField ,
320
334
Collection <JTypeWrapper > stringTypes ) {
321
335
Iterator <JTypeWrapper > iter = stringTypes .iterator ();
322
336
JTypeWrapper first = iter .next ();
@@ -330,7 +344,7 @@ private void wrapStrings(
330
344
JFieldVar instanceField =
331
345
getInstanceField (parentSchema , definedClass , first .getType (), first .getNode ());
332
346
JVar instanceParam = constructor .param (first .type , instanceField .name ());
333
- valueField . ifPresent ( v -> body .assign (JExpr ._this ().ref (v ), instanceParam ) );
347
+ body .assign (JExpr ._this ().ref (valueField ), instanceParam );
334
348
if (pattern != null ) {
335
349
JConditional condition =
336
350
body ._if (getPatternCondition (pattern , body , instanceField , instanceParam , definedClass ));
0 commit comments