@@ -313,13 +313,21 @@ protected Object createJavaObjectInstance(Class clazz, JsonObject jsonObj)
313
313
String type = jsonObj .type ;
314
314
315
315
// We can't set values to an Object, so well try to use the contained type instead
316
- if ("java.lang.Object" .equals (type ))
316
+ if ("java.lang.Object" .equals (type ))
317
317
{
318
- Object value = jsonObj .get ("value" );
319
- if (jsonObj .keySet ().size () == 1 && value != null )
318
+ Object value = jsonObj .get ("value" );
319
+ if (jsonObj .keySet ().size () == 1 && value != null )
320
320
{
321
- type = value .getClass ().getName ();
322
- }
321
+ type = value .getClass ().getName ();
322
+ }
323
+ }
324
+ if (type == null )
325
+ {
326
+ Object mayEnumSpecial = jsonObj .get ("@enum" );
327
+ if (mayEnumSpecial instanceof String )
328
+ {
329
+ type = "java.util.EnumSet" ;
330
+ }
323
331
}
324
332
325
333
Object mate ;
@@ -380,7 +388,7 @@ else if (Enum.class.isAssignableFrom(c)) // anonymous subclass of an enum
380
388
}
381
389
else if (EnumSet .class .isAssignableFrom (c ))
382
390
{
383
- mate = getEnumSet (c , jsonObj );
391
+ mate = extractEnumSet (c , jsonObj );
384
392
}
385
393
else if ((mate = coerceCertainTypes (c .getName ())) != null )
386
394
{ // if coerceCertainTypes() returns non-null, it did the work
@@ -426,7 +434,7 @@ else if (Enum.class.isAssignableFrom(clazz)) // anonymous subclass of an enum
426
434
}
427
435
else if (EnumSet .class .isAssignableFrom (clazz )) // anonymous subclass of an enum
428
436
{
429
- mate = getEnumSet (clazz , jsonObj );
437
+ mate = extractEnumSet (clazz , jsonObj );
430
438
}
431
439
else if ((mate = coerceCertainTypes (clazz .getName ())) != null )
432
440
{ // if coerceCertainTypes() returns non-null, it did the work
@@ -533,7 +541,7 @@ private static enum OneEnum {
533
541
/*
534
542
/* java 17 don't allow to call reflect on internal java api like EnumSet's implement, so need to create like this
535
543
*/
536
- private Object getEmptyEnumSet () {
544
+ private EnumSet getEmptyEnumSet () {
537
545
return EnumSet .noneOf (OneEnum .class );
538
546
}
539
547
@@ -568,6 +576,54 @@ private Object getEnumSet(Class c, JsonObject<String, Object> jsonObj)
568
576
return enumSet ;
569
577
}
570
578
579
+ protected EnumSet <?> extractEnumSet (Class c , JsonObject <String , Object > jsonObj )
580
+ {
581
+ String enumClassName = (String ) jsonObj .get ("@enum" );
582
+ Class enumClass = enumClassName == null ? null
583
+ : MetaUtils .classForName (enumClassName , reader .getClassLoader ());
584
+ Object [] items = jsonObj .getArray ();
585
+ if (items == null || items .length == 0 )
586
+ {
587
+ if (enumClass != null )
588
+ {
589
+ return EnumSet .noneOf (enumClass );
590
+ }
591
+ else
592
+ {
593
+ return EnumSet .noneOf (MetaUtils .Dumpty .class );
594
+ }
595
+ }
596
+ else if (enumClass == null )
597
+ {
598
+ throw new JsonIoException ("Could not figure out Enum of the not empty set " + jsonObj );
599
+ }
600
+
601
+ EnumSet enumSet = null ;
602
+ for (Object item : items )
603
+ {
604
+ Enum enumItem ;
605
+ if (item instanceof String )
606
+ {
607
+ enumItem = Enum .valueOf (enumClass , (String )item );
608
+ }
609
+ else
610
+ {
611
+ JsonObject jsItem = (JsonObject ) item ;
612
+ enumItem = Enum .valueOf (c , (String ) jsItem .get ("name" ));
613
+ }
614
+
615
+ if (enumSet == null )
616
+ { // Lazy init the EnumSet
617
+ enumSet = EnumSet .of (enumItem );
618
+ }
619
+ else
620
+ {
621
+ enumSet .add (enumItem );
622
+ }
623
+ }
624
+ return enumSet ;
625
+ }
626
+
571
627
/**
572
628
* For all fields where the value was "@ref":"n" where 'n' was the id of an object
573
629
* that had not yet been encountered in the stream, make the final substitution.
0 commit comments