bval-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mben...@apache.org
Subject [15/15] bval git commit: wip
Date Wed, 15 Nov 2017 22:54:20 GMT
wip


Project: http://git-wip-us.apache.org/repos/asf/bval/repo
Commit: http://git-wip-us.apache.org/repos/asf/bval/commit/a43c0b0c
Tree: http://git-wip-us.apache.org/repos/asf/bval/tree/a43c0b0c
Diff: http://git-wip-us.apache.org/repos/asf/bval/diff/a43c0b0c

Branch: refs/heads/bv2
Commit: a43c0b0c7ee43f11a7baa61267db4f00bc20bd4c
Parents: 31e1eff
Author: Matt Benson <mbenson@apache.org>
Authored: Wed Nov 15 16:52:45 2017 -0600
Committer: Matt Benson <mbenson@apache.org>
Committed: Wed Nov 15 16:53:43 2017 -0600

----------------------------------------------------------------------
 .../constraints/FutureOrPresentValidator.java   | 138 ++++
 .../bval/constraints/FutureValidator.java       | 138 ++++
 .../bval/constraints/NotBlankValidator.java     |  34 +
 .../bval/constraints/NumberSignValidator.java   |  68 ++
 .../constraints/PastOrPresentValidator.java     | 138 ++++
 .../apache/bval/constraints/PastValidator.java  | 138 ++++
 .../apache/bval/constraints/TimeValidator.java  |  44 ++
 .../apache/bval/context/ValidationContext.java  | 126 ++++
 .../bval/jsr/AbstractConstraintDescriptor.java  |  32 +
 .../apache/bval/jsr/ApacheFactoryContext.java   |  83 +-
 .../bval/jsr/ApacheValidatorConfiguration.java  |   7 +-
 .../apache/bval/jsr/ApacheValidatorFactory.java | 161 ++--
 .../bval/jsr/BootstrapConfigurationImpl.java    |  29 +-
 .../org/apache/bval/jsr/ConfigurationImpl.java  | 128 ++--
 .../jsr/ConstraintAnnotationAttributes.java     |  38 +-
 .../org/apache/bval/jsr/ConstraintCached.java   |  98 ++-
 .../org/apache/bval/jsr/ConstraintDefaults.java |  24 +-
 .../bval/jsr/ConstraintDescriptorImpl.java      |  13 +
 .../apache/bval/jsr/ConstraintValidation.java   |  33 +-
 .../jsr/ConstraintValidatorContextImpl.java     |  20 +-
 .../bval/jsr/ConstraintViolationImpl.java       |  69 +-
 .../java/org/apache/bval/jsr/GraphContext.java  |  75 ++
 .../jsr/NodeBuilderCustomizableContextImpl.java |  89 +++
 .../apache/bval/jsr/NodeContextBuilderImpl.java |  88 +++
 .../bval/jsr/ParameterDescriptorImpl.java       |   7 +
 .../apache/bval/jsr/PropertyDescriptorImpl.java |   9 +
 .../bval/jsr/ReturnValueDescriptorImpl.java     |   8 +
 .../java/org/apache/bval/jsr/ValidatorImpl.java | 141 ++++
 .../org/apache/bval/jsr/descriptor/BeanD.java   | 112 +++
 .../jsr/descriptor/CascadableContainerD.java    |  92 +++
 .../apache/bval/jsr/descriptor/ComposedD.java   | 125 ++++
 .../ComputeConstraintValidatorClass.java        | 147 ++++
 .../apache/bval/jsr/descriptor/ConstraintD.java | 206 +++++
 .../bval/jsr/descriptor/ConstructorD.java       |  36 +
 .../jsr/descriptor/ContainerElementTypeD.java   | 119 +++
 .../bval/jsr/descriptor/CrossParameterD.java    |  18 +
 .../bval/jsr/descriptor/DescriptorManager.java  |  68 ++
 .../apache/bval/jsr/descriptor/ElementD.java    | 103 +++
 .../apache/bval/jsr/descriptor/ExecutableD.java |  89 +++
 .../org/apache/bval/jsr/descriptor/Finder.java  | 100 +++
 .../bval/jsr/descriptor/GroupConversion.java    |  85 +++
 .../bval/jsr/descriptor/MetadataReader.java     | 266 +++++++
 .../org/apache/bval/jsr/descriptor/MethodD.java |  44 ++
 .../apache/bval/jsr/descriptor/ParameterD.java  |  62 ++
 .../apache/bval/jsr/descriptor/PropertyD.java   | 142 ++++
 .../bval/jsr/descriptor/ReturnValueD.java       |  36 +
 .../jsr/job/ConstraintValidatorContextImpl.java | 194 +++++
 .../org/apache/bval/jsr/job/ValidateBean.java   |  58 ++
 .../apache/bval/jsr/job/ValidateParameters.java | 165 ++++
 .../apache/bval/jsr/job/ValidateProperty.java   |  95 +++
 .../bval/jsr/job/ValidateReturnValue.java       | 104 +++
 .../org/apache/bval/jsr/job/ValidationJob.java  | 245 ++++++
 .../bval/jsr/job/ValidationJobFactory.java      | 105 +++
 .../bval/jsr/metadata/AnnotationBehavior.java   |  34 +
 .../AnnotationBehaviorMergeStrategy.java        |  54 ++
 .../bval/jsr/metadata/CompositeBuilder.java     | 232 ++++++
 .../bval/jsr/metadata/ContainerElementKey.java  | 164 ++++
 .../apache/bval/jsr/metadata/EmptyBuilder.java  | 183 +++++
 .../bval/jsr/metadata/HierarchyBuilder.java     | 134 ++++
 .../bval/jsr/metadata/MetadataBuilder.java      | 104 +++
 .../bval/jsr/metadata/MetadataBuilders.java     |  41 +
 .../org/apache/bval/jsr/metadata/Metas.java     | 245 ++++++
 .../bval/jsr/metadata/ParallelBuilder.java      | 238 ++++++
 .../bval/jsr/metadata/ReflectionBuilder.java    | 245 ++++++
 .../org/apache/bval/jsr/metadata/Signature.java |  75 ++
 .../apache/bval/jsr/metadata/XmlBuilder.java    | 715 ++++++++++++++++++
 .../bval/jsr/util/AnnotationsManager.java       | 279 +++++++
 ...ementNodeBuilderCustomizableContextImpl.java |  77 ++
 ...nerElementNodeBuilderDefinedContextImpl.java |  65 ++
 .../ContainerElementNodeContextBuilderImpl.java |  85 +++
 .../org/apache/bval/jsr/util/Exceptions.java    |  65 ++
 .../java/org/apache/bval/jsr/util/LRUCache.java |  40 +
 .../LeafNodeBuilderCustomizableContextImpl.java |  23 +-
 .../java/org/apache/bval/jsr/util/Methods.java  |  45 ++
 .../NodeBuilderCustomizableContextImpl.java     |  55 +-
 .../jsr/util/NodeBuilderDefinedContextImpl.java |  32 +-
 .../bval/jsr/util/NodeContextBuilderImpl.java   |  52 +-
 .../java/org/apache/bval/jsr/util/NodeImpl.java | 103 ++-
 .../java/org/apache/bval/jsr/util/PathImpl.java |  50 +-
 .../apache/bval/jsr/util/ToUnmodifiable.java    |  28 +
 .../bval/jsr/valueextraction/FxExtractor.java   |  96 +++
 .../IterableElementExtractor.java               |  30 +
 .../valueextraction/ListElementExtractor.java   |  34 +
 .../bval/jsr/valueextraction/MapExtractor.java  |  42 ++
 .../jsr/valueextraction/OptionalExtractor.java  |  65 ++
 .../jsr/valueextraction/ValueExtractors.java    | 167 +++++
 .../apache/bval/jsr/xml/AnnotationProxy.java    |  59 +-
 .../bval/jsr/xml/AnnotationProxyBuilder.java    |  61 +-
 .../org/apache/bval/jsr/xml/SchemaManager.java  | 286 +++++++
 .../bval/jsr/xml/ValidationMappingParser.java   | 749 ++-----------------
 .../apache/bval/jsr/xml/ValidationParser.java   | 330 ++++----
 .../java/org/apache/bval/jsr/xml/XmlUtils.java  |  67 ++
 .../bval/jsr/DefaultConstraints.properties      |  73 +-
 .../DefaultExtractors.properties                |  25 +
 bval-jsr/src/main/xjb/binding-customization.xjb |   4 +-
 .../main/xsd/validation-configuration-2.0.xsd   |  75 ++
 .../src/main/xsd/validation-mapping-2.0.xsd     | 297 ++++++++
 .../bval/jsr/CustomValidatorFactoryTest.java    |   6 +
 .../test/java/org/apache/bval/jsr/xml/Demo.java |  40 +
 .../bval/jsr/xml/ValidationParserTest.java      |  12 +
 .../src/test/resources/sample-validation11.xml  |  30 +
 .../src/test/resources/sample-validation2.xml   |  30 +
 102 files changed, 9526 insertions(+), 1307 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/constraints/FutureOrPresentValidator.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/constraints/FutureOrPresentValidator.java b/bval-jsr/src/main/java/org/apache/bval/constraints/FutureOrPresentValidator.java
new file mode 100644
index 0000000..4cc85b1
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/constraints/FutureOrPresentValidator.java
@@ -0,0 +1,138 @@
+/*
+ * 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.time.Clock;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.MonthDay;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.Year;
+import java.time.YearMonth;
+import java.time.ZonedDateTime;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.ChronoZonedDateTime;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.function.Function;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.constraints.FutureOrPresent;
+
+/**
+ * Defines built-in {@link ConstraintValidator} implementations for {@link FutureOrPresent}.
+ *
+ * @param <T>
+ *            validated type
+ */
+public abstract class FutureOrPresentValidator<T extends Comparable<T>> extends TimeValidator<FutureOrPresent, T> {
+
+    public static class ForDate extends FutureOrPresentValidator<Date> {
+
+        public ForDate() {
+            super(clock -> Date.from(clock.instant()));
+        }
+    }
+
+    public static class ForCalendar extends FutureOrPresentValidator<Calendar> {
+
+        public ForCalendar() {
+            super(clock -> GregorianCalendar.from(clock.instant().atZone(clock.getZone())));
+        }
+    }
+
+    public static class ForInstant extends FutureOrPresentValidator<Instant> {
+
+        public ForInstant() {
+            super(Instant::now);
+        }
+    }
+
+    public static class ForChronoLocalDate extends FutureOrPresentValidator<ChronoLocalDate> {
+
+        public ForChronoLocalDate() {
+            super(LocalDate::now);
+        }
+    }
+
+    public static class ForChronoLocalDateTime extends FutureOrPresentValidator<ChronoLocalDateTime<?>> {
+
+        public ForChronoLocalDateTime() {
+            super(LocalDateTime::now);
+        }
+    }
+
+    public static class ForLocalTime extends FutureOrPresentValidator<LocalTime> {
+
+        public ForLocalTime() {
+            super(LocalTime::now);
+        }
+    }
+
+    public static class ForOffsetDateTime extends FutureOrPresentValidator<OffsetDateTime> {
+
+        public ForOffsetDateTime() {
+            super(OffsetDateTime::now);
+        }
+    }
+
+    public static class ForOffsetTime extends FutureOrPresentValidator<OffsetTime> {
+
+        public ForOffsetTime() {
+            super(OffsetTime::now);
+        }
+    }
+
+    public static class ForChronoZonedDateTime extends FutureOrPresentValidator<ChronoZonedDateTime<?>> {
+
+        public ForChronoZonedDateTime() {
+            super(ZonedDateTime::now);
+        }
+    }
+
+    public static class ForMonthDay extends FutureOrPresentValidator<MonthDay> {
+
+        public ForMonthDay() {
+            super(MonthDay::now);
+        }
+    }
+
+    public static class ForYear extends FutureOrPresentValidator<Year> {
+
+        public ForYear() {
+            super(Year::now);
+        }
+    }
+
+    public static class ForYearMonth extends FutureOrPresentValidator<YearMonth> {
+
+        public ForYearMonth() {
+            super(YearMonth::now);
+        }
+    }
+
+    protected FutureOrPresentValidator(Function<Clock, T> now) {
+        super(now, n -> n >= 0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/constraints/FutureValidator.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/constraints/FutureValidator.java b/bval-jsr/src/main/java/org/apache/bval/constraints/FutureValidator.java
new file mode 100644
index 0000000..dd6116b
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/constraints/FutureValidator.java
@@ -0,0 +1,138 @@
+/*
+ * 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.time.Clock;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.MonthDay;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.Year;
+import java.time.YearMonth;
+import java.time.ZonedDateTime;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.ChronoZonedDateTime;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.function.Function;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.constraints.Future;
+
+/**
+ * Defines built-in {@link ConstraintValidator} implementations for {@link Future}.
+ *
+ * @param <T>
+ *            validated type
+ */
+public abstract class FutureValidator<T extends Comparable<T>> extends TimeValidator<Future, T> {
+
+    public static class ForDate extends FutureValidator<Date> {
+
+        public ForDate() {
+            super(clock -> Date.from(clock.instant()));
+        }
+    }
+
+    public static class ForCalendar extends FutureValidator<Calendar> {
+
+        public ForCalendar() {
+            super(clock -> GregorianCalendar.from(clock.instant().atZone(clock.getZone())));
+        }
+    }
+
+    public static class ForInstant extends FutureValidator<Instant> {
+
+        public ForInstant() {
+            super(Instant::now);
+        }
+    }
+
+    public static class ForChronoLocalDate extends FutureValidator<ChronoLocalDate> {
+
+        public ForChronoLocalDate() {
+            super(LocalDate::now);
+        }
+    }
+
+    public static class ForChronoLocalDateTime extends FutureValidator<ChronoLocalDateTime<?>> {
+
+        public ForChronoLocalDateTime() {
+            super(LocalDateTime::now);
+        }
+    }
+
+    public static class ForLocalTime extends FutureValidator<LocalTime> {
+
+        public ForLocalTime() {
+            super(LocalTime::now);
+        }
+    }
+
+    public static class ForOffsetDateTime extends FutureValidator<OffsetDateTime> {
+
+        public ForOffsetDateTime() {
+            super(OffsetDateTime::now);
+        }
+    }
+
+    public static class ForOffsetTime extends FutureValidator<OffsetTime> {
+
+        public ForOffsetTime() {
+            super(OffsetTime::now);
+        }
+    }
+
+    public static class ForChronoZonedDateTime extends FutureValidator<ChronoZonedDateTime<?>> {
+
+        public ForChronoZonedDateTime() {
+            super(ZonedDateTime::now);
+        }
+    }
+
+    public static class ForMonthDay extends FutureValidator<MonthDay> {
+
+        public ForMonthDay() {
+            super(MonthDay::now);
+        }
+    }
+
+    public static class ForYear extends FutureValidator<Year> {
+
+        public ForYear() {
+            super(Year::now);
+        }
+    }
+
+    public static class ForYearMonth extends FutureValidator<YearMonth> {
+
+        public ForYearMonth() {
+            super(YearMonth::now);
+        }
+    }
+
+    protected FutureValidator(Function<Clock, T> now) {
+        super(now, n -> n > 0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/constraints/NotBlankValidator.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/constraints/NotBlankValidator.java b/bval-jsr/src/main/java/org/apache/bval/constraints/NotBlankValidator.java
new file mode 100644
index 0000000..e201c0d
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/constraints/NotBlankValidator.java
@@ -0,0 +1,34 @@
+/*
+ * 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 javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraints.NotBlank;
+
+/**
+ * Validate {@link NotBlank} for {@link CharSequence}.
+ */
+public class NotBlankValidator implements ConstraintValidator<NotBlank, CharSequence> {
+
+    @Override
+    public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
+        return value == null || value.length() > 0 && !value.chars().allMatch(Character::isWhitespace);
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/constraints/NumberSignValidator.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/constraints/NumberSignValidator.java b/bval-jsr/src/main/java/org/apache/bval/constraints/NumberSignValidator.java
new file mode 100644
index 0000000..fe8f59c
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/constraints/NumberSignValidator.java
@@ -0,0 +1,68 @@
+/*
+ * 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.util.function.IntPredicate;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraints.Negative;
+
+import org.apache.bval.util.Validate;
+
+/**
+ * Description: validate positive/negative number values.
+ */
+public abstract class NumberSignValidator implements ConstraintValidator<Negative, Number> {
+    public static class ForPositive extends NumberSignValidator {
+        public static class OrZero extends NumberSignValidator {
+            public OrZero() {
+                super(n -> n >= 0);
+            }
+        }
+
+        public ForPositive() {
+            super(n -> n > 0);
+        }
+    }
+
+    public static class ForNegative extends NumberSignValidator {
+        public static class OrZero extends NumberSignValidator {
+            public OrZero() {
+                super(n -> n <= 0);
+            }
+        }
+
+        public ForNegative() {
+            super(n -> n < 0);
+        }
+    }
+    
+    private final IntPredicate comparisonTest;
+    
+    protected NumberSignValidator(IntPredicate comparisonTest) {
+        super();
+        this.comparisonTest = Validate.notNull(comparisonTest);
+    }
+
+    @Override
+    public boolean isValid(Number value, ConstraintValidatorContext context) {
+        return value == null || comparisonTest.test(Double.compare(value.doubleValue(), 0.0));
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/constraints/PastOrPresentValidator.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/constraints/PastOrPresentValidator.java b/bval-jsr/src/main/java/org/apache/bval/constraints/PastOrPresentValidator.java
new file mode 100644
index 0000000..d1e3e19
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/constraints/PastOrPresentValidator.java
@@ -0,0 +1,138 @@
+/*
+ * 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.time.Clock;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.MonthDay;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.Year;
+import java.time.YearMonth;
+import java.time.ZonedDateTime;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.ChronoZonedDateTime;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.function.Function;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.constraints.PastOrPresent;
+
+/**
+ * Defines built-in {@link ConstraintValidator} implementations for {@link PastOrPresent}.
+ *
+ * @param <T>
+ *            validated type
+ */
+public abstract class PastOrPresentValidator<T extends Comparable<T>> extends TimeValidator<PastOrPresent, T> {
+
+    public static class ForDate extends PastOrPresentValidator<Date> {
+
+        public ForDate() {
+            super(clock -> Date.from(clock.instant()));
+        }
+    }
+
+    public static class ForCalendar extends PastOrPresentValidator<Calendar> {
+
+        public ForCalendar() {
+            super(clock -> GregorianCalendar.from(clock.instant().atZone(clock.getZone())));
+        }
+    }
+
+    public static class ForInstant extends PastOrPresentValidator<Instant> {
+
+        public ForInstant() {
+            super(Instant::now);
+        }
+    }
+
+    public static class ForChronoLocalDate extends PastOrPresentValidator<ChronoLocalDate> {
+
+        public ForChronoLocalDate() {
+            super(LocalDate::now);
+        }
+    }
+
+    public static class ForChronoLocalDateTime extends PastOrPresentValidator<ChronoLocalDateTime<?>> {
+
+        public ForChronoLocalDateTime() {
+            super(LocalDateTime::now);
+        }
+    }
+
+    public static class ForLocalTime extends PastOrPresentValidator<LocalTime> {
+
+        public ForLocalTime() {
+            super(LocalTime::now);
+        }
+    }
+
+    public static class ForOffsetDateTime extends PastOrPresentValidator<OffsetDateTime> {
+
+        public ForOffsetDateTime() {
+            super(OffsetDateTime::now);
+        }
+    }
+
+    public static class ForOffsetTime extends PastOrPresentValidator<OffsetTime> {
+
+        public ForOffsetTime() {
+            super(OffsetTime::now);
+        }
+    }
+
+    public static class ForChronoZonedDateTime extends PastOrPresentValidator<ChronoZonedDateTime<?>> {
+
+        public ForChronoZonedDateTime() {
+            super(ZonedDateTime::now);
+        }
+    }
+
+    public static class ForMonthDay extends PastOrPresentValidator<MonthDay> {
+
+        public ForMonthDay() {
+            super(MonthDay::now);
+        }
+    }
+
+    public static class ForYear extends PastOrPresentValidator<Year> {
+
+        public ForYear() {
+            super(Year::now);
+        }
+    }
+
+    public static class ForYearMonth extends PastOrPresentValidator<YearMonth> {
+
+        public ForYearMonth() {
+            super(YearMonth::now);
+        }
+    }
+
+    protected PastOrPresentValidator(Function<Clock, T> now) {
+        super(now, n -> n <= 0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/constraints/PastValidator.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/constraints/PastValidator.java b/bval-jsr/src/main/java/org/apache/bval/constraints/PastValidator.java
new file mode 100644
index 0000000..0136d83
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/constraints/PastValidator.java
@@ -0,0 +1,138 @@
+/*
+ * 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.time.Clock;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.MonthDay;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.Year;
+import java.time.YearMonth;
+import java.time.ZonedDateTime;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.ChronoZonedDateTime;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.function.Function;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.constraints.Past;
+
+/**
+ * Defines built-in {@link ConstraintValidator} implementations for {@link Past}.
+ *
+ * @param <T>
+ *            validated type
+ */
+public abstract class PastValidator<T extends Comparable<T>> extends TimeValidator<Past, T> {
+
+    public static class ForDate extends PastValidator<Date> {
+
+        public ForDate() {
+            super(clock -> Date.from(clock.instant()));
+        }
+    }
+
+    public static class ForCalendar extends PastValidator<Calendar> {
+
+        public ForCalendar() {
+            super(clock -> GregorianCalendar.from(clock.instant().atZone(clock.getZone())));
+        }
+    }
+
+    public static class ForInstant extends PastValidator<Instant> {
+
+        public ForInstant() {
+            super(Instant::now);
+        }
+    }
+
+    public static class ForChronoLocalDate extends PastValidator<ChronoLocalDate> {
+
+        public ForChronoLocalDate() {
+            super(LocalDate::now);
+        }
+    }
+
+    public static class ForChronoLocalDateTime extends PastValidator<ChronoLocalDateTime<?>> {
+
+        public ForChronoLocalDateTime() {
+            super(LocalDateTime::now);
+        }
+    }
+
+    public static class ForLocalTime extends PastValidator<LocalTime> {
+
+        public ForLocalTime() {
+            super(LocalTime::now);
+        }
+    }
+
+    public static class ForOffsetDateTime extends PastValidator<OffsetDateTime> {
+
+        public ForOffsetDateTime() {
+            super(OffsetDateTime::now);
+        }
+    }
+
+    public static class ForOffsetTime extends PastValidator<OffsetTime> {
+
+        public ForOffsetTime() {
+            super(OffsetTime::now);
+        }
+    }
+
+    public static class ForChronoZonedDateTime extends PastValidator<ChronoZonedDateTime<?>> {
+
+        public ForChronoZonedDateTime() {
+            super(ZonedDateTime::now);
+        }
+    }
+
+    public static class ForMonthDay extends PastValidator<MonthDay> {
+
+        public ForMonthDay() {
+            super(MonthDay::now);
+        }
+    }
+
+    public static class ForYear extends PastValidator<Year> {
+
+        public ForYear() {
+            super(Year::now);
+        }
+    }
+
+    public static class ForYearMonth extends PastValidator<YearMonth> {
+
+        public ForYearMonth() {
+            super(YearMonth::now);
+        }
+    }
+
+    protected PastValidator(Function<Clock, T> now) {
+        super(now, n -> n < 0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/constraints/TimeValidator.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/constraints/TimeValidator.java b/bval-jsr/src/main/java/org/apache/bval/constraints/TimeValidator.java
new file mode 100644
index 0000000..02e3836
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/constraints/TimeValidator.java
@@ -0,0 +1,44 @@
+/*
+ * 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.time.Clock;
+import java.util.function.Function;
+import java.util.function.IntPredicate;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+public abstract class TimeValidator<A extends Annotation, T extends Comparable<T>> implements ConstraintValidator<A, T> {
+
+    private final Function<Clock, T> now;
+    private final IntPredicate test;
+    
+    protected TimeValidator(Function<Clock, T> now, IntPredicate test) {
+        super();
+        this.now = now;
+        this.test = test;
+    }
+
+    @Override
+    public final boolean isValid(T value, ConstraintValidatorContext context) {
+        return value == null || test.test(value.compareTo(now.apply(context.getClockProvider().getClock())));
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/context/ValidationContext.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/context/ValidationContext.java b/bval-jsr/src/main/java/org/apache/bval/context/ValidationContext.java
new file mode 100644
index 0000000..3cdd7bc
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/context/ValidationContext.java
@@ -0,0 +1,126 @@
+package org.apache.bval.context;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.validation.ClockProvider;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.Path;
+import javax.validation.ValidationException;
+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.descriptor.BeanD;
+import org.apache.bval.jsr.util.Exceptions;
+import org.apache.bval.jsr.util.PathImpl;
+import org.apache.bval.model.ValidationListener;
+import org.apache.bval.util.Validate;
+
+/**
+ * Context for a single validation call over one object or graph.
+ */
+public class ValidationContext {
+
+    abstract class ElementContext<D> {
+
+        class ValidatorContext implements ConstraintValidatorContext {
+            private final List<ValidationListener.Error> errorMessages = new LinkedList<>();
+            private boolean disableDefaultConstraintViolation;
+
+            /**
+             * Get the queued error messages.
+             * 
+             * @return List
+             */
+            List<ValidationListener.Error> getErrorMessages() {
+                if (disableDefaultConstraintViolation && errorMessages.isEmpty()) {
+                    throw new ValidationException(
+                        "At least one custom message must be created if the default error message gets disabled.");
+                }
+
+                List<ValidationListener.Error> returnedErrorMessages = new ArrayList<>(errorMessages);
+                if (!disableDefaultConstraintViolation) {
+                    returnedErrorMessages
+                        .add(new ValidationListener.Error(getDefaultConstraintMessageTemplate(), getPath(), null));
+                }
+                return returnedErrorMessages;
+            }
+
+            @Override
+            public void disableDefaultConstraintViolation() {
+                this.disableDefaultConstraintViolation = true;
+            }
+
+            @Override
+            public String getDefaultConstraintMessageTemplate() {
+                // TODO Auto-generated method stub
+                return null;
+            }
+
+            @Override
+            public ConstraintViolationBuilder buildConstraintViolationWithTemplate(String messageTemplate) {
+                // TODO Auto-generated method stub
+                return null;
+            }
+
+            @Override
+            public final ClockProvider getClockProvider() {
+                return validatorFactory.getClockProvider();
+            }
+
+            @Override
+            public final <T> T unwrap(Class<T> type) {
+                Exceptions.raiseUnless(type.isInstance(this), ValidationException::new, "Type %s not supported", type);
+
+                return type.cast(this);
+            }
+        }
+
+        protected final D descriptor;
+
+        ElementContext(D descriptor) {
+            super();
+            this.descriptor = Validate.notNull(descriptor, "descriptor");
+        }
+
+        protected abstract PathImpl getPath();
+    }
+
+    private class BeanContext extends ElementContext<BeanD> {
+        BeanContext(BeanD descriptor) {
+            super(descriptor);
+        }
+
+        @Override
+        protected PathImpl getPath() {
+            return PathImpl.create();
+        }
+    }
+
+    private class CascadableContainerContext<D extends ElementDescriptor & CascadableDescriptor & ContainerDescriptor>
+        extends ElementContext<D> {
+
+        private final PathImpl path;
+
+        CascadableContainerContext(D descriptor, Path path) {
+            super(descriptor);
+            this.path = PathImpl.copy(Validate.notNull(path, "path"));
+        }
+
+        @Override
+        protected PathImpl getPath() {
+            // careful, live
+            return path;
+        }
+    }
+
+    private final ApacheValidatorFactory validatorFactory;
+
+    public ValidationContext(ApacheValidatorFactory validatorFactory) {
+        super();
+        this.validatorFactory = Validate.notNull(validatorFactory, "validatorFactory");
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/jsr/AbstractConstraintDescriptor.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/AbstractConstraintDescriptor.java b/bval-jsr/src/main/java/org/apache/bval/jsr/AbstractConstraintDescriptor.java
new file mode 100644
index 0000000..4c303ae
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/AbstractConstraintDescriptor.java
@@ -0,0 +1,32 @@
+package org.apache.bval.jsr;
+
+import java.lang.annotation.Annotation;
+import java.util.Set;
+
+import javax.validation.Payload;
+import javax.validation.metadata.ConstraintDescriptor;
+import javax.validation.metadata.ValidateUnwrappedValue;
+import javax.validation.valueextraction.Unwrapping;
+
+abstract class AbstractConstraintDescriptor<T extends Annotation> implements ConstraintDescriptor<T> {
+
+    @Override
+    public ValidateUnwrappedValue getValueUnwrapping() {
+        final Set<Class<? extends Payload>> payload = getPayload();
+        if (payload != null) {
+            if (payload.contains(Unwrapping.Unwrap.class)) {
+                return ValidateUnwrappedValue.UNWRAP;
+            }
+            if (payload.contains(Unwrapping.Skip.class)) {
+                return ValidateUnwrappedValue.SKIP;
+            }
+        }
+        // TODO handle UnwrapByDefault extractors
+        return ValidateUnwrappedValue.DEFAULT;
+    }
+
+    @Override
+    public <U> U unwrap(Class<U> type) {
+        throw new UnsupportedOperationException();
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java
index 8f68b9e..b310503 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java
@@ -18,46 +18,56 @@
  */
 package org.apache.bval.jsr;
 
-import org.apache.bval.MetaBeanFinder;
-import org.apache.bval.util.reflection.Reflection;
-import org.apache.commons.weaver.privilizer.Privilizing;
-import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
-
+import javax.validation.ClockProvider;
 import javax.validation.ConstraintValidatorFactory;
 import javax.validation.MessageInterpolator;
 import javax.validation.ParameterNameProvider;
 import javax.validation.TraversableResolver;
 import javax.validation.Validator;
 import javax.validation.ValidatorContext;
+import javax.validation.valueextraction.ValueExtractor;
+
+import org.apache.bval.MetaBeanFinder;
+import org.apache.bval.jsr.descriptor.DescriptorManager;
+import org.apache.bval.jsr.groups.GroupsComputer;
+import org.apache.bval.jsr.valueextraction.ValueExtractors;
+import org.apache.bval.util.Lazy;
+import org.apache.bval.util.reflection.Reflection;
+import org.apache.commons.weaver.privilizer.Privilizing;
+import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
 
 /**
- * Description: Represents the context that is used to create
- * {@link ClassValidator} instances.
+ * Description: Represents the context that is used to create {@link ClassValidator} instances.
  */
 @Privilizing(@CallTo(Reflection.class))
 public class ApacheFactoryContext implements ValidatorContext {
+    private final Lazy<GroupsComputer> groupsComputer = new Lazy<>(GroupsComputer::new);
     private final ApacheValidatorFactory factory;
+    private final ValueExtractors valueExtractors;
     private volatile MetaBeanFinder metaBeanFinder;
 
     private MessageInterpolator messageInterpolator;
     private TraversableResolver traversableResolver;
     private ParameterNameProvider parameterNameProvider;
     private ConstraintValidatorFactory constraintValidatorFactory;
+    private ClockProvider clockProvider;
 
     /**
      * Create a new ApacheFactoryContext instance.
      * 
-     * @param factory validator factory
-     * @param metaBeanFinder meta finder
+     * @param factory
+     *            validator factory
+     * @param metaBeanFinder
+     *            meta finder
      */
     public ApacheFactoryContext(ApacheValidatorFactory factory, MetaBeanFinder metaBeanFinder) {
         this.factory = factory;
         this.metaBeanFinder = metaBeanFinder;
+        valueExtractors = factory.getValueExtractors().createChild();
     }
 
     /**
-     * Get the {@link ApacheValidatorFactory} used by this
-     * {@link ApacheFactoryContext}.
+     * Get the {@link ApacheValidatorFactory} used by this {@link ApacheFactoryContext}.
      * 
      * @return {@link ApacheValidatorFactory}
      */
@@ -75,13 +85,13 @@ public class ApacheFactoryContext implements ValidatorContext {
     }
 
     /**
-     * Discard cached metadata. Calling this method unnecessarily has the effect of severly
-     * limiting performance, therefore only do so when changes have been made that affect
-     * validation metadata, i.e. particularly NOT in response to:
+     * Discard cached metadata. Calling this method unnecessarily has the effect of severly limiting performance,
+     * therefore only do so when changes have been made that affect validation metadata, i.e. particularly NOT in
+     * response to:
      * <ul>
-     *   <li>{@link #messageInterpolator(MessageInterpolator)}</li>
-     *   <li>{@link #traversableResolver(TraversableResolver)}</li>
-     *   <li>{@link #constraintValidatorFactory(ConstraintValidatorFactory)</li>
+     * <li>{@link #messageInterpolator(MessageInterpolator)}</li>
+     * <li>{@link #traversableResolver(TraversableResolver)}</li>
+     * <li>{@link #constraintValidatorFactory(ConstraintValidatorFactory)</li>
      * </ul>
      */
     private synchronized void resetMeta() {
@@ -92,7 +102,7 @@ public class ApacheFactoryContext implements ValidatorContext {
      * {@inheritDoc}
      */
     @Override
-    public ValidatorContext messageInterpolator(MessageInterpolator messageInterpolator) {
+    public ApacheFactoryContext messageInterpolator(MessageInterpolator messageInterpolator) {
         this.messageInterpolator = messageInterpolator;
         return this;
     }
@@ -101,7 +111,7 @@ public class ApacheFactoryContext implements ValidatorContext {
      * {@inheritDoc}
      */
     @Override
-    public ValidatorContext traversableResolver(TraversableResolver traversableResolver) {
+    public ApacheFactoryContext traversableResolver(TraversableResolver traversableResolver) {
         this.traversableResolver = traversableResolver;
         return this;
     }
@@ -110,18 +120,30 @@ public class ApacheFactoryContext implements ValidatorContext {
      * {@inheritDoc}
      */
     @Override
-    public ValidatorContext constraintValidatorFactory(ConstraintValidatorFactory constraintValidatorFactory) {
+    public ApacheFactoryContext constraintValidatorFactory(ConstraintValidatorFactory constraintValidatorFactory) {
         this.constraintValidatorFactory = constraintValidatorFactory;
         return this;
     }
 
     @Override
-    public ValidatorContext parameterNameProvider(ParameterNameProvider parameterNameProvider) {
+    public ApacheFactoryContext parameterNameProvider(ParameterNameProvider parameterNameProvider) {
         this.parameterNameProvider = parameterNameProvider;
         resetMeta(); // needed since parameter names are a component of validation metadata
         return this;
     }
 
+    @Override
+    public ApacheFactoryContext clockProvider(ClockProvider clockProvider) {
+        this.clockProvider = clockProvider;
+        return this;
+    }
+
+    @Override
+    public ApacheFactoryContext addValueExtractor(ValueExtractor<?> extractor) {
+        valueExtractors.addValueExtractor(extractor);
+        return this;
+    }
+
     /**
      * Get the {@link ConstraintValidatorFactory}.
      * 
@@ -137,7 +159,7 @@ public class ApacheFactoryContext implements ValidatorContext {
      */
     @Override
     public Validator getValidator() {
-        return new ClassValidator(this);
+        return new ValidatorImpl(this);
     }
 
     /**
@@ -162,6 +184,23 @@ public class ApacheFactoryContext implements ValidatorContext {
         return parameterNameProvider == null ? factory.getParameterNameProvider() : parameterNameProvider;
     }
 
+    public ClockProvider getClockProvider() {
+        return clockProvider == null ? factory.getClockProvider() : clockProvider;
+    }
+
+    public ValueExtractors getValueExtractors() {
+        return valueExtractors;
+    }
+
+    public DescriptorManager getDescriptorManager() {
+        // TODO handle context customizations
+        return factory.getDescriptorManager();
+    }
+
+    public GroupsComputer getGroupsComputer() {
+        return groupsComputer.get();
+    }
+
     boolean isTreatMapsLikeBeans() {
         return Boolean
             .parseBoolean(factory.getProperties().get(ApacheValidatorConfiguration.Properties.TREAT_MAPS_LIKE_BEANS));

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java
index fb64d4e..81187f3 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java
@@ -32,7 +32,7 @@ public interface ApacheValidatorConfiguration extends Configuration<ApacheValida
     /**
      * Proprietary property keys for {@link ConfigurationImpl}  
      */
-    public interface Properties {
+    interface Properties {
         /**
          * the location where to look for the validation.xml file.
          * default: "META-INF/validation.xml"
@@ -91,5 +91,10 @@ public interface ApacheValidatorConfiguration extends Configuration<ApacheValida
          * </ol>
          */
         String METABEAN_FACTORY_CLASSNAMES = "apache.bval.metabean-factory-classnames";
+
+        /**
+         * Size to use for caching of constraint-related information. Default is {@code 50}.
+         */
+        String CONSTRAINTS_CACHE_SIZE = "apache.bval.constraints-cache-size";
     }
 }

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java
index 5e6a611..eb760a1 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java
@@ -18,11 +18,39 @@
  */
 package org.apache.bval.jsr;
 
+import java.io.Closeable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.validation.ClockProvider;
+import javax.validation.ConstraintValidatorFactory;
+import javax.validation.MessageInterpolator;
+import javax.validation.ParameterNameProvider;
+import javax.validation.TraversableResolver;
+import javax.validation.Validation;
+import javax.validation.ValidationException;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+import javax.validation.spi.ConfigurationState;
+
 import org.apache.bval.IntrospectorMetaBeanFactory;
 import org.apache.bval.MetaBeanBuilder;
 import org.apache.bval.MetaBeanFactory;
 import org.apache.bval.MetaBeanFinder;
 import org.apache.bval.MetaBeanManager;
+import org.apache.bval.jsr.descriptor.DescriptorManager;
+import org.apache.bval.jsr.metadata.MetadataBuilders;
+import org.apache.bval.jsr.util.AnnotationsManager;
+import org.apache.bval.jsr.valueextraction.ValueExtractors;
 import org.apache.bval.jsr.xml.AnnotationIgnores;
 import org.apache.bval.jsr.xml.MetaConstraint;
 import org.apache.bval.jsr.xml.ValidationMappingParser;
@@ -37,28 +65,6 @@ import org.apache.commons.weaver.privilizer.Privileged;
 import org.apache.commons.weaver.privilizer.Privilizing;
 import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
 
-import javax.validation.ConstraintValidatorFactory;
-import javax.validation.MessageInterpolator;
-import javax.validation.ParameterNameProvider;
-import javax.validation.TraversableResolver;
-import javax.validation.Validation;
-import javax.validation.ValidationException;
-import javax.validation.Validator;
-import javax.validation.ValidatorFactory;
-import javax.validation.spi.ConfigurationState;
-import java.io.Closeable;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
 /**
  * Description: a factory is a complete configurated object that can create
  * validators.<br/>
@@ -74,7 +80,12 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
     private TraversableResolver traversableResolver;
     private ConstraintValidatorFactory constraintValidatorFactory;
     private ParameterNameProvider parameterNameProvider;
+    private ClockProvider clockProvider;
     private final Map<String, String> properties;
+    private final AnnotationsManager annotationsManager;
+    private final DescriptorManager descriptorManager = new DescriptorManager(this);
+    private final MetadataBuilders metadataBuilders = new MetadataBuilders();
+    private final ValueExtractors valueExtractors = new ValueExtractors();
 
     /**
      * information from xml parsing
@@ -89,7 +100,7 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
     private final ConcurrentMap<Class<?>, List<AccessStrategy>> validAccesses;
     private final ConcurrentMap<Class<?>, List<MetaConstraint<?, ? extends Annotation>>> constraintMap;
 
-    private final Collection<Closeable> toClose = new ArrayList<Closeable>();
+    private final Collection<Closeable> toClose = new ArrayList<>();
     private final MetaBeanFinder defaultMetaBeanFinder;
 
     /**
@@ -112,7 +123,7 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
      * @return a new instance of MetaBeanManager with adequate MetaBeanFactories
      */
     protected MetaBeanFinder buildMetaBeanFinder() {
-        final List<MetaBeanFactory> builders = new ArrayList<MetaBeanFactory>();
+        final List<MetaBeanFactory> builders = new ArrayList<>();
         if (Boolean.parseBoolean(getProperties().get(ApacheValidatorConfiguration.Properties.ENABLE_INTROSPECTOR))) {
             builders.add(new IntrospectorMetaBeanFactory());
         }
@@ -121,9 +132,8 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
         if (factoryClassNames != null) {
             for (String clsName : factoryClassNames) {
                 // cast, relying on #createMetaBeanFactory to throw the exception if incompatible:
-                @SuppressWarnings("unchecked")
                 final Class<? extends MetaBeanFactory> factoryClass =
-                    (Class<? extends MetaBeanFactory>) loadClass(clsName);
+                    loadClass(clsName).asSubclass(MetaBeanFactory.class);
                 builders.add(createMetaBeanFactory(factoryClass));
             }
         }
@@ -173,24 +183,27 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
      * Create a new ApacheValidatorFactory instance.
      */
     public ApacheValidatorFactory(ConfigurationState configuration) {
-        properties = new HashMap<String, String>(configuration.getProperties());
-        defaultSequences = new HashMap<Class<?>, Class<?>[]>();
-        validAccesses = new ConcurrentHashMap<Class<?>, List<AccessStrategy>>();
-        constraintMap = new ConcurrentHashMap<Class<?>, List<MetaConstraint<?, ? extends Annotation>>>();
+        properties = new HashMap<>(configuration.getProperties());
+        defaultSequences = new HashMap<>();
+        validAccesses = new ConcurrentHashMap<>();
+        constraintMap = new ConcurrentHashMap<>();
 
         parameterNameProvider = configuration.getParameterNameProvider();
         messageResolver = configuration.getMessageInterpolator();
         traversableResolver = configuration.getTraversableResolver();
         constraintValidatorFactory = configuration.getConstraintValidatorFactory();
+        clockProvider = configuration.getClockProvider();
 
         if (ConfigurationImpl.class.isInstance(configuration)) {
-            final ConfigurationImpl impl = ConfigurationImpl.class.cast(configuration);
-            toClose.add(impl.getClosable());
+            toClose.add(ConfigurationImpl.class.cast(configuration).getClosable());
         }
 
         new ValidationMappingParser(this).processMappingConfig(configuration.getMappingStreams());
 
         defaultMetaBeanFinder = buildMetaBeanFinder();
+
+        configuration.getValueExtractors().forEach(valueExtractors::addValueExtractor);
+        annotationsManager = new AnnotationsManager(this);
     }
 
     /**
@@ -203,8 +216,7 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
     }
 
     /**
-     * Shortcut method to create a new Validator instance with factory's
-     * settings
+     * Shortcut method to create a new Validator instance with factory's settings
      *
      * @return the new validator instance
      */
@@ -271,6 +283,12 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
         }
     }
 
+    public void setClockProvider(final ClockProvider clockProvider) {
+        if (clockProvider != null) {
+            this.clockProvider = clockProvider;
+        }
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -307,6 +325,11 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
     }
 
     @Override
+    public ClockProvider getClockProvider() {
+        return clockProvider;
+    }
+
+    @Override
     public void close() {
         try {
             for (final Closeable c : toClose) {
@@ -319,13 +342,14 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
     }
 
     /**
-     * Return an object of the specified type to allow access to the
-     * provider-specific API. If the Bean Validation provider implementation
-     * does not support the specified class, the ValidationException is thrown.
+     * Return an object of the specified type to allow access to the provider-specific API. If the Bean Validation
+     * provider implementation does not support the specified class, the ValidationException is thrown.
      *
-     * @param type the class of the object to be returned.
+     * @param type
+     *            the class of the object to be returned.
      * @return an instance of the specified class
-     * @throws ValidationException if the provider does not support the call.
+     * @throws ValidationException
+     *             if the provider does not support the call.
      */
     @Override
     public <T> T unwrap(final Class<T> type) {
@@ -392,8 +416,34 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
     }
 
     /**
-     * Add a meta-constraint to this {@link ApacheValidatorFactory}'s runtime
-     * customizations.
+     * Get the {@link AnnotationsManager}.
+     * 
+     * @return {@link AnnotationsManager}
+     */
+    public AnnotationsManager getAnnotationsManager() {
+        return annotationsManager;
+    }
+
+    /**
+     * Get the {@link DescriptorManager}.
+     * 
+     * @return {@link DescriptorManager}
+     */
+    public DescriptorManager getDescriptorManager() {
+        return descriptorManager;
+    }
+
+    /**
+     * Get the {@link ValueExtractors}.
+     * 
+     * @return {@link ValueExtractors}
+     */
+    public ValueExtractors getValueExtractors() {
+        return valueExtractors;
+    }
+
+    /**
+     * Add a meta-constraint to this {@link ApacheValidatorFactory}'s runtime customizations.
      *
      * @param beanClass
      * @param metaConstraint
@@ -401,7 +451,7 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
     public void addMetaConstraint(final Class<?> beanClass, final MetaConstraint<?, ?> metaConstraint) {
         List<MetaConstraint<?, ? extends Annotation>> slot = constraintMap.get(beanClass);
         if (slot == null) {
-            slot = new ArrayList<MetaConstraint<?, ? extends Annotation>>();
+            slot = new ArrayList<>();
             final List<MetaConstraint<?, ? extends Annotation>> old = constraintMap.putIfAbsent(beanClass, slot);
             if (old != null) {
                 slot = old;
@@ -420,7 +470,7 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
     public void addValid(Class<?> beanClass, AccessStrategy accessStrategy) {
         List<AccessStrategy> slot = validAccesses.get(beanClass);
         if (slot == null) {
-            slot = new ArrayList<AccessStrategy>();
+            slot = new ArrayList<>();
             final List<AccessStrategy> old = validAccesses.putIfAbsent(beanClass, slot);
             if (old != null) {
                 slot = old;
@@ -444,8 +494,7 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
      *
      * @param <T>
      * @param beanClass
-     * @return List of {@link MetaConstraint}s applicable to
-     *         <code>beanClass</code>
+     * @return List of {@link MetaConstraint}s applicable to <code>beanClass</code>
      */
     public <T> List<MetaConstraint<T, ? extends Annotation>> getMetaConstraints(Class<T> beanClass) {
         final List<MetaConstraint<?, ? extends Annotation>> slot = constraintMap.get(beanClass);
@@ -459,16 +508,15 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
     }
 
     /**
-     * Get the {@link AccessStrategy} {@link List} indicating nested bean
-     * validations that must be triggered in the course of validating a
-     * <code>beanClass</code> graph.
+     * Get the {@link AccessStrategy} {@link List} indicating nested bean validations that must be triggered in the
+     * course of validating a <code>beanClass</code> graph.
      *
      * @param beanClass
      * @return {@link List} of {@link AccessStrategy}
      */
     public List<AccessStrategy> getValidAccesses(Class<?> beanClass) {
         final List<AccessStrategy> slot = validAccesses.get(beanClass);
-        return slot == null ? Collections.<AccessStrategy> emptyList() : Collections.unmodifiableList(slot);
+        return slot == null ? Collections.emptyList() : Collections.unmodifiableList(slot);
     }
 
     /**
@@ -481,6 +529,10 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
         return safeArray(defaultSequences.get(beanClass));
     }
 
+    public MetadataBuilders getMetadataBuilders() {
+        return metadataBuilders;
+    }
+
     private static Class<?>[] safeArray(Class<?>... array) {
         return array == null || array.length == 0 ? ObjectUtils.EMPTY_CLASS_ARRAY : array.clone();
     }
@@ -519,9 +571,8 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
     }
 
     /**
-     * separate class to prevent the classloader to immediately load optional
-     * classes: XMLMetaBeanManager, XMLMetaBeanFactory, XMLMetaBeanBuilder that
-     * might not be available in the classpath
+     * separate class to prevent the classloader to immediately load optional classes: XMLMetaBeanManager,
+     * XMLMetaBeanFactory, XMLMetaBeanBuilder that might not be available in the classpath
      */
     private static class XMLMetaBeanManagerCreator {
 
@@ -530,10 +581,10 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
         }
 
         /**
-         * Create the {@link MetaBeanManager} to process JSR303 XML. Requires
-         * bval-xstream at RT.
+         * Create the {@link MetaBeanManager} to process JSR303 XML. Requires bval-xstream at RT.
          *
-         * @param builders meta bean builders
+         * @param builders
+         *            meta bean builders
          * @return {@link MetaBeanManager}
          */
         // NOTE - We return MetaBeanManager instead of XMLMetaBeanManager to

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/jsr/BootstrapConfigurationImpl.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/BootstrapConfigurationImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/BootstrapConfigurationImpl.java
index 3a3abf1..d85ab51 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/BootstrapConfigurationImpl.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/BootstrapConfigurationImpl.java
@@ -34,12 +34,15 @@ public class BootstrapConfigurationImpl implements BootstrapConfiguration {
     private String messageInterpolatorClassName;
     private String constraintValidatorFactoryClassName;
     private String defaultProviderClassName;
+    private String clockProviderClassName;
+    private Set<String> valueExtractorClassNames;
 
     public BootstrapConfigurationImpl(final String defaultProviderClassName,
         final String constraintValidatorFactoryClassName, final String messageInterpolatorClassName,
         final String traversableResolverClassName, final String parameterNameProviderClassName,
         final Set<String> constraintMappingResourcePaths, final boolean executableValidationEnabled,
-        final Set<ExecutableType> defaultValidatedExecutableTypes, final Map<String, String> properties) {
+        final Set<ExecutableType> defaultValidatedExecutableTypes, final Map<String, String> properties,
+        final String clockProviderClassName, final Set<String> valueExtractorClassNames) {
         this.properties = Collections.unmodifiableMap(properties);
         this.defaultValidatedExecutableTypes = Collections.unmodifiableSet(defaultValidatedExecutableTypes);
         this.executableValidationEnabled = executableValidationEnabled;
@@ -49,6 +52,8 @@ public class BootstrapConfigurationImpl implements BootstrapConfiguration {
         this.messageInterpolatorClassName = messageInterpolatorClassName;
         this.constraintValidatorFactoryClassName = constraintValidatorFactoryClassName;
         this.defaultProviderClassName = defaultProviderClassName;
+        this.clockProviderClassName = clockProviderClassName;
+        this.valueExtractorClassNames = valueExtractorClassNames;
     }
 
     @Override
@@ -78,7 +83,7 @@ public class BootstrapConfigurationImpl implements BootstrapConfiguration {
 
     @Override
     public Set<String> getConstraintMappingResourcePaths() {
-        return constraintMappingResourcePaths;
+        return Collections.unmodifiableSet(constraintMappingResourcePaths);
     }
 
     @Override
@@ -88,11 +93,27 @@ public class BootstrapConfigurationImpl implements BootstrapConfiguration {
 
     @Override
     public Set<ExecutableType> getDefaultValidatedExecutableTypes() {
-        return defaultValidatedExecutableTypes;
+        return Collections.unmodifiableSet(defaultValidatedExecutableTypes);
     }
 
     @Override
     public Map<String, String> getProperties() {
-        return properties;
+        return Collections.unmodifiableMap(properties);
+    }
+
+    /**
+     * @since 2.0
+     */
+    @Override
+    public String getClockProviderClassName() {
+        return clockProviderClassName;
+    }
+
+    /**
+     * @since 2.0
+     */
+    @Override
+    public Set<String> getValueExtractorClassNames() {
+        return Collections.unmodifiableSet(valueExtractorClassNames);
     }
 }

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java
index 7c4780f..046d6d2 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java
@@ -19,9 +19,10 @@
 package org.apache.bval.jsr;
 
 import java.io.Closeable;
-import java.io.IOException;
 import java.io.InputStream;
+import java.time.Clock;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -29,6 +30,7 @@ import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import javax.validation.BootstrapConfiguration;
+import javax.validation.ClockProvider;
 import javax.validation.ConstraintValidatorFactory;
 import javax.validation.MessageInterpolator;
 import javax.validation.ParameterNameProvider;
@@ -40,6 +42,7 @@ import javax.validation.executable.ExecutableType;
 import javax.validation.spi.BootstrapState;
 import javax.validation.spi.ConfigurationState;
 import javax.validation.spi.ValidationProvider;
+import javax.validation.valueextraction.ValueExtractor;
 
 import org.apache.bval.cdi.BValExtension;
 import org.apache.bval.jsr.parameter.DefaultParameterNameProvider;
@@ -76,29 +79,33 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
      */
     protected MessageInterpolator defaultMessageInterpolator = new DefaultMessageInterpolator();
     protected volatile MessageInterpolator messageInterpolator = defaultMessageInterpolator;
-    protected Class<? extends MessageInterpolator> messageInterpolatorClass = null;
+    protected Class<? extends MessageInterpolator> messageInterpolatorClass;
 
     /**
      * Configured {@link ConstraintValidatorFactory}
      */
     protected ConstraintValidatorFactory defaultConstraintValidatorFactory = new DefaultConstraintValidatorFactory();
     protected volatile ConstraintValidatorFactory constraintValidatorFactory = defaultConstraintValidatorFactory;
-    protected Class<? extends ConstraintValidatorFactory> constraintValidatorFactoryClass = null;
+    protected Class<? extends ConstraintValidatorFactory> constraintValidatorFactoryClass;
 
     protected TraversableResolver defaultTraversableResolver = new DefaultTraversableResolver();
     protected volatile TraversableResolver traversableResolver = defaultTraversableResolver;
-    protected Class<? extends TraversableResolver> traversableResolverClass = null;
+    protected Class<? extends TraversableResolver> traversableResolverClass;
 
     protected ParameterNameProvider defaultParameterNameProvider = new DefaultParameterNameProvider();
     protected volatile ParameterNameProvider parameterNameProvider = defaultParameterNameProvider;
-    protected Class<? extends ParameterNameProvider> parameterNameProviderClass = null;
+    protected Class<? extends ParameterNameProvider> parameterNameProviderClass;
 
     protected BootstrapConfiguration bootstrapConfiguration;
 
     protected Collection<ExecutableType> executableValidation;
 
-    private Collection<BValExtension.Releasable<?>> releasables =
-        new CopyOnWriteArrayList<BValExtension.Releasable<?>>();
+    private Collection<BValExtension.Releasable<?>> releasables = new CopyOnWriteArrayList<>();
+    protected ClockProvider defaultClockProvider = Clock::systemDefaultZone;
+    protected volatile ClockProvider clockProvider = defaultClockProvider;
+    protected Class<? extends ClockProvider> clockProviderClass;
+
+    protected Set<ValueExtractor<?>> valueExtractors = new HashSet<>();
 
     private boolean beforeCdi = false;
 
@@ -109,8 +116,8 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
     private boolean prepared = false;
     // END DEFAULTS
 
-    private Set<InputStream> mappingStreams = new HashSet<InputStream>();
-    private Map<String, String> properties = new HashMap<String, String>();
+    private Set<InputStream> mappingStreams = new HashSet<>();
+    private Map<String, String> properties = new HashMap<>();
     private boolean ignoreXmlConfiguration = false;
 
     private volatile ValidationParser parser;
@@ -134,6 +141,7 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
         } else {
             throw new ValidationException("either provider or state are required");
         }
+        initializePropertyDefaults();
     }
 
     /**
@@ -141,13 +149,11 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
      */
     @Override
     public ApacheValidatorConfiguration traversableResolver(TraversableResolver resolver) {
-        if (resolver == null) {
-            return this;
+        if (resolver != null) {
+            this.traversableResolverClass = null;
+            this.traversableResolver = resolver;
+            this.prepared = false;
         }
-
-        this.traversableResolverClass = null;
-        this.traversableResolver = resolver;
-        this.prepared = false;
         return this;
     }
 
@@ -169,13 +175,11 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
      */
     @Override
     public ConfigurationImpl messageInterpolator(MessageInterpolator resolver) {
-        if (resolver == null) {
-            return this;
+        if (resolver != null) {
+            this.messageInterpolatorClass = null;
+            this.messageInterpolator = resolver;
+            this.prepared = false;
         }
-
-        this.messageInterpolatorClass = null;
-        this.messageInterpolator = resolver;
-        this.prepared = false;
         return this;
     }
 
@@ -184,23 +188,20 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
      */
     @Override
     public ConfigurationImpl constraintValidatorFactory(ConstraintValidatorFactory constraintFactory) {
-        if (constraintFactory == null) {
-            return this;
+        if (constraintFactory != null) {
+            this.constraintValidatorFactoryClass = null;
+            this.constraintValidatorFactory = constraintFactory;
+            this.prepared = false;
         }
-
-        this.constraintValidatorFactoryClass = null;
-        this.constraintValidatorFactory = constraintFactory;
-        this.prepared = false;
         return this;
     }
 
     @Override
     public ApacheValidatorConfiguration parameterNameProvider(ParameterNameProvider parameterNameProvider) {
-        if (parameterNameProvider == null) {
-            return this;
+        if (parameterNameProvider != null) {
+            this.parameterNameProviderClass = null;
+            this.parameterNameProvider = parameterNameProvider;
         }
-        this.parameterNameProviderClass = null;
-        this.parameterNameProvider = parameterNameProvider;
         return this;
     }
 
@@ -213,10 +214,9 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
      */
     @Override
     public ApacheValidatorConfiguration addMapping(InputStream stream) {
-        if (stream == null) {
-            return this;
+        if (stream != null) {
+            mappingStreams.add(IOs.convertToMarkableInputStream(stream));
         }
-        mappingStreams.add(IOs.convertToMarkableInputStream(stream));
         return this;
     }
 
@@ -297,7 +297,6 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
         if (beforeCdi) {
             return defaultMessageInterpolator;
         }
-
         if (messageInterpolator == defaultMessageInterpolator && messageInterpolatorClass != null) {
             synchronized (this) {
                 if (messageInterpolator == defaultMessageInterpolator && messageInterpolatorClass != null) {
@@ -336,7 +335,6 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
         if (prepared) {
             return this;
         }
-
         createBootstrapConfiguration();
         parser.applyConfigWithInstantiation(this); // instantiate the config if needed
 
@@ -367,7 +365,6 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
         if (beforeCdi) {
             return constraintValidatorFactory;
         }
-
         if (constraintValidatorFactory == defaultConstraintValidatorFactory
             && constraintValidatorFactoryClass != null) {
             synchronized (this) {
@@ -388,7 +385,6 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
         if (beforeCdi) {
             return defaultTraversableResolver;
         }
-
         if (traversableResolver == defaultTraversableResolver && traversableResolverClass != null) {
             synchronized (this) {
                 if (traversableResolver == defaultTraversableResolver && traversableResolverClass != null) {
@@ -404,7 +400,6 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
         if (beforeCdi) {
             return defaultParameterNameProvider;
         }
-
         if (parameterNameProvider == defaultParameterNameProvider && parameterNameProviderClass != null) {
             synchronized (this) {
                 if (parameterNameProvider == defaultParameterNameProvider && parameterNameProviderClass != null) {
@@ -452,14 +447,11 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
     }
 
     public Closeable getClosable() {
-        return new Closeable() {
-            @Override
-            public void close() throws IOException {
-                for (final BValExtension.Releasable<?> releasable : releasables) {
-                    releasable.release();
-                }
-                releasables.clear();
+        return () -> {
+            for (final BValExtension.Releasable<?> releasable : releasables) {
+                releasable.release();
             }
+            releasables.clear();
         };
     }
 
@@ -469,8 +461,7 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
             final BValExtension.Releasable<T> releasable = BValExtension.inject(cls);
             releasables.add(releasable);
             return releasable.getInstance();
-        } catch (final Exception e) {
-        } catch (final NoClassDefFoundError error) {
+        } catch (Exception | NoClassDefFoundError e) {
         }
         try {
             return cls.newInstance();
@@ -494,4 +485,45 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
     public void parameterNameProviderClass(final Class<? extends ParameterNameProvider> clazz) {
         parameterNameProviderClass = clazz;
     }
+
+    @Override
+    public ApacheValidatorConfiguration clockProvider(ClockProvider clockProvider) {
+        this.clockProvider = clockProvider;
+        return this;
+    }
+
+    @Override
+    public ApacheValidatorConfiguration addValueExtractor(ValueExtractor<?> extractor) {
+        valueExtractors.add(extractor);
+        return this;
+    }
+
+    @Override
+    public ClockProvider getDefaultClockProvider() {
+        return defaultClockProvider;
+    }
+
+    @Override
+    public Set<ValueExtractor<?>> getValueExtractors() {
+        return Collections.unmodifiableSet(valueExtractors);
+    }
+
+    @Override
+    public ClockProvider getClockProvider() {
+        if (beforeCdi) {
+            return defaultClockProvider;
+        }
+        if (clockProvider == defaultClockProvider && clockProviderClass != null) {
+            synchronized (this) {
+                if (clockProvider == defaultClockProvider && clockProviderClass != null) {
+                    clockProvider = newInstance(clockProviderClass);
+                }
+            }
+        }
+        return clockProvider;
+    }
+
+    protected void initializePropertyDefaults() {
+        properties.put(Properties.CONSTRAINTS_CACHE_SIZE, Integer.toString(50));
+    }
 }

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintAnnotationAttributes.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintAnnotationAttributes.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintAnnotationAttributes.java
index 24b38ea..6b9842c 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintAnnotationAttributes.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintAnnotationAttributes.java
@@ -134,20 +134,16 @@ public enum ConstraintAnnotationAttributes {
     public <C extends Annotation> Worker<C> analyze(final Class<C> clazz) {
         if (clazz.getName().startsWith("javax.validation.constraint.")) { // cache only APIs classes to avoid memory leaks
             @SuppressWarnings("unchecked")
-            Worker<C> w = Worker.class.cast(WORKER_CACHE.get(clazz));
-            if (w == null) {
-                w = new Worker<C>(clazz);
-                WORKER_CACHE.putIfAbsent(clazz, w);
-                return w;
-            }
+            final Worker<C> w = (Worker<C>) WORKER_CACHE.computeIfAbsent(clazz, Worker::new);
+            return w;
         }
         return new Worker<C>(clazz);
     }
 
     // this is static but related to Worker
-    private static final ConcurrentMap<Class<?>, Worker<?>> WORKER_CACHE = new ConcurrentHashMap<Class<?>, Worker<?>>();
+    private static final ConcurrentMap<Class<?>, Worker<?>> WORKER_CACHE = new ConcurrentHashMap<>();
     private static final ConcurrentMap<Class<?>, ConcurrentMap<String, Method>> METHOD_BY_NAME_AND_CLASS =
-        new ConcurrentHashMap<Class<?>, ConcurrentMap<String, Method>>();
+        new ConcurrentHashMap<>();
     private static final Method NULL_METHOD;
     static {
         try {
@@ -171,14 +167,8 @@ public enum ConstraintAnnotationAttributes {
         }
 
         private Method findMethod(final Class<C> constraintType, final String attributeName) {
-            ConcurrentMap<String, Method> cache = METHOD_BY_NAME_AND_CLASS.get(constraintType);
-            if (cache == null) {
-                cache = new ConcurrentHashMap<String, Method>();
-                final ConcurrentMap<String, Method> old = METHOD_BY_NAME_AND_CLASS.putIfAbsent(constraintType, cache);
-                if (old != null) {
-                    cache = old;
-                }
-            }
+            ConcurrentMap<String, Method> cache =
+                METHOD_BY_NAME_AND_CLASS.computeIfAbsent(constraintType, t -> new ConcurrentHashMap<>());
 
             final Method found = cache.get(attributeName);
             if (found != null) {
@@ -189,15 +179,19 @@ public enum ConstraintAnnotationAttributes {
                 cache.putIfAbsent(attributeName, NULL_METHOD);
                 return null;
             }
-            final Method oldMtd = cache.putIfAbsent(attributeName, m);
-            if (oldMtd != null) {
-                return oldMtd;
-            }
-            return m;
+            return cache.computeIfAbsent(attributeName, s -> m);
         }
 
         public boolean isValid() {
-            return method != null && method != NULL_METHOD;
+            return method != null && method != NULL_METHOD && TypeUtils.isAssignable(method.getReturnType(), type);
+        }
+
+        /**
+         * @since 2.0
+         * @return {@link Type}
+         */
+        public Type getSpecificType() {
+            return isValid() ? method.getGenericReturnType() : type;
         }
 
         public <T> T read(final Annotation constraint) {

http://git-wip-us.apache.org/repos/asf/bval/blob/a43c0b0c/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
index 1bb012f..5ec3ab7 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
@@ -18,18 +18,76 @@
  */
 package org.apache.bval.jsr;
 
-import javax.validation.ConstraintValidator;
 import java.lang.annotation.Annotation;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.constraintvalidation.SupportedValidationTarget;
+import javax.validation.constraintvalidation.ValidationTarget;
+
+import org.apache.bval.jsr.util.ToUnmodifiable;
+import org.apache.bval.util.ObjectUtils;
+import org.apache.bval.util.Validate;
 
 /**
  * Description: hold the relationship annotation->validatedBy[] ConstraintValidator classes that are already parsed in a
  * cache.<br/>
  */
 public class ConstraintCached {
-    private final Map<Class<? extends Annotation>, Class<? extends ConstraintValidator<?, ?>>[]> classes =
-        new HashMap<Class<? extends Annotation>, Class<? extends ConstraintValidator<?, ?>>[]>();
+
+    /**
+     * Describes a {@link ConstraintValidator} implementation type.
+     * 
+     * @since 2.0
+     */
+    public static final class ConstraintValidatorInfo<T extends Annotation> {
+        private static final Set<ValidationTarget> DEFAULT_VALIDATION_TARGETS =
+            Collections.singleton(ValidationTarget.ANNOTATED_ELEMENT);
+
+        private final Class<? extends ConstraintValidator<T, ?>> type;
+        private Set<ValidationTarget> supportedTargets;
+
+        ConstraintValidatorInfo(Class<? extends ConstraintValidator<T, ?>> type) {
+            super();
+            this.type = Validate.notNull(type);
+            final SupportedValidationTarget svt = type.getAnnotation(SupportedValidationTarget.class);
+
+            supportedTargets = svt == null ? DEFAULT_VALIDATION_TARGETS
+                : Collections.unmodifiableSet(EnumSet.copyOf(Arrays.asList(svt.value())));
+        }
+
+        public Class<? extends ConstraintValidator<T, ?>> getType() {
+            return type;
+        }
+
+        public Set<ValidationTarget> getSupportedTargets() {
+            return supportedTargets;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return obj == this
+                || obj instanceof ConstraintValidatorInfo<?> && ((ConstraintValidatorInfo<?>) obj).type.equals(type);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type);
+        }
+    }
+
+    private final Map<Class<? extends Annotation>, Set<ConstraintValidatorInfo<?>>> constraintValidatorInfo =
+        new HashMap<>();
 
     /**
      * Record the set of validator classes for a given constraint annotation.
@@ -39,7 +97,12 @@ public class ConstraintCached {
      */
     public <A extends Annotation> void putConstraintValidator(Class<A> annotationClass,
         Class<? extends ConstraintValidator<A, ?>>[] definitionClasses) {
-        classes.put(annotationClass, definitionClasses);
+        if (ObjectUtils.isEmpty(definitionClasses)) {
+            return;
+        }
+        Validate.notNull(annotationClass, "annotationClass");
+        Stream.of(definitionClasses).map(t -> new ConstraintValidatorInfo<>(t))
+            .forEach(constraintValidatorInfo.computeIfAbsent(annotationClass, k -> new HashSet<>())::add);
     }
 
     /**
@@ -50,20 +113,39 @@ public class ConstraintCached {
      * @return boolean
      */
     public boolean containsConstraintValidator(Class<? extends Annotation> annotationClass) {
-        return classes.containsKey(annotationClass);
+        return constraintValidatorInfo.containsKey(annotationClass);
     }
 
     /**
      * Get the cached validator classes for the requested constraint annotation.
      * 
-     * @param annotationClass
+     * @param constraintType
      *            to look up
      * @return array of {@link ConstraintValidator} implementation types
      */
     @SuppressWarnings("unchecked")
+    @Deprecated
     public <A extends Annotation> Class<? extends ConstraintValidator<A, ?>>[] getConstraintValidators(
-        Class<A> annotationClass) {
-        return (Class<? extends ConstraintValidator<A, ?>>[]) classes.get(annotationClass);
+        Class<A> constraintType) {
+        final Set<ConstraintValidatorInfo<A>> infos = infos(constraintType);
+        return infos == null ? new Class[0]
+            : infos.stream().map(ConstraintValidatorInfo::getType).toArray(Class[]::new);
     }
 
+    public <A extends Annotation> List<Class<? extends ConstraintValidator<A, ?>>> getConstraintValidatorClasses(
+        Class<A> constraintType) {
+        final Set<ConstraintValidatorInfo<A>> infos = infos(constraintType);
+        return infos == null ? Collections.emptyList()
+            : infos.stream().map(ConstraintValidatorInfo::getType).collect(ToUnmodifiable.list());
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    private <A extends Annotation> Set<ConstraintValidatorInfo<A>> infos(Class<A> constraintType) {
+        return (Set) constraintValidatorInfo.get(constraintType);
+    }
+
+    public <A extends Annotation> Optional<Set<ConstraintValidatorInfo<A>>> getConstraintValidatorInfo(
+        Class<A> constraintType) {
+        return Optional.ofNullable(infos(constraintType)).map(Collections::unmodifiableSet);
+    }
 }


Mime
View raw message