7
7
import java .io .Serializable ;
8
8
import java .lang .invoke .MethodHandles ;
9
9
import java .util .Arrays ;
10
+ import java .util .Iterator ;
11
+ import java .util .LinkedList ;
10
12
import java .util .List ;
11
13
import java .util .Map ;
12
14
35
37
*/
36
38
public class NodeImpl
37
39
implements Path .PropertyNode , Path .MethodNode , Path .ConstructorNode , Path .BeanNode , Path .ParameterNode , Path .ReturnValueNode , Path .CrossParameterNode , Path .ContainerElementNode ,
38
- org .hibernate .validator .path .PropertyNode , org .hibernate .validator .path .ContainerElementNode , Serializable {
40
+ org .hibernate .validator .path .PropertyNode , org .hibernate .validator .path .ContainerElementNode , Serializable , Iterable < Path . Node > {
39
41
private static final long serialVersionUID = 2075466571633860499L ;
40
42
private static final Class <?>[] EMPTY_CLASS_ARRAY = new Class <?>[] { };
41
43
@@ -55,6 +57,8 @@ public class NodeImpl
55
57
56
58
private final String name ;
57
59
private final NodeImpl parent ;
60
+ private final NodeImpl root ;
61
+ private final int size ;
58
62
private final boolean isIterable ;
59
63
private final Integer index ;
60
64
private final Object key ;
@@ -70,10 +74,14 @@ public class NodeImpl
70
74
private int hashCode = -1 ;
71
75
private String asString ;
72
76
73
- private NodeImpl (String name , NodeImpl parent , boolean isIterable , Integer index , Object key , ElementKind kind , Class <?>[] parameterTypes ,
74
- Integer parameterIndex , Object value , Class <?> containerClass , Integer typeArgumentIndex ) {
77
+ private NodeImpl (
78
+ String name , NodeImpl parent , boolean isIterable , Integer index , Object key , ElementKind kind , Class <?>[] parameterTypes ,
79
+ Integer parameterIndex , Object value , Class <?> containerClass , Integer typeArgumentIndex
80
+ ) {
75
81
this .name = name ;
76
82
this .parent = parent ;
83
+ this .root = parent == null ? this : parent .root ;
84
+ this .size = ( parent == null ? 0 : parent .size ) + 1 ;
77
85
this .index = index ;
78
86
this .key = key ;
79
87
this .value = value ;
@@ -525,4 +533,92 @@ else if ( !Arrays.equals( parameterTypes, other.parameterTypes ) ) {
525
533
}
526
534
return true ;
527
535
}
536
+
537
+ boolean isRootPath () {
538
+ // .size() == 1 && nodeList.get( 0 ).getName() == null
539
+ return parent == null && name == null ;
540
+ }
541
+
542
+ @ Override
543
+ public Iterator <Path .Node > iterator () {
544
+ if ( parent == null ) {
545
+ return List .of ( (Path .Node ) this ).iterator ();
546
+ }
547
+ List <Path .Node > result = new LinkedList <>();
548
+ NodeImpl curr = this ;
549
+ while ( !curr .isRootPath () ) {
550
+ result .add ( 0 , curr );
551
+ curr = curr .parent ;
552
+ }
553
+ return result .iterator ();
554
+ }
555
+
556
+ boolean isSubPathOf (NodeImpl other ) {
557
+ if ( this .size > other .size ) {
558
+ return false ;
559
+ }
560
+ NodeImpl curr = this ;
561
+ NodeImpl otherCurr = other ;
562
+ while ( otherCurr != null && !otherCurr .equals ( this ) ) {
563
+ otherCurr = otherCurr .parent ;
564
+ }
565
+ if ( otherCurr == null ) {
566
+ return false ;
567
+ }
568
+ while ( !curr .isRootPath () && !otherCurr .isRootPath () ) {
569
+ if ( !curr .equals ( otherCurr ) ) {
570
+ return false ;
571
+ }
572
+ curr = curr .parent ;
573
+ otherCurr = otherCurr .parent ;
574
+ }
575
+
576
+ return curr .isRootPath ();
577
+ }
578
+
579
+ boolean isSubPathOrContains (NodeImpl other ) {
580
+ NodeImpl curr ;
581
+ NodeImpl otherCurr ;
582
+ if ( this .size > other .size ) {
583
+ curr = other ;
584
+ otherCurr = this ;
585
+ }
586
+ else {
587
+ curr = this ;
588
+ otherCurr = other ;
589
+ }
590
+
591
+ while ( otherCurr != null && !otherCurr .equals ( curr ) ) {
592
+ otherCurr = otherCurr .parent ;
593
+ }
594
+ if ( otherCurr == null ) {
595
+ return false ;
596
+ }
597
+ while ( !curr .isRootPath () && !otherCurr .isRootPath () ) {
598
+ if ( !curr .equals ( otherCurr ) ) {
599
+ return false ;
600
+ }
601
+ curr = curr .parent ;
602
+ otherCurr = otherCurr .parent ;
603
+ }
604
+
605
+ return curr .isRootPath () && otherCurr .isRootPath ();
606
+ }
607
+
608
+ boolean samePath (NodeImpl other ) {
609
+ if ( this .size != other .size ) {
610
+ return false ;
611
+ }
612
+ NodeImpl curr = this ;
613
+ NodeImpl otherCurr = other ;
614
+ while ( curr != null && otherCurr != null ) {
615
+ if ( !curr .equals ( otherCurr ) ) {
616
+ return false ;
617
+ }
618
+ otherCurr = otherCurr .parent ;
619
+ curr = curr .parent ;
620
+ }
621
+
622
+ return curr == null && otherCurr == null ;
623
+ }
528
624
}
0 commit comments