@@ -150,82 +150,115 @@ public JType apply(
150150 ruleFactory .getEnumRule ().apply (nodeName , schemaNode , parent , generatableType , schema );
151151 } else if (!schemaNode .has ("properties" ) && unionTypes .isEmpty () && refType .isPresent ()) {
152152 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+ }
153169
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+ }
154182 } else {
155183 javaType =
156184 ruleFactory
157185 .getTypeRule ()
158186 .apply (nodeName , schemaNode , parent , generatableType .getPackage (), schema );
159187 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 );
165189 }
166190 schema .setJavaTypeIfEmpty (javaType );
167191 }
192+
168193 return javaType ;
169194 }
170195
171196 private JDefinedClass populateClass (
172197 Schema parentSchema ,
173198 JDefinedClass definedClass ,
174- Optional <JType > refType ,
199+ Optional <JType > commonType ,
175200 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 );
177207
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 ()));
187213
188- definedClass ._implements (
189- definedClass .owner ().ref (GeneratorUtils .ONE_OF_VALUE_PROVIDER_INTERFACE_NAME ));
214+ GeneratorUtils .implementInterface (definedClass , valueField );
190215
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+ }
192222
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+ }
199229
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 {
206235
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 ));
213239 }
240+ wrapIt (
241+ parentSchema ,
242+ definedClass ,
243+ Optional .of (valueField ),
244+ unionType .getType (),
245+ unionType .getNode ());
214246 }
215- if (!stringTypes .isEmpty ()) {
216- wrapStrings (parentSchema , definedClass , valueField , stringTypes );
217- }
218-
219- } else {
220- valueField = Optional .empty ();
221247 }
248+ if (!stringTypes .isEmpty ()) {
249+ wrapStrings (parentSchema , definedClass , valueField , stringTypes );
250+ }
251+ return definedClass ;
252+ }
222253
254+ private JDefinedClass populateRef (
255+ JDefinedClass definedClass , Optional <JType > refType , Schema parentSchema ) {
223256 refType .ifPresent (
224257 type -> {
225258 if (type instanceof JClass ) {
226259 definedClass ._extends ((JClass ) type );
227260 } else {
228- wrapIt (parentSchema , definedClass , valueField , type , null );
261+ wrapIt (parentSchema , definedClass , Optional . empty () , type , null );
229262 }
230263 });
231264
@@ -280,25 +313,6 @@ private JDefinedClass generateDeserializer(
280313 return definedClass ;
281314 }
282315
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-
302316 private void wrapIt (
303317 Schema parentSchema ,
304318 JDefinedClass definedClass ,
@@ -316,7 +330,7 @@ private void wrapIt(
316330 private void wrapStrings (
317331 Schema parentSchema ,
318332 JDefinedClass definedClass ,
319- Optional < JFieldVar > valueField ,
333+ JFieldVar valueField ,
320334 Collection <JTypeWrapper > stringTypes ) {
321335 Iterator <JTypeWrapper > iter = stringTypes .iterator ();
322336 JTypeWrapper first = iter .next ();
@@ -330,7 +344,7 @@ private void wrapStrings(
330344 JFieldVar instanceField =
331345 getInstanceField (parentSchema , definedClass , first .getType (), first .getNode ());
332346 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 );
334348 if (pattern != null ) {
335349 JConditional condition =
336350 body ._if (getPatternCondition (pattern , body , instanceField , instanceParam , definedClass ));
0 commit comments