Skip to content

Commit 35ae62c

Browse files
committed
HV-2127 Do not rely on a list for creating a path
Signed-off-by: marko-bekhta <[email protected]>
1 parent 9ee5e33 commit 35ae62c

File tree

2 files changed

+125
-114
lines changed

2 files changed

+125
-114
lines changed

engine/src/main/java/org/hibernate/validator/internal/engine/path/NodeImpl.java

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import java.io.Serializable;
88
import java.lang.invoke.MethodHandles;
99
import java.util.Arrays;
10+
import java.util.Iterator;
11+
import java.util.LinkedList;
1012
import java.util.List;
1113
import java.util.Map;
1214

@@ -35,7 +37,7 @@
3537
*/
3638
public class NodeImpl
3739
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> {
3941
private static final long serialVersionUID = 2075466571633860499L;
4042
private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[] { };
4143

@@ -55,6 +57,8 @@ public class NodeImpl
5557

5658
private final String name;
5759
private final NodeImpl parent;
60+
private final NodeImpl root;
61+
private final int size;
5862
private final boolean isIterable;
5963
private final Integer index;
6064
private final Object key;
@@ -70,10 +74,14 @@ public class NodeImpl
7074
private int hashCode = -1;
7175
private String asString;
7276

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+
) {
7581
this.name = name;
7682
this.parent = parent;
83+
this.root = parent == null ? this : parent.root;
84+
this.size = ( parent == null ? 0 : parent.size ) + 1;
7785
this.index = index;
7886
this.key = key;
7987
this.value = value;
@@ -525,4 +533,92 @@ else if ( !Arrays.equals( parameterTypes, other.parameterTypes ) ) {
525533
}
526534
return true;
527535
}
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+
}
528624
}

0 commit comments

Comments
 (0)