Repository: bval Updated Branches: refs/heads/bv2 4c1e1e0b3 -> a63f3d5e0
more TCK container work Project: http://git-wip-us.apache.org/repos/asf/bval/repo Commit: http://git-wip-us.apache.org/repos/asf/bval/commit/a63f3d5e Tree: http://git-wip-us.apache.org/repos/asf/bval/tree/a63f3d5e Diff: http://git-wip-us.apache.org/repos/asf/bval/diff/a63f3d5e Branch: refs/heads/bv2 Commit: a63f3d5e06950e3c055a36a0a97479d26a7a909d Parents: 4c1e1e0 Author: Matt Benson <mben...@apache.org> Authored: Tue Mar 6 14:34:25 2018 -0600 Committer: Matt Benson <mben...@apache.org> Committed: Tue Mar 6 17:51:43 2018 -0600 ---------------------------------------------------------------------- .../jsr/descriptor/ContainerElementTypeD.java | 16 +++-- .../bval/jsr/descriptor/DescriptorManager.java | 9 ++- .../org/apache/bval/jsr/job/ValidationJob.java | 65 ++++++++++++-------- .../java/org/apache/bval/jsr/util/NodeImpl.java | 14 ++++- .../java/org/apache/bval/jsr/util/PathImpl.java | 14 ++--- 5 files changed, 73 insertions(+), 45 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/bval/blob/a63f3d5e/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ContainerElementTypeD.java ---------------------------------------------------------------------- diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ContainerElementTypeD.java b/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ContainerElementTypeD.java index 51252aa..fb80802 100644 --- a/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ContainerElementTypeD.java +++ b/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ContainerElementTypeD.java @@ -30,6 +30,7 @@ import javax.validation.valueextraction.ValueExtractor; import org.apache.bval.jsr.GraphContext; import org.apache.bval.jsr.metadata.ContainerElementKey; import org.apache.bval.jsr.util.NodeImpl; +import org.apache.bval.jsr.util.PathImpl; import org.apache.bval.util.Exceptions; import org.apache.bval.util.Lazy; import org.apache.bval.util.Validate; @@ -48,33 +49,36 @@ public class ContainerElementTypeD extends CascadableContainerD<CascadableContai @Override public void value(String nodeName, Object object) { - addChild(new NodeImpl.PropertyNodeImpl(nodeName), object); + addChild(new NodeImpl.ContainerElementNodeImpl(nodeName), object); } @Override public void iterableValue(String nodeName, Object object) { - final NodeImpl.PropertyNodeImpl node = new NodeImpl.PropertyNodeImpl(nodeName); + final NodeImpl node = new NodeImpl.ContainerElementNodeImpl(nodeName); node.setInIterable(true); addChild(node, object); } @Override public void indexedValue(String nodeName, int i, Object object) { - final NodeImpl.PropertyNodeImpl node = new NodeImpl.PropertyNodeImpl(nodeName); + final NodeImpl node = new NodeImpl.ContainerElementNodeImpl(nodeName); node.setIndex(Integer.valueOf(i)); addChild(node, object); } @Override public void keyedValue(String nodeName, Object key, Object object) { - final NodeImpl.PropertyNodeImpl node = new NodeImpl.PropertyNodeImpl(nodeName); + final NodeImpl node = new NodeImpl.ContainerElementNodeImpl(nodeName); node.setKey(key); addChild(node, object); } private void addChild(NodeImpl node, Object value) { - result.get() - .add(context.child(node.inContainer(key.getContainerClass(), key.getTypeArgumentIndex()), value)); + final PathImpl path = context.getPath(); + if (node.getName() != null) { + path.addNode(node.inContainer(key.getContainerClass(), key.getTypeArgumentIndex())); + } + result.get().add(context.child(path, value)); } } http://git-wip-us.apache.org/repos/asf/bval/blob/a63f3d5e/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/DescriptorManager.java ---------------------------------------------------------------------- diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/DescriptorManager.java b/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/DescriptorManager.java index 0f1a13a..3c7365e 100644 --- a/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/DescriptorManager.java +++ b/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/DescriptorManager.java @@ -23,20 +23,23 @@ import java.util.concurrent.ConcurrentMap; import javax.validation.metadata.BeanDescriptor; import javax.validation.metadata.CascadableDescriptor; +import javax.validation.metadata.ContainerDescriptor; import javax.validation.metadata.ElementDescriptor; import org.apache.bval.jsr.ApacheValidatorFactory; import org.apache.bval.jsr.metadata.AnnotationBehaviorMergeStrategy; import org.apache.bval.jsr.metadata.CompositeBuilder; +import org.apache.bval.jsr.metadata.DualBuilder; import org.apache.bval.jsr.metadata.HierarchyBuilder; import org.apache.bval.jsr.metadata.MetadataBuilder; -import org.apache.bval.jsr.metadata.DualBuilder; import org.apache.bval.jsr.metadata.ReflectionBuilder; import org.apache.bval.util.Validate; public class DescriptorManager { - public static <D extends ElementDescriptor & CascadableDescriptor> boolean isConstrained(D descriptor) { - return descriptor.hasConstraints() || descriptor.isCascaded(); + public static <D extends ElementDescriptor & CascadableDescriptor & ContainerDescriptor> boolean isConstrained( + D descriptor) { + return descriptor.hasConstraints() || descriptor.isCascaded() + || !descriptor.getConstrainedContainerElementTypes().isEmpty(); } private final ApacheValidatorFactory validatorFactory; http://git-wip-us.apache.org/repos/asf/bval/blob/a63f3d5e/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java ---------------------------------------------------------------------- diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java b/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java index 070bdc6..088f69d 100644 --- a/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java +++ b/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java @@ -21,8 +21,6 @@ package org.apache.bval.jsr.job; import java.lang.reflect.Array; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; -import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashSet; @@ -35,7 +33,6 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentSkipListSet; import java.util.function.BiConsumer; import java.util.function.Consumer; -import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -43,6 +40,7 @@ import java.util.stream.Stream; import javax.validation.ConstraintValidator; import javax.validation.ConstraintViolation; +import javax.validation.ElementKind; import javax.validation.MessageInterpolator; import javax.validation.Path; import javax.validation.TraversableResolver; @@ -65,13 +63,13 @@ import org.apache.bval.jsr.descriptor.ElementD; import org.apache.bval.jsr.descriptor.PropertyD; import org.apache.bval.jsr.groups.Group; import org.apache.bval.jsr.groups.Groups; +import org.apache.bval.jsr.metadata.ContainerElementKey; import org.apache.bval.jsr.util.NodeImpl; import org.apache.bval.jsr.util.PathImpl; import org.apache.bval.jsr.util.Proxies; import org.apache.bval.util.Exceptions; import org.apache.bval.util.Lazy; import org.apache.bval.util.ObjectUtils; -import org.apache.bval.util.ObjectWrapper; import org.apache.bval.util.Validate; import org.apache.bval.util.reflection.TypeUtils; @@ -269,32 +267,13 @@ public abstract class ValidationJob<T> { @Override void recurse(Class<?> group, Consumer<ConstraintViolation<T>> sink) { @SuppressWarnings({ "unchecked", "rawtypes" }) - final Stream<ContainerElementTypeD> containerElements = - descriptor.getConstrainedContainerElementTypes().stream() - .flatMap(d -> ComposedD.unwrap(d, (Class) ContainerElementTypeD.class)); - - final ObjectWrapper<Boolean> effectiveCascade = - new ObjectWrapper<>(Boolean.valueOf(descriptor.isCascaded())); + final Stream<ContainerElementTypeD> containerElements = descriptor.getConstrainedContainerElementTypes() + .stream().flatMap(d -> ComposedD.unwrap(d, (Class) ContainerElementTypeD.class)); - // cascade legacy containers the old way by filtering them out here: - - final Collection<TypeVariable<?>> wellKnown = Arrays.asList(ITERABLE_ELEMENT, MAP_VALUE); - - final Predicate<? super ContainerElementTypeD> isNotLegacyContainer = d -> { - final boolean cascadedLegacyContainer = - d.isCascaded() && wellKnown.stream().anyMatch(d.getKey()::represents); - - if (cascadedLegacyContainer) { - effectiveCascade.accept(Boolean.TRUE); - } - return !cascadedLegacyContainer; - }; - - containerElements.filter(isNotLegacyContainer) - .flatMap(d -> d.read(context).map(child -> new SproutFrame<>(this, d, child))) + containerElements.flatMap(d -> d.read(context).map(child -> new ContainerElementFrame(this, d, child))) .forEach(f -> f.process(group, sink)); - if (!effectiveCascade.get().booleanValue()) { + if (!descriptor.isCascaded()) { return; } if (descriptor instanceof PropertyDescriptor) { @@ -358,6 +337,7 @@ public abstract class ValidationJob<T> { final Type assignedType = TypeUtils.getTypeArguments(containerType, (Class<?>) originalTypeVariable.getGenericDeclaration()) .get(originalTypeVariable); + tv = assignedType instanceof TypeVariable<?> ? (TypeVariable<?>) assignedType : null; } final int i = tv == null ? -1 : ObjectUtils.indexOf(containerType.getTypeParameters(), tv); @@ -370,6 +350,37 @@ public abstract class ValidationJob<T> { } } + private class ContainerElementFrame extends SproutFrame<ContainerElementTypeD> { + + ContainerElementFrame(ValidationJob<T>.Frame<?> parent, ContainerElementTypeD descriptor, + GraphContext context) { + super(parent, descriptor, context); + } + + @Override + void recurse(Class<?> group, Consumer<ConstraintViolation<T>> sink) { + final PathImpl path = context.getPath(); + final NodeImpl leafNode = path.getLeafNode(); + + final NodeImpl newLeaf; + + if (leafNode.getKind() == ElementKind.CONTAINER_ELEMENT) { + // recurse using elided path: + path.removeLeafNode(); + newLeaf = new NodeImpl.PropertyNodeImpl(leafNode); + newLeaf.setName(null); + } else { + final ContainerElementKey key = descriptor.getKey(); + newLeaf = new NodeImpl.PropertyNodeImpl((String) null).inContainer(key.getContainerClass(), + key.getTypeArgumentIndex()); + } + path.addNode(newLeaf); + + new SproutFrame<>(parent, descriptor, context.getParent().child(path, context.getValue())).recurse(group, + sink); + } + } + private static final Comparator<Path> COMPARE_TO_STRING = Comparator.comparing(Object::toString); protected static final TypeVariable<?> MAP_VALUE = Map.class.getTypeParameters()[1]; http://git-wip-us.apache.org/repos/asf/bval/blob/a63f3d5e/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeImpl.java ---------------------------------------------------------------------- diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeImpl.java index 8e12ce3..4de46de 100644 --- a/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeImpl.java +++ b/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeImpl.java @@ -114,6 +114,14 @@ public abstract class NodeImpl implements Path.Node, Serializable { this.inIterable = node.isInIterable(); this.index = node.getIndex(); this.key = node.getKey(); + + if (node instanceof NodeImpl) { + final NodeImpl n = (NodeImpl) node; + this.parameterIndex = n.parameterIndex; + this.parameterTypes = n.parameterTypes; + this.containerType = n.containerType; + this.typeArgumentIndex = n.typeArgumentIndex; + } } <T extends Path.Node> NodeImpl(Path.Node node, Class<T> nodeType, Consumer<T> handler) { @@ -386,8 +394,12 @@ public abstract class NodeImpl implements Path.Node, Serializable { @SuppressWarnings("serial") public static class ContainerElementNodeImpl extends NodeImpl implements Path.ContainerElementNode { - public ContainerElementNodeImpl(String name, Class<?> containerType, Integer typeArgumentIndex) { + public ContainerElementNodeImpl(String name) { super(name); + } + + public ContainerElementNodeImpl(String name, Class<?> containerType, Integer typeArgumentIndex) { + this(name); inContainer(containerType, typeArgumentIndex); } http://git-wip-us.apache.org/repos/asf/bval/blob/a63f3d5e/bval-jsr/src/main/java/org/apache/bval/jsr/util/PathImpl.java ---------------------------------------------------------------------- diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/util/PathImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/util/PathImpl.java index 1f5f3d0..e96a0de 100644 --- a/bval-jsr/src/main/java/org/apache/bval/jsr/util/PathImpl.java +++ b/bval-jsr/src/main/java/org/apache/bval/jsr/util/PathImpl.java @@ -153,6 +153,10 @@ public class PathImpl implements Path, Serializable { return new NodeImpl.PropertyNodeImpl(cast); } + private static boolean isAwaitingPropertyName(NodeImpl n) { + return n != null && n.getName() == null && (n.isInIterable() || n.getContainerClass() != null); + } + private final LinkedList<NodeImpl> nodeList = new LinkedList<>(); private PathImpl() { @@ -210,7 +214,7 @@ public class PathImpl implements Path, Serializable { public void addProperty(String name) { if (!nodeList.isEmpty()) { NodeImpl leaf = getLeafNode(); - if (leaf != null && leaf.isInIterable() && leaf.getName() == null) { // TODO: avoid to be here + if (isAwaitingPropertyName(leaf)) { if (!PropertyNode.class.isInstance(leaf)) { final NodeImpl tmp = new NodeImpl.PropertyNodeImpl(leaf); removeLeafNode(); @@ -221,13 +225,7 @@ public class PathImpl implements Path, Serializable { return; } } - final NodeImpl node; - if ("<cross-parameter>".equals(name)) { - node = new NodeImpl.CrossParameterNodeImpl(); - } else { - node = new NodeImpl.PropertyNodeImpl(name); - } - addNode(node); + addNode(new NodeImpl.PropertyNodeImpl(name)); } /**