3636import java .util .Set ;
3737import java .util .function .BiFunction ;
3838
39- public class UnionDeserializer <T , M > implements JsonpDeserializer <T > {
39+ public class UnionDeserializer <Union , Kind , Member > implements JsonpDeserializer <Union > {
4040
4141 public static class AmbiguousUnionException extends RuntimeException {
4242 public AmbiguousUnionException (String message ) {
4343 super (message );
4444 }
4545 }
4646
47- private abstract static class EventHandler <T , M > {
48- abstract T deserialize (JsonParser parser , JsonpMapper mapper , Event event , BiFunction <String , M , T > buildFn );
47+ private abstract static class EventHandler <Union , Kind , Member > {
48+ abstract Union deserialize (JsonParser parser , JsonpMapper mapper , Event event , BiFunction <Kind , Member , Union > buildFn );
4949 abstract EnumSet <Event > nativeEvents ();
5050 }
5151
52- private static class SingleMemberHandler <T , M > extends EventHandler <T , M > {
53- private final JsonpDeserializer <? extends M > deserializer ;
54- private final String tag ;
52+ private static class SingleMemberHandler <Union , Kind , Member > extends EventHandler <Union , Kind , Member > {
53+ private final JsonpDeserializer <? extends Member > deserializer ;
54+ private final Kind tag ;
5555 // ObjectDeserializers provide the list of fields they know about
5656 private final Set <String > fields ;
5757
58- SingleMemberHandler (String tag , JsonpDeserializer <? extends M > deserializer ) {
58+ SingleMemberHandler (Kind tag , JsonpDeserializer <? extends Member > deserializer ) {
5959 this (tag , deserializer , null );
6060 }
6161
62- SingleMemberHandler (String tag , JsonpDeserializer <? extends M > deserializer , Set <String > fields ) {
62+ SingleMemberHandler (Kind tag , JsonpDeserializer <? extends Member > deserializer , Set <String > fields ) {
6363 this .deserializer = deserializer ;
6464 this .tag = tag ;
6565 this .fields = fields ;
@@ -71,7 +71,7 @@ EnumSet<Event> nativeEvents() {
7171 }
7272
7373 @ Override
74- T deserialize (JsonParser parser , JsonpMapper mapper , Event event , BiFunction <String , M , T > buildFn ) {
74+ Union deserialize (JsonParser parser , JsonpMapper mapper , Event event , BiFunction <Kind , Member , Union > buildFn ) {
7575 return buildFn .apply (tag , deserializer .deserialize (parser , mapper , event ));
7676 }
7777 }
@@ -80,22 +80,22 @@ T deserialize(JsonParser parser, JsonpMapper mapper, Event event, BiFunction<Str
8080 * An event handler for value events (string, number, etc) that can try multiple handlers, which are ordered
8181 * from most specific (e.g. enum) to least specific (e.g. string)
8282 */
83- private static class MultiMemberHandler <T , M > extends EventHandler <T , M > {
84- private List <SingleMemberHandler <T , M >> handlers ;
83+ private static class MultiMemberHandler <Union , Kind , Member > extends EventHandler <Union , Kind , Member > {
84+ private List <SingleMemberHandler <Union , Kind , Member >> handlers ;
8585
8686 @ Override
8787 EnumSet <Event > nativeEvents () {
8888 EnumSet <Event > result = EnumSet .noneOf (Event .class );
89- for (SingleMemberHandler <T , M > smh : handlers ) {
89+ for (SingleMemberHandler <Union , Kind , Member > smh : handlers ) {
9090 result .addAll (smh .deserializer .nativeEvents ());
9191 }
9292 return result ;
9393 }
9494
9595 @ Override
96- T deserialize (JsonParser parser , JsonpMapper mapper , Event event , BiFunction <String , M , T > buildFn ) {
96+ Union deserialize (JsonParser parser , JsonpMapper mapper , Event event , BiFunction <Kind , Member , Union > buildFn ) {
9797 RuntimeException exception = null ;
98- for (EventHandler <T , M > d : handlers ) {
98+ for (EventHandler <Union , Kind , Member > d : handlers ) {
9999 try {
100100 return d .deserialize (parser , mapper , event , buildFn );
101101 } catch (RuntimeException ex ) {
@@ -106,37 +106,37 @@ T deserialize(JsonParser parser, JsonpMapper mapper, Event event, BiFunction<Str
106106 }
107107 }
108108
109- public static class Builder <T , M > implements ObjectBuilder <JsonpDeserializer <T >> {
109+ public static class Builder <Union , Kind , Member > implements ObjectBuilder <JsonpDeserializer <Union >> {
110110
111- private final BiFunction <String , M , T > buildFn ;
111+ private final BiFunction <Kind , Member , Union > buildFn ;
112112
113- private final List <UnionDeserializer .SingleMemberHandler <T , M >> objectMembers = new ArrayList <>();
114- private final Map <Event , EventHandler <T , M >> otherMembers = new HashMap <>();
113+ private final List <UnionDeserializer .SingleMemberHandler <Union , Kind , Member >> objectMembers = new ArrayList <>();
114+ private final Map <Event , EventHandler <Union , Kind , Member >> otherMembers = new HashMap <>();
115115 private final boolean allowAmbiguousPrimitive ;
116116
117- public Builder (BiFunction <String , M , T > buildFn , boolean allowAmbiguities ) {
117+ public Builder (BiFunction <Kind , Member , Union > buildFn , boolean allowAmbiguities ) {
118118 // If we allow ambiguities, multiple handlers for a given json value event will be allowed
119119 this .allowAmbiguousPrimitive = allowAmbiguities ;
120120 this .buildFn = buildFn ;
121121 }
122122
123- private void addAmbiguousDeserializer (Event e , String tag , JsonpDeserializer <? extends M > deserializer ) {
124- EventHandler <T , M > m = otherMembers .get (e );
125- MultiMemberHandler <T , M > mmh ;
126- if (m instanceof MultiMemberHandler <?, ?>) {
127- mmh = (MultiMemberHandler <T , M >) m ;
123+ private void addAmbiguousDeserializer (Event e , Kind tag , JsonpDeserializer <? extends Member > deserializer ) {
124+ EventHandler <Union , Kind , Member > m = otherMembers .get (e );
125+ MultiMemberHandler <Union , Kind , Member > mmh ;
126+ if (m instanceof MultiMemberHandler <?, ?, ? >) {
127+ mmh = (MultiMemberHandler <Union , Kind , Member >) m ;
128128 } else {
129129 mmh = new MultiMemberHandler <>();
130130 mmh .handlers = new ArrayList <>(2 );
131- mmh .handlers .add ((SingleMemberHandler <T , M >) m );
131+ mmh .handlers .add ((SingleMemberHandler <Union , Kind , Member >) m );
132132 otherMembers .put (e , mmh );
133133 }
134134 mmh .handlers .add (new SingleMemberHandler <>(tag , deserializer ));
135135 // Sort handlers by number of accepted events, which gives their specificity
136136 mmh .handlers .sort (Comparator .comparingInt (a -> a .deserializer .acceptedEvents ().size ()));
137137 }
138138
139- private void addMember (Event e , String tag , UnionDeserializer .SingleMemberHandler <T , M > member ) {
139+ private void addMember (Event e , Kind tag , UnionDeserializer .SingleMemberHandler <Union , Kind , Member > member ) {
140140 if (otherMembers .containsKey (e )) {
141141 if (!allowAmbiguousPrimitive || e == Event .START_OBJECT || e == Event .START_ARRAY ) {
142142 throw new AmbiguousUnionException ("Union member '" + tag + "' conflicts with other members" );
@@ -151,26 +151,26 @@ private void addMember(Event e, String tag, UnionDeserializer.SingleMemberHandle
151151 }
152152 }
153153
154- public Builder <T , M > addMember (String tag , JsonpDeserializer <? extends M > deserializer ) {
154+ public Builder <Union , Kind , Member > addMember (Kind tag , JsonpDeserializer <? extends Member > deserializer ) {
155155
156156 JsonpDeserializer <?> unwrapped = DelegatingDeserializer .unwrap (deserializer );
157157 if (unwrapped instanceof ObjectDeserializer ) {
158158 ObjectDeserializer <?> od = (ObjectDeserializer <?>) unwrapped ;
159159 Set <String > allFields = od .fieldNames ();
160160 Set <String > fields = new HashSet <>(allFields ); // copy to update
161- for (UnionDeserializer .SingleMemberHandler <T , M > member : objectMembers ) {
161+ for (UnionDeserializer .SingleMemberHandler <Union , Kind , Member > member : objectMembers ) {
162162 // Remove respective fields on both sides to keep specific ones
163163 fields .removeAll (member .fields );
164164 member .fields .removeAll (allFields );
165165 }
166- UnionDeserializer .SingleMemberHandler <T , M > member = new SingleMemberHandler <>(tag , deserializer , fields );
166+ UnionDeserializer .SingleMemberHandler <Union , Kind , Member > member = new SingleMemberHandler <>(tag , deserializer , fields );
167167 objectMembers .add (member );
168168 if (od .shortcutProperty () != null ) {
169169 // also add it as a string
170170 addMember (Event .VALUE_STRING , tag , member );
171171 }
172172 } else {
173- UnionDeserializer .SingleMemberHandler <T , M > member = new SingleMemberHandler <>(tag , deserializer );
173+ UnionDeserializer .SingleMemberHandler <Union , Kind , Member > member = new SingleMemberHandler <>(tag , deserializer );
174174 for (Event e : deserializer .nativeEvents ()) {
175175 addMember (e , tag , member );
176176 }
@@ -180,9 +180,9 @@ public Builder<T, M> addMember(String tag, JsonpDeserializer<? extends M> deseri
180180 }
181181
182182 @ Override
183- public JsonpDeserializer <T > build () {
183+ public JsonpDeserializer <Union > build () {
184184 // Check that no object member had all its fields removed
185- for (UnionDeserializer .SingleMemberHandler <T , M > member : objectMembers ) {
185+ for (UnionDeserializer .SingleMemberHandler <Union , Kind , Member > member : objectMembers ) {
186186 if (member .fields .isEmpty ()) {
187187 throw new AmbiguousUnionException ("All properties of '" + member .tag + "' also exist in other object members" );
188188 }
@@ -201,16 +201,16 @@ public JsonpDeserializer<T> build() {
201201 }
202202 }
203203
204- private final BiFunction <String , M , T > buildFn ;
204+ private final BiFunction <Kind , Member , Union > buildFn ;
205205 private final EnumSet <Event > nativeEvents ;
206- private final Map <String , EventHandler <T , M >> objectMembers ;
207- private final Map <Event , EventHandler <T , M >> otherMembers ;
208- private final EventHandler <T , M > fallbackObjectMember ;
206+ private final Map <String , EventHandler <Union , Kind , Member >> objectMembers ;
207+ private final Map <Event , EventHandler <Union , Kind , Member >> otherMembers ;
208+ private final EventHandler <Union , Kind , Member > fallbackObjectMember ;
209209
210210 public UnionDeserializer (
211- List <SingleMemberHandler <T , M >> objectMembers ,
212- Map <Event , EventHandler <T , M >> otherMembers ,
213- BiFunction <String , M , T > buildFn
211+ List <SingleMemberHandler <Union , Kind , Member >> objectMembers ,
212+ Map <Event , EventHandler <Union , Kind , Member >> otherMembers ,
213+ BiFunction <Kind , Member , Union > buildFn
214214 ) {
215215 this .buildFn = buildFn ;
216216
@@ -219,7 +219,7 @@ public UnionDeserializer(
219219 this .objectMembers = Collections .emptyMap ();
220220 } else {
221221 this .objectMembers = new HashMap <>();
222- for (SingleMemberHandler <T , M > member : objectMembers ) {
222+ for (SingleMemberHandler <Union , Kind , Member > member : objectMembers ) {
223223 for (String field : member .fields ) {
224224 this .objectMembers .put (field , member );
225225 }
@@ -229,7 +229,7 @@ public UnionDeserializer(
229229 this .otherMembers = otherMembers ;
230230
231231 this .nativeEvents = EnumSet .noneOf (Event .class );
232- for (EventHandler <T , M > member : otherMembers .values ()) {
232+ for (EventHandler <Union , Kind , Member > member : otherMembers .values ()) {
233233 this .nativeEvents .addAll (member .nativeEvents ());
234234 }
235235
@@ -253,15 +253,15 @@ public EnumSet<Event> acceptedEvents() {
253253 }
254254
255255 @ Override
256- public T deserialize (JsonParser parser , JsonpMapper mapper ) {
256+ public Union deserialize (JsonParser parser , JsonpMapper mapper ) {
257257 Event event = parser .next ();
258258 JsonpUtils .ensureAccepts (this , parser , event );
259259 return deserialize (parser , mapper , event );
260260 }
261261
262262 @ Override
263- public T deserialize (JsonParser parser , JsonpMapper mapper , Event event ) {
264- EventHandler <T , M > member = otherMembers .get (event );
263+ public Union deserialize (JsonParser parser , JsonpMapper mapper , Event event ) {
264+ EventHandler <Union , Kind , Member > member = otherMembers .get (event );
265265
266266 if (member == null && event == Event .START_OBJECT && !objectMembers .isEmpty ()) {
267267 // Parse as an object to find matching field names
0 commit comments