66import com .fasterxml .jackson .databind .JsonNode ;
77import com .fasterxml .jackson .databind .node .ArrayNode ;
88import com .sun .codemodel .JClass ;
9+ import com .sun .codemodel .JClassAlreadyExistsException ;
910import com .sun .codemodel .JClassContainer ;
1011import com .sun .codemodel .JDefinedClass ;
1112import com .sun .codemodel .JFieldVar ;
1213import com .sun .codemodel .JMethod ;
1314import com .sun .codemodel .JMod ;
15+ import com .sun .codemodel .JPackage ;
1416import com .sun .codemodel .JType ;
1517import java .io .UnsupportedEncodingException ;
1618import java .net .URI ;
@@ -48,34 +50,62 @@ public JType apply(
4850 unionType ("anyOf" , nodeName , schemaNode , parent , generatableType , schema , unionTypes );
4951 unionType ("allOf" , nodeName , schemaNode , parent , generatableType , schema , unionTypes );
5052
51- if (!schemaNode .has ("properties" ) && unionTypes .isEmpty () && refType .isPresent ()) {
52- return refType .get ();
53- }
53+ JType javaType ;
54+ if (schemaNode .has ("enum" )) {
55+ javaType =
56+ ruleFactory .getEnumRule ().apply (nodeName , schemaNode , parent , generatableType , schema );
57+ } else if (!schemaNode .has ("properties" ) && unionTypes .isEmpty () && refType .isPresent ()) {
58+ javaType = refType .get ();
5459
55- JType javaType =
56- schemaNode .has ("enum" )
57- ? ruleFactory .getEnumRule ().apply (nodeName , schemaNode , parent , generatableType , schema )
58- : ruleFactory
59- .getTypeRule ()
60- .apply (nodeName , schemaNode , parent , generatableType .getPackage (), schema );
61-
62- if (javaType instanceof JDefinedClass ) {
63- JDefinedClass definedClass = (JDefinedClass ) javaType ;
64- refType .ifPresent (
65- type -> {
66- if (type instanceof JClass ) {
67- definedClass ._extends ((JClass ) type );
68- } else {
69- wrapIt (definedClass , type );
70- }
71- });
72- unionTypes .forEach (unionType -> wrapIt (definedClass , unionType ));
60+ } else {
61+ javaType =
62+ ruleFactory
63+ .getTypeRule ()
64+ .apply (nodeName , schemaNode , parent , generatableType .getPackage (), schema );
65+ if (javaType instanceof JDefinedClass ) {
66+ populateClass ((JDefinedClass ) javaType , refType , unionTypes );
67+ } else if (isCandidateForCreation (unionTypes )) {
68+ javaType = createUnionClass (nodeName , generatableType .getPackage (), refType , unionTypes );
69+ }
70+ schema .setJavaTypeIfEmpty (javaType );
7371 }
74- schema .setJavaTypeIfEmpty (javaType );
75-
7672 return javaType ;
7773 }
7874
75+ private boolean isCandidateForCreation (Collection <JType > unionTypes ) {
76+ return !unionTypes .isEmpty ()
77+ && unionTypes .stream ()
78+ .allMatch (
79+ o ->
80+ o instanceof JClass
81+ && !((JClass ) o ).isPrimitive ()
82+ && !o .name ().equals ("String" ));
83+ }
84+
85+ private JDefinedClass populateClass (
86+ JDefinedClass definedClass , Optional <JType > refType , Collection <JType > unionTypes ) {
87+ unionTypes .forEach (unionType -> wrapIt (definedClass , unionType ));
88+ refType .ifPresent (
89+ type -> {
90+ if (type instanceof JClass ) {
91+ definedClass ._extends ((JClass ) type );
92+ } else {
93+ wrapIt (definedClass , type );
94+ }
95+ });
96+ return definedClass ;
97+ }
98+
99+ private JDefinedClass createUnionClass (
100+ String nodeName , JPackage container , Optional <JType > refType , Collection <JType > unionTypes ) {
101+ String className = ruleFactory .getNameHelper ().getUniqueClassName (nodeName , null , container );
102+ try {
103+ return populateClass (container ._class (className ), refType , unionTypes );
104+ } catch (JClassAlreadyExistsException e ) {
105+ throw new IllegalArgumentException (e );
106+ }
107+ }
108+
79109 private void wrapIt (JDefinedClass definedClass , JType unionType ) {
80110 JFieldVar instanceField =
81111 definedClass .field (
@@ -102,17 +132,17 @@ private void unionType(
102132 if (schemaNode .has (prefix )) {
103133 int i = 0 ;
104134 for (JsonNode oneOf : (ArrayNode ) schemaNode .get (prefix )) {
135+ String ref = parentSchema .getId ().toString () + '/' + prefix + '/' + i ++;
136+ Schema schema =
137+ ruleFactory
138+ .getSchemaStore ()
139+ .create (
140+ URI .create (ref ),
141+ ruleFactory .getGenerationConfig ().getRefFragmentPathDelimiters ());
105142 types .add (
106- apply (
107- nodeName ,
108- oneOf ,
109- parent ,
110- generatableType .getPackage (),
111- ruleFactory
112- .getSchemaStore ()
113- .create (
114- URI .create (parentSchema .getId ().toString () + '/' + prefix + '/' + i ++),
115- ruleFactory .getGenerationConfig ().getRefFragmentPathDelimiters ())));
143+ schema .isGenerated ()
144+ ? schema .getJavaType ()
145+ : apply (nodeName , oneOf , parent , generatableType .getPackage (), schema ));
116146 }
117147 }
118148 }
0 commit comments