You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by mb...@apache.org on 2018/03/12 18:40:00 UTC
[1/2] bval git commit: pass email validation TCK tests by factoring
out AbstractPatternValidator to validate @Email's additional regexp
constraint
Repository: bval
Updated Branches:
refs/heads/bv2 b10dc6833 -> 51b9ab27b
pass email validation TCK tests by factoring out AbstractPatternValidator to validate @Email's additional regexp constraint
Project: http://git-wip-us.apache.org/repos/asf/bval/repo
Commit: http://git-wip-us.apache.org/repos/asf/bval/commit/617fb7c7
Tree: http://git-wip-us.apache.org/repos/asf/bval/tree/617fb7c7
Diff: http://git-wip-us.apache.org/repos/asf/bval/diff/617fb7c7
Branch: refs/heads/bv2
Commit: 617fb7c7535781522b92268166a195653f75502f
Parents: b10dc68
Author: Matt Benson <mb...@apache.org>
Authored: Fri Mar 9 14:06:15 2018 -0600
Committer: Matt Benson <mb...@apache.org>
Committed: Fri Mar 9 14:06:15 2018 -0600
----------------------------------------------------------------------
.../constraints/AbstractPatternValidator.java | 72 ++++++++++++++++++++
.../apache/bval/constraints/EmailValidator.java | 25 +++++--
.../bval/constraints/PatternValidator.java | 38 ++++-------
3 files changed, 106 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/bval/blob/617fb7c7/bval-jsr/src/main/java/org/apache/bval/constraints/AbstractPatternValidator.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/constraints/AbstractPatternValidator.java b/bval-jsr/src/main/java/org/apache/bval/constraints/AbstractPatternValidator.java
new file mode 100644
index 0000000..888eb51
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/constraints/AbstractPatternValidator.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.constraints;
+
+import java.lang.annotation.Annotation;
+import java.util.function.Function;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraints.Pattern.Flag;
+
+import org.apache.bval.util.Validate;
+
+public abstract class AbstractPatternValidator<A extends Annotation, T extends CharSequence>
+ implements ConstraintValidator<A, T> {
+
+ public interface PatternDescriptor {
+ String regexp();
+
+ Flag[] flags();
+ }
+
+ private final Function<A, PatternDescriptor> toDescriptor;
+
+ protected Pattern pattern;
+
+ protected AbstractPatternValidator(Function<A, PatternDescriptor> toDescriptor) {
+ super();
+ this.toDescriptor = Validate.notNull(toDescriptor);
+ }
+
+ @Override
+ public void initialize(A constraintAnnotation) {
+ ConstraintValidator.super.initialize(constraintAnnotation);
+
+ final PatternDescriptor pd = toDescriptor.apply(constraintAnnotation);
+
+ final Flag flags[] = pd.flags();
+ int intFlag = 0;
+ for (Flag flag : flags) {
+ intFlag = intFlag | flag.getValue();
+ }
+ try {
+ pattern = Pattern.compile(pd.regexp(), intFlag);
+ } catch (PatternSyntaxException e) {
+ throw new IllegalArgumentException("Invalid regular expression.", e);
+ }
+ }
+
+ @Override
+ public boolean isValid(T value, ConstraintValidatorContext context) {
+ return value == null || pattern.matcher(value).matches();
+ }
+}
http://git-wip-us.apache.org/repos/asf/bval/blob/617fb7c7/bval-jsr/src/main/java/org/apache/bval/constraints/EmailValidator.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/constraints/EmailValidator.java b/bval-jsr/src/main/java/org/apache/bval/constraints/EmailValidator.java
index b20806b..dca7753 100644
--- a/bval-jsr/src/main/java/org/apache/bval/constraints/EmailValidator.java
+++ b/bval-jsr/src/main/java/org/apache/bval/constraints/EmailValidator.java
@@ -18,18 +18,33 @@
*/
package org.apache.bval.constraints;
-import org.apache.bval.routines.EMailValidationUtils;
-
-import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraints.Pattern.Flag;
+
+import org.apache.bval.routines.EMailValidationUtils;
/**
* Description: <br/>
*/
-public class EmailValidator implements ConstraintValidator<javax.validation.constraints.Email, CharSequence> {
+public class EmailValidator extends AbstractPatternValidator<javax.validation.constraints.Email, CharSequence> {
+
+ public EmailValidator() {
+ super(email -> new PatternDescriptor() {
+
+ @Override
+ public String regexp() {
+ return email.regexp();
+ }
+
+ @Override
+ public Flag[] flags() {
+ return email.flags();
+ }
+ });
+ }
@Override
public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
- return EMailValidationUtils.isValid(value);
+ return EMailValidationUtils.isValid(value) && super.isValid(value, context);
}
}
http://git-wip-us.apache.org/repos/asf/bval/blob/617fb7c7/bval-jsr/src/main/java/org/apache/bval/constraints/PatternValidator.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/constraints/PatternValidator.java b/bval-jsr/src/main/java/org/apache/bval/constraints/PatternValidator.java
index 8a53062..3d0fdd4 100644
--- a/bval-jsr/src/main/java/org/apache/bval/constraints/PatternValidator.java
+++ b/bval-jsr/src/main/java/org/apache/bval/constraints/PatternValidator.java
@@ -18,35 +18,25 @@
*/
package org.apache.bval.constraints;
-import javax.validation.ConstraintValidator;
-import javax.validation.ConstraintValidatorContext;
import javax.validation.constraints.Pattern;
-import java.util.regex.PatternSyntaxException;
+import javax.validation.constraints.Pattern.Flag;
/**
- * validator using a regular expression,
- * based on the jsr Pattern constraint annotation.
+ * validator using a regular expression, based on the jsr Pattern constraint annotation.
*/
-public class PatternValidator implements ConstraintValidator<Pattern, CharSequence> {
- protected java.util.regex.Pattern pattern;
+public class PatternValidator extends AbstractPatternValidator<Pattern, CharSequence> {
+ public PatternValidator() {
+ super(p -> new PatternDescriptor() {
- @Override
- public void initialize(Pattern annotation) {
- final Pattern.Flag flags[] = annotation.flags();
- int intFlag = 0;
- for (Pattern.Flag flag : flags) {
- intFlag = intFlag | flag.getValue();
- }
+ @Override
+ public String regexp() {
+ return p.regexp();
+ }
- try {
- pattern = java.util.regex.Pattern.compile(annotation.regexp(), intFlag);
- } catch (PatternSyntaxException e) {
- throw new IllegalArgumentException("Invalid regular expression.", e);
- }
- }
-
- @Override
- public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
- return value == null || pattern.matcher(value).matches();
+ @Override
+ public Flag[] flags() {
+ return p.flags();
+ }
+ });
}
}
[2/2] bval git commit: TCK: GroupConversionValidationTest
Posted by mb...@apache.org.
TCK: GroupConversionValidationTest
Project: http://git-wip-us.apache.org/repos/asf/bval/repo
Commit: http://git-wip-us.apache.org/repos/asf/bval/commit/51b9ab27
Tree: http://git-wip-us.apache.org/repos/asf/bval/tree/51b9ab27
Diff: http://git-wip-us.apache.org/repos/asf/bval/diff/51b9ab27
Branch: refs/heads/bv2
Commit: 51b9ab27b910e180caae05c2e46f846c935560c3
Parents: 617fb7c
Author: Matt Benson <mb...@apache.org>
Authored: Mon Mar 12 13:39:53 2018 -0500
Committer: Matt Benson <mb...@apache.org>
Committed: Mon Mar 12 13:39:53 2018 -0500
----------------------------------------------------------------------
.../apache/bval/jsr/groups/GroupsComputer.java | 51 ++++++++++++++++++++
.../org/apache/bval/jsr/job/ValidationJob.java | 16 +++++-
.../org/apache/bval/jsr/metadata/Liskov.java | 32 ++++++++++--
3 files changed, 93 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/bval/blob/51b9ab27/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java b/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java
index ae6f629..8f4cdda 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java
@@ -27,11 +27,13 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
import javax.validation.GroupDefinitionException;
import javax.validation.GroupSequence;
import javax.validation.ValidationException;
import javax.validation.groups.Default;
+import javax.validation.metadata.GroupConversionDescriptor;
import org.apache.bval.util.Exceptions;
import org.apache.bval.util.Validate;
@@ -72,6 +74,55 @@ public class GroupsComputer {
}
/**
+ * Compute groups for a single cascading validation taking into account the specified set of
+ * {@link GroupConversionDescriptor}s.
+ *
+ * @param groupConversions
+ * @param group
+ * @return {@link Groups}
+ */
+ public final Groups computeCascadingGroups(Set<GroupConversionDescriptor> groupConversions, Class<?> group) {
+ final Groups preliminaryResult = computeGroups(group);
+
+ final Map<Class<?>, Class<?>> gcMap = groupConversions.stream()
+ .collect(Collectors.toMap(GroupConversionDescriptor::getFrom, GroupConversionDescriptor::getTo));
+
+ final boolean simpleGroup = preliminaryResult.getSequences().isEmpty();
+
+ // conversion of a simple (non-sequence) group:
+ if (simpleGroup && gcMap.containsKey(group)) {
+ return computeGroups(gcMap.get(group));
+ }
+
+ final Groups result = new Groups();
+
+ if (simpleGroup) {
+ // ignore group inheritance from initial argument as that is handled elsewhere:
+ result.insertGroup(preliminaryResult.getGroups().get(0));
+ } else {
+ // expand group sequence conversions in place:
+
+ for (List<Group> seq : preliminaryResult.getSequences()) {
+ final List<Group> converted = new ArrayList<>();
+ for (Group gg : seq) {
+ final Class<?> c = gg.getGroup();
+ if (gcMap.containsKey(c)) {
+ final Groups convertedGroupExpansion = computeGroups(gcMap.get(c));
+ if (convertedGroupExpansion.getSequences().isEmpty()) {
+ converted.add(gg);
+ } else {
+ convertedGroupExpansion.getSequences().stream().flatMap(Collection::stream)
+ .forEach(converted::add);
+ }
+ }
+ }
+ result.insertSequence(converted);
+ }
+ }
+ return result;
+ }
+
+ /**
* Main compute implementation.
*
* @param groups
http://git-wip-us.apache.org/repos/asf/bval/blob/51b9ab27/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 70905d0..f2eaa26 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
@@ -271,6 +271,20 @@ public abstract class ValidationJob<T> {
@Override
void recurse(Class<?> group, Consumer<ConstraintViolation<T>> sink) {
+ final Groups convertedGroups =
+ validatorContext.getGroupsComputer().computeCascadingGroups(descriptor.getGroupConversions(), group);
+
+ convertedGroups.getGroups().stream().map(Group::getGroup).forEach(g -> recurseSingleExpandedGroup(g, sink));
+
+ sequences: for (List<Group> seq : convertedGroups.getSequences()) {
+ final boolean proceed = each(seq.stream().map(Group::getGroup), this::recurseSingleExpandedGroup, sink);
+ if (!proceed) {
+ break sequences;
+ }
+ }
+ }
+
+ protected void recurseSingleExpandedGroup(Class<?> group, Consumer<ConstraintViolation<T>> sink) {
@SuppressWarnings({ "unchecked", "rawtypes" })
final Stream<ContainerElementTypeD> containerElements = descriptor.getConstrainedContainerElementTypes()
.stream().flatMap(d -> ComposedD.unwrap(d, (Class) ContainerElementTypeD.class));
@@ -363,7 +377,7 @@ public abstract class ValidationJob<T> {
}
@Override
- void recurse(Class<?> group, Consumer<ConstraintViolation<T>> sink) {
+ protected void recurseSingleExpandedGroup(Class<?> group, Consumer<ConstraintViolation<T>> sink) {
final PathImpl path = context.getPath();
final NodeImpl leafNode = path.getLeafNode();
http://git-wip-us.apache.org/repos/asf/bval/blob/51b9ab27/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Liskov.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Liskov.java b/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Liskov.java
index a3701d4..2440948 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Liskov.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Liskov.java
@@ -18,6 +18,7 @@ package org.apache.bval.jsr.metadata;
import java.lang.annotation.ElementType;
import java.util.Collection;
+import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -115,8 +116,17 @@ class Liskov {
}
switch (elementKind) {
case RETURN_VALUE:
- noStrengtheningOfPreconditions(delegates, detectGroupConversion());
noRedeclarationOfReturnValueCascading(delegates);
+
+ final Map<Meta<?>, Set<ValidationElement>> detectedValidationElements =
+ detectValidationElements(delegates, detectGroupConversion());
+
+ // pre-check return value overridden hierarchy:
+ Stream.of(StrengtheningIssue.values())
+ .filter((Predicate<? super StrengtheningIssue>) si -> !(si == StrengtheningIssue.overriddenHierarchy
+ && detectedValidationElements.values().stream().filter(s -> !s.isEmpty()).count() < 2))
+ .forEach(si -> si.check(detectedValidationElements));
+
break;
case PARAMETER:
noStrengtheningOfPreconditions(delegates, detectConstraints(), detectCascading(), detectGroupConversion());
@@ -160,6 +170,20 @@ class Liskov {
private static <D extends ElementDelegate<?, ?>> void noStrengtheningOfPreconditions(List<? extends D> delegates,
Function<? super D, ValidationElement>... detectors) {
+ final Map<Meta<?>, Set<ValidationElement>> detectedValidationElements =
+ detectValidationElements(delegates, detectors);
+
+ if (detectedValidationElements.isEmpty()) {
+ return;
+ }
+ for (StrengtheningIssue s : StrengtheningIssue.values()) {
+ s.check(detectedValidationElements);
+ }
+ }
+
+ @SafeVarargs
+ private static <D extends ElementDelegate<?, ?>> Map<Meta<?>, Set<ValidationElement>> detectValidationElements(
+ List<? extends D> delegates, Function<? super D, ValidationElement>... detectors) {
final Map<Meta<?>, Set<ValidationElement>> detectedValidationElements = new LinkedHashMap<>();
delegates.forEach(d -> {
detectedValidationElements.put(d.getHierarchyElement(),
@@ -168,11 +192,9 @@ class Liskov {
});
if (detectedValidationElements.values().stream().allMatch(Collection::isEmpty)) {
// nothing declared
- return;
- }
- for (StrengtheningIssue s : StrengtheningIssue.values()) {
- s.check(detectedValidationElements);
+ return Collections.emptyMap();
}
+ return detectedValidationElements;
}
private static boolean related(Class<?> c1, Class<?> c2) {