Repository: bval Updated Branches: refs/heads/bv2 4dbe0936b -> 648bebe51
refactor and permit unwrapping if a single maximally specific unwrapByDefault ValueExtractor is found when the constraint has DEFAULT valueUnwrapping Project: http://git-wip-us.apache.org/repos/asf/bval/repo Commit: http://git-wip-us.apache.org/repos/asf/bval/commit/648bebe5 Tree: http://git-wip-us.apache.org/repos/asf/bval/tree/648bebe5 Diff: http://git-wip-us.apache.org/repos/asf/bval/diff/648bebe5 Branch: refs/heads/bv2 Commit: 648bebe5133b31396d723ef8fe10a63d25650a2e Parents: 4dbe093 Author: Matt Benson <[email protected]> Authored: Thu Mar 29 17:55:23 2018 -0500 Committer: Matt Benson <[email protected]> Committed: Thu Mar 29 17:55:23 2018 -0500 ---------------------------------------------------------------------- .../jsr/valueextraction/ValueExtractors.java | 74 +++++++++++--------- 1 file changed, 42 insertions(+), 32 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/bval/blob/648bebe5/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ValueExtractors.java ---------------------------------------------------------------------- diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ValueExtractors.java b/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ValueExtractors.java index f635c92..430f267 100644 --- a/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ValueExtractors.java +++ b/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ValueExtractors.java @@ -73,6 +73,43 @@ public class ValueExtractors { this.containerElementKey = containerElementKey; this.valueExtractor = valueExtractor; } + + UnwrappingInfo inTermsOf(Class<?> containerClass) { + final Class<?> keyContainer = containerElementKey.getContainerClass(); + if (keyContainer.equals(containerClass)) { + return this; + } + Validate.validState(keyContainer.isAssignableFrom(containerClass), "Cannot render %s in terms of %s", + containerElementKey, containerClass); + + final ContainerElementKey key; + + if (containerElementKey.getTypeArgumentIndex() == null) { + key = new ContainerElementKey(containerClass, null); + } else { + Integer typeArgumentIndex = null; + final Map<TypeVariable<?>, Type> typeArguments = + TypeUtils.getTypeArguments(containerClass, keyContainer); + Type t = typeArguments + .get(keyContainer.getTypeParameters()[containerElementKey.getTypeArgumentIndex().intValue()]); + while (t instanceof TypeVariable<?>) { + final TypeVariable<?> var = (TypeVariable<?>) t; + if (containerClass.equals(var.getGenericDeclaration())) { + typeArgumentIndex = + Integer.valueOf(ObjectUtils.indexOf(containerClass.getTypeParameters(), var)); + break; + } + t = typeArguments.get(t); + } + key = new ContainerElementKey(containerClass, typeArgumentIndex); + } + return new UnwrappingInfo(key, valueExtractor); + } + + @Override + public String toString() { + return String.format("%s:%s", containerElementKey, valueExtractor); + } } public static final ValueExtractors EMPTY = @@ -279,45 +316,18 @@ public class ValueExtractors { final Set<UnwrappingInfo> unwrapping = allValueExtractors.entrySet().stream() .filter(e -> e.getKey().getContainerClass().isAssignableFrom(containerClass)) + .filter(e -> valueUnwrapping == ValidateUnwrappedValue.UNWRAP || isUnwrapByDefault(e.getValue())) .map(e -> new UnwrappingInfo(e.getKey(), e.getValue())).collect(Collectors.toSet()); final Optional<UnwrappingInfo> result = - maximallySpecific(unwrapping, u -> u.containerElementKey.getContainerClass()); + maximallySpecific(unwrapping, u -> u.containerElementKey.getContainerClass()) + .map(u -> u.inTermsOf(containerClass)); - if (result.isPresent()) { - if (valueUnwrapping == ValidateUnwrappedValue.UNWRAP || isUnwrapByDefault(result.get().valueExtractor)) { - return result - .map(u -> new UnwrappingInfo(translateTo(containerClass, u.containerElementKey), u.valueExtractor)); - } - } else if (valueUnwrapping == ValidateUnwrappedValue.UNWRAP) { + if (!result.isPresent() && valueUnwrapping == ValidateUnwrappedValue.UNWRAP) { Exceptions.raise(ConstraintDeclarationException::new, "Could not determine %s for %s", ValueExtractor.class.getSimpleName(), containerClass); } - return Optional.empty(); - } - - private static ContainerElementKey translateTo(Class<?> containerClass, ContainerElementKey key) { - final Class<?> keyContainer = key.getContainerClass(); - if (keyContainer.equals(containerClass)) { - return key; - } - Validate.validState(keyContainer.isAssignableFrom(containerClass), "Cannot render %s in terms of %s", key, - containerClass); - if (key.getTypeArgumentIndex() == null) { - return new ContainerElementKey(containerClass, null); - } - Integer typeArgumentIndex = null; - final Map<TypeVariable<?>, Type> typeArguments = TypeUtils.getTypeArguments(containerClass, keyContainer); - Type t = typeArguments.get(keyContainer.getTypeParameters()[key.getTypeArgumentIndex().intValue()]); - while (t instanceof TypeVariable<?>) { - final TypeVariable<?> var = (TypeVariable<?>) t; - if (containerClass.equals(var.getGenericDeclaration())) { - typeArgumentIndex = Integer.valueOf(ObjectUtils.indexOf(containerClass.getTypeParameters(), var)); - break; - } - t = typeArguments.get(t); - } - return new ContainerElementKey(containerClass, typeArgumentIndex); + return result; } private void populate(Supplier<Map<ContainerElementKey, ValueExtractor<?>>> target) {
