@@ -568,6 +568,10 @@ public static boolean isBean(Class<?> clz) {
568
568
return isBean (TypeRef .of (clz ));
569
569
}
570
570
571
+ public static boolean isBean (Type type , CustomTypeRegistry customTypes ) {
572
+ return isBean (TypeRef .of (type ), new LinkedHashSet <>(), customTypes );
573
+ }
574
+
571
575
/**
572
576
* Returns true if class is not array/iterable/map, and all fields is {@link
573
577
* TypeUtils#isSupported(TypeRef)}. Bean class can't be a non-static inner class. Public static
@@ -577,7 +581,14 @@ public static boolean isBean(TypeRef<?> typeRef) {
577
581
return isBean (typeRef , new LinkedHashSet <>());
578
582
}
579
583
580
- private static boolean isBean (TypeRef <?> typeRef , LinkedHashSet <TypeRef > walkedTypePath ) {
584
+ private static boolean isBean (TypeRef <?> typeRef , LinkedHashSet <TypeRef <?>> walkedTypePath ) {
585
+ return isBean (typeRef , walkedTypePath , CustomTypeRegistry .EMPTY );
586
+ }
587
+
588
+ private static boolean isBean (
589
+ TypeRef <?> typeRef ,
590
+ LinkedHashSet <TypeRef <?>> walkedTypePath ,
591
+ CustomTypeRegistry customTypes ) {
581
592
Class <?> cls = getRawType (typeRef );
582
593
if (Modifier .isAbstract (cls .getModifiers ()) || Modifier .isInterface (cls .getModifiers ())) {
583
594
return false ;
@@ -589,7 +600,7 @@ private static boolean isBean(TypeRef<?> typeRef, LinkedHashSet<TypeRef> walkedT
589
600
if (cls .getEnclosingClass () != null && !Modifier .isStatic (cls .getModifiers ())) {
590
601
return false ;
591
602
}
592
- LinkedHashSet <TypeRef > newTypePath = new LinkedHashSet <>(walkedTypePath );
603
+ LinkedHashSet <TypeRef <?> > newTypePath = new LinkedHashSet <>(walkedTypePath );
593
604
newTypePath .add (typeRef );
594
605
if (cls == Object .class ) {
595
606
// return false for typeToken that point to un-specialized generic type.
@@ -602,14 +613,17 @@ private static boolean isBean(TypeRef<?> typeRef, LinkedHashSet<TypeRef> walkedT
602
613
&& !ITERABLE_TYPE .isSupertypeOf (typeRef )
603
614
&& !MAP_TYPE .isSupertypeOf (typeRef );
604
615
if (maybe ) {
616
+ Class <?> enclosingType = enclosingType (newTypePath );
605
617
return Descriptor .getDescriptors (cls ).stream ()
606
618
.allMatch (
607
619
d -> {
608
620
TypeRef <?> t = d .getTypeRef ();
609
621
// do field modifiers and getter/setter validation here, not in getDescriptors.
610
622
// If Modifier.isFinal(d.getModifiers()), use reflection
611
623
// private field that doesn't have getter/setter will be handled by reflection.
612
- return isSupported (t , newTypePath ) || isBean (t , newTypePath );
624
+ return customTypes .hasCodec (enclosingType , t .getRawType ())
625
+ || isSupported (t , newTypePath , customTypes )
626
+ || isBean (t , newTypePath , customTypes );
613
627
});
614
628
} else {
615
629
return false ;
@@ -621,10 +635,13 @@ private static boolean isBean(TypeRef<?> typeRef, LinkedHashSet<TypeRef> walkedT
621
635
622
636
/** Check if <code>typeToken</code> is supported by row-format. */
623
637
public static boolean isSupported (TypeRef <?> typeRef ) {
624
- return isSupported (typeRef , new LinkedHashSet <>());
638
+ return isSupported (typeRef , new LinkedHashSet <>(), CustomTypeRegistry . EMPTY );
625
639
}
626
640
627
- private static boolean isSupported (TypeRef <?> typeRef , LinkedHashSet <TypeRef > walkedTypePath ) {
641
+ private static boolean isSupported (
642
+ TypeRef <?> typeRef ,
643
+ LinkedHashSet <TypeRef <?>> walkedTypePath ,
644
+ CustomTypeRegistry customTypes ) {
628
645
Class <?> cls = getRawType (typeRef );
629
646
if (!Modifier .isPublic (cls .getModifiers ())) {
630
647
return false ;
@@ -639,6 +656,10 @@ private static boolean isSupported(TypeRef<?> typeRef, LinkedHashSet<TypeRef> wa
639
656
} else if (typeRef .isArray ()) {
640
657
return isSupported (Objects .requireNonNull (typeRef .getComponentType ()));
641
658
} else if (ITERABLE_TYPE .isSupertypeOf (typeRef )) {
659
+ TypeRef <?> elementType = getElementType (typeRef );
660
+ if (customTypes .canConstructCollection (typeRef .getRawType (), elementType .getRawType ())) {
661
+ return true ;
662
+ }
642
663
boolean isSuperOfArrayList = cls .isAssignableFrom (ArrayList .class );
643
664
boolean isSuperOfHashSet = cls .isAssignableFrom (HashSet .class );
644
665
if ((!isSuperOfArrayList && !isSuperOfHashSet )
@@ -658,7 +679,7 @@ private static boolean isSupported(TypeRef<?> typeRef, LinkedHashSet<TypeRef> wa
658
679
throw new UnsupportedOperationException (
659
680
"cyclic type is not supported. walkedTypePath: " + walkedTypePath );
660
681
} else {
661
- LinkedHashSet <TypeRef > newTypePath = new LinkedHashSet <>(walkedTypePath );
682
+ LinkedHashSet <TypeRef <?> > newTypePath = new LinkedHashSet <>(walkedTypePath );
662
683
newTypePath .add (typeRef );
663
684
return isBean (typeRef , newTypePath );
664
685
}
@@ -673,13 +694,24 @@ private static boolean isSupported(TypeRef<?> typeRef, LinkedHashSet<TypeRef> wa
673
694
* parameters recursively
674
695
*/
675
696
public static LinkedHashSet <Class <?>> listBeansRecursiveInclusive (Class <?> beanClass ) {
676
- return listBeansRecursiveInclusive (beanClass , new LinkedHashSet <>());
697
+ return listBeansRecursiveInclusive (beanClass , CustomTypeRegistry .EMPTY );
698
+ }
699
+
700
+ public static LinkedHashSet <Class <?>> listBeansRecursiveInclusive (
701
+ Class <?> beanClass , CustomTypeRegistry customTypes ) {
702
+ return listBeansRecursiveInclusive (beanClass , new LinkedHashSet <>(), customTypes );
677
703
}
678
704
679
705
private static LinkedHashSet <Class <?>> listBeansRecursiveInclusive (
680
- Class <?> beanClass , LinkedHashSet <TypeRef <?>> walkedTypePath ) {
706
+ Class <?> beanClass ,
707
+ LinkedHashSet <TypeRef <?>> walkedTypePath ,
708
+ CustomTypeRegistry customTypes ) {
681
709
LinkedHashSet <Class <?>> beans = new LinkedHashSet <>();
682
- if (isBean (beanClass )) {
710
+ Class <?> enclosingType = enclosingType (walkedTypePath );
711
+ if (customTypes .hasCodec (enclosingType , beanClass )) {
712
+ return beans ;
713
+ }
714
+ if (isBean (beanClass , customTypes )) {
683
715
beans .add (beanClass );
684
716
}
685
717
LinkedHashSet <TypeRef <?>> typeRefs = new LinkedHashSet <>();
@@ -692,33 +724,34 @@ private static LinkedHashSet<Class<?>> listBeansRecursiveInclusive(
692
724
693
725
for (TypeRef <?> typeToken : typeRefs ) {
694
726
Class <?> type = getRawType (typeToken );
695
- if (isBean (type )) {
696
- beans .add (type );
727
+ if (isBean (type , customTypes )) {
697
728
if (walkedTypePath .contains (typeToken )) {
698
729
throw new UnsupportedOperationException (
699
730
"cyclic type is not supported. walkedTypePath: " + walkedTypePath );
700
731
} else {
701
732
LinkedHashSet <TypeRef <?>> newPath = new LinkedHashSet <>(walkedTypePath );
702
733
newPath .add (typeToken );
703
- beans .addAll (listBeansRecursiveInclusive (type , newPath ));
734
+ beans .addAll (listBeansRecursiveInclusive (type , newPath , customTypes ));
704
735
}
705
736
} else if (isCollection (type )) {
706
737
TypeRef <?> elementType = getElementType (typeToken );
707
738
LinkedHashSet <TypeRef <?>> newPath = new LinkedHashSet <>(walkedTypePath );
708
739
newPath .add (elementType );
709
- beans .addAll (listBeansRecursiveInclusive (elementType .getClass (), newPath ));
740
+ beans .addAll (listBeansRecursiveInclusive (elementType .getClass (), newPath , customTypes ));
710
741
} else if (isMap (type )) {
711
742
Tuple2 <TypeRef <?>, TypeRef <?>> mapKeyValueType = getMapKeyValueType (typeToken );
712
743
LinkedHashSet <TypeRef <?>> newPath = new LinkedHashSet <>(walkedTypePath );
713
744
newPath .add (mapKeyValueType .f0 );
714
745
newPath .add (mapKeyValueType .f1 );
715
- beans .addAll (listBeansRecursiveInclusive (mapKeyValueType .f0 .getRawType (), newPath ));
716
- beans .addAll (listBeansRecursiveInclusive (mapKeyValueType .f1 .getRawType (), newPath ));
746
+ beans .addAll (
747
+ listBeansRecursiveInclusive (mapKeyValueType .f0 .getRawType (), newPath , customTypes ));
748
+ beans .addAll (
749
+ listBeansRecursiveInclusive (mapKeyValueType .f1 .getRawType (), newPath , customTypes ));
717
750
} else if (type .isArray ()) {
718
751
Class <?> arrayComponent = getArrayComponent (type );
719
752
LinkedHashSet <TypeRef <?>> newPath = new LinkedHashSet <>(walkedTypePath );
720
753
newPath .add (TypeRef .of (arrayComponent ));
721
- beans .addAll (listBeansRecursiveInclusive (arrayComponent , newPath ));
754
+ beans .addAll (listBeansRecursiveInclusive (arrayComponent , newPath , customTypes ));
722
755
}
723
756
}
724
757
return beans ;
@@ -737,7 +770,7 @@ public static int computeStringHash(String str) {
737
770
}
738
771
739
772
/** Returns generic type arguments of <code>typeToken</code>. */
740
- public static List <TypeRef <?>> getTypeArguments (TypeRef typeRef ) {
773
+ public static List <TypeRef <?>> getTypeArguments (TypeRef <?> typeRef ) {
741
774
if (typeRef .getType () instanceof ParameterizedType ) {
742
775
ParameterizedType parameterizedType = (ParameterizedType ) typeRef .getType ();
743
776
return Arrays .stream (parameterizedType .getActualTypeArguments ())
@@ -752,7 +785,7 @@ public static List<TypeRef<?>> getTypeArguments(TypeRef typeRef) {
752
785
* Returns generic type arguments of <code>typeToken</code>, includes generic type arguments of
753
786
* generic type arguments recursively.
754
787
*/
755
- public static List <TypeRef <?>> getAllTypeArguments (TypeRef typeRef ) {
788
+ public static List <TypeRef <?>> getAllTypeArguments (TypeRef <?> typeRef ) {
756
789
List <TypeRef <?>> types = getTypeArguments (typeRef );
757
790
LinkedHashSet <TypeRef <?>> allTypeArguments = new LinkedHashSet <>(types );
758
791
for (TypeRef <?> type : types ) {
@@ -776,4 +809,12 @@ public static String qualifiedName(String pkg, String className) {
776
809
return pkg + "." + className ;
777
810
}
778
811
}
812
+
813
+ private static Class <?> enclosingType (LinkedHashSet <TypeRef <?>> newTypePath ) {
814
+ Class <?> result = Object .class ;
815
+ for (TypeRef <?> type : newTypePath ) {
816
+ result = type .getRawType ();
817
+ }
818
+ return result ;
819
+ }
779
820
}
0 commit comments