1 /*
2  * Hibernate Validator, declare and validate application constraints
3  *
4  * License: Apache License, Version 2.0
5  * See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
6  */

7 package org.hibernate.validator.internal.engine;
8
9 import java.time.Duration;
10
11 import javax.validation.ClockProvider;
12 import javax.validation.MessageInterpolator;
13 import javax.validation.ParameterNameProvider;
14 import javax.validation.TraversableResolver;
15
16 import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorInitializationContext;
17 import org.hibernate.validator.internal.engine.constraintvalidation.HibernateConstraintValidatorInitializationContextImpl;
18 import org.hibernate.validator.internal.util.Contracts;
19 import org.hibernate.validator.internal.util.ExecutableParameterNameProvider;
20 import org.hibernate.validator.spi.scripting.ScriptEvaluatorFactory;
21
22 public class ValidatorFactoryScopedContext {
23     /**
24      * The default message interpolator for this factory.
25      */

26     private final MessageInterpolator messageInterpolator;
27
28     /**
29      * The default traversable resolver for this factory.
30      */

31     private final TraversableResolver traversableResolver;
32
33     /**
34      * The default parameter name provider for this factory.
35      */

36     private final ExecutableParameterNameProvider parameterNameProvider;
37
38     /**
39      * Provider for the current time when validating {@code @Future} or {@code @Past}
40      */

41     private final ClockProvider clockProvider;
42
43     /**
44      * Defines the temporal validation tolerance i.e. the allowed margin of error when comparing date/time in temporal
45      * constraints.
46      */

47     private final Duration temporalValidationTolerance;
48
49     /**
50      * Used to get the {@code ScriptEvaluatorFactory} when validating {@code @ScriptAssert} and
51      * {@code @ParameterScriptAssert} constraints.
52      */

53     private final ScriptEvaluatorFactory scriptEvaluatorFactory;
54
55     /**
56      * Hibernate Validator specific flag to abort validation on first constraint violation.
57      */

58     private final boolean failFast;
59
60     /**
61      * Hibernate Validator specific flag to disable the {@code TraversableResolver} result cache.
62      */

63     private final boolean traversableResolverResultCacheEnabled;
64
65     /**
66      * The constraint validator payload.
67      */

68     private final Object constraintValidatorPayload;
69
70     /**
71      * The constraint validator initialization context.
72      */

73     private final HibernateConstraintValidatorInitializationContextImpl constraintValidatorInitializationContext;
74
75     ValidatorFactoryScopedContext(MessageInterpolator messageInterpolator,
76             TraversableResolver traversableResolver,
77             ExecutableParameterNameProvider parameterNameProvider,
78             ClockProvider clockProvider,
79             Duration temporalValidationTolerance,
80             ScriptEvaluatorFactory scriptEvaluatorFactory,
81             boolean failFast,
82             boolean traversableResolverResultCacheEnabled,
83             Object constraintValidatorPayload) {
84         this( messageInterpolator, traversableResolver, parameterNameProvider, clockProvider, temporalValidationTolerance, scriptEvaluatorFactory, failFast,
85                 traversableResolverResultCacheEnabled, constraintValidatorPayload,
86                 new HibernateConstraintValidatorInitializationContextImpl( scriptEvaluatorFactory, clockProvider,
87                         temporalValidationTolerance ) );
88     }
89
90     private ValidatorFactoryScopedContext(MessageInterpolator messageInterpolator,
91             TraversableResolver traversableResolver,
92             ExecutableParameterNameProvider parameterNameProvider,
93             ClockProvider clockProvider,
94             Duration temporalValidationTolerance,
95             ScriptEvaluatorFactory scriptEvaluatorFactory,
96             boolean failFast,
97             boolean traversableResolverResultCacheEnabled,
98             Object constraintValidatorPayload,
99             HibernateConstraintValidatorInitializationContextImpl constraintValidatorInitializationContext) {
100         this.messageInterpolator = messageInterpolator;
101         this.traversableResolver = traversableResolver;
102         this.parameterNameProvider = parameterNameProvider;
103         this.clockProvider = clockProvider;
104         this.temporalValidationTolerance = temporalValidationTolerance;
105         this.scriptEvaluatorFactory = scriptEvaluatorFactory;
106         this.failFast = failFast;
107         this.traversableResolverResultCacheEnabled = traversableResolverResultCacheEnabled;
108         this.constraintValidatorPayload = constraintValidatorPayload;
109         this.constraintValidatorInitializationContext = constraintValidatorInitializationContext;
110     }
111
112     public MessageInterpolator getMessageInterpolator() {
113         return this.messageInterpolator;
114     }
115
116     public TraversableResolver getTraversableResolver() {
117         return this.traversableResolver;
118     }
119
120     public ExecutableParameterNameProvider getParameterNameProvider() {
121         return this.parameterNameProvider;
122     }
123
124     public ClockProvider getClockProvider() {
125         return this.clockProvider;
126     }
127
128     public Duration getTemporalValidationTolerance() {
129         return this.temporalValidationTolerance;
130     }
131
132     public ScriptEvaluatorFactory getScriptEvaluatorFactory() {
133         return this.scriptEvaluatorFactory;
134     }
135
136     public boolean isFailFast() {
137         return this.failFast;
138     }
139
140     public boolean isTraversableResolverResultCacheEnabled() {
141         return this.traversableResolverResultCacheEnabled;
142     }
143
144     public Object getConstraintValidatorPayload() {
145         return this.constraintValidatorPayload;
146     }
147
148     public HibernateConstraintValidatorInitializationContext getConstraintValidatorInitializationContext() {
149         return this.constraintValidatorInitializationContext;
150     }
151
152     static class Builder {
153         private final ValidatorFactoryScopedContext defaultContext;
154
155         private MessageInterpolator messageInterpolator;
156         private TraversableResolver traversableResolver;
157         private ExecutableParameterNameProvider parameterNameProvider;
158         private ClockProvider clockProvider;
159         private ScriptEvaluatorFactory scriptEvaluatorFactory;
160         private Duration temporalValidationTolerance;
161         private boolean failFast;
162         private boolean traversableResolverResultCacheEnabled;
163         private Object constraintValidatorPayload;
164         private HibernateConstraintValidatorInitializationContextImpl constraintValidatorInitializationContext;
165
166         Builder(ValidatorFactoryScopedContext defaultContext) {
167             Contracts.assertNotNull( defaultContext, "Default context cannot be null." );
168
169             this.defaultContext = defaultContext;
170             this.messageInterpolator = defaultContext.messageInterpolator;
171             this.traversableResolver = defaultContext.traversableResolver;
172             this.parameterNameProvider = defaultContext.parameterNameProvider;
173             this.clockProvider = defaultContext.clockProvider;
174             this.scriptEvaluatorFactory = defaultContext.scriptEvaluatorFactory;
175             this.temporalValidationTolerance = defaultContext.temporalValidationTolerance;
176             this.failFast = defaultContext.failFast;
177             this.traversableResolverResultCacheEnabled = defaultContext.traversableResolverResultCacheEnabled;
178             this.constraintValidatorPayload = defaultContext.constraintValidatorPayload;
179             this.constraintValidatorInitializationContext = defaultContext.constraintValidatorInitializationContext;
180         }
181
182         public ValidatorFactoryScopedContext.Builder setMessageInterpolator(MessageInterpolator messageInterpolator) {
183             if ( messageInterpolator == null ) {
184                 this.messageInterpolator = defaultContext.messageInterpolator;
185             }
186             else {
187                 this.messageInterpolator = messageInterpolator;
188             }
189
190             return this;
191         }
192
193         public ValidatorFactoryScopedContext.Builder setTraversableResolver(TraversableResolver traversableResolver) {
194             if ( traversableResolver == null ) {
195                 this.traversableResolver = defaultContext.traversableResolver;
196             }
197             else {
198                 this.traversableResolver = traversableResolver;
199             }
200             return this;
201         }
202
203         public ValidatorFactoryScopedContext.Builder setParameterNameProvider(ParameterNameProvider parameterNameProvider) {
204             if ( parameterNameProvider == null ) {
205                 this.parameterNameProvider = defaultContext.parameterNameProvider;
206             }
207             else {
208                 this.parameterNameProvider = new ExecutableParameterNameProvider( parameterNameProvider );
209             }
210             return this;
211         }
212
213         public ValidatorFactoryScopedContext.Builder setClockProvider(ClockProvider clockProvider) {
214             if ( clockProvider == null ) {
215                 this.clockProvider = defaultContext.clockProvider;
216             }
217             else {
218                 this.clockProvider = clockProvider;
219             }
220             return this;
221         }
222
223         public ValidatorFactoryScopedContext.Builder setTemporalValidationTolerance(Duration temporalValidationTolerance) {
224             this.temporalValidationTolerance = temporalValidationTolerance == null ? Duration.ZERO : temporalValidationTolerance.abs();
225             return this;
226         }
227
228         public ValidatorFactoryScopedContext.Builder setScriptEvaluatorFactory(ScriptEvaluatorFactory scriptEvaluatorFactory) {
229             if ( scriptEvaluatorFactory == null ) {
230                 this.scriptEvaluatorFactory = defaultContext.scriptEvaluatorFactory;
231             }
232             else {
233                 this.scriptEvaluatorFactory = scriptEvaluatorFactory;
234             }
235             return this;
236         }
237
238         public ValidatorFactoryScopedContext.Builder setFailFast(boolean failFast) {
239             this.failFast = failFast;
240             return this;
241         }
242
243         public ValidatorFactoryScopedContext.Builder setTraversableResolverResultCacheEnabled(boolean traversableResolverResultCacheEnabled) {
244             this.traversableResolverResultCacheEnabled = traversableResolverResultCacheEnabled;
245             return this;
246         }
247
248         public ValidatorFactoryScopedContext.Builder setConstraintValidatorPayload(Object constraintValidatorPayload) {
249             this.constraintValidatorPayload = constraintValidatorPayload;
250             return this;
251         }
252
253         public ValidatorFactoryScopedContext build() {
254             return new ValidatorFactoryScopedContext(
255                     messageInterpolator,
256                     traversableResolver,
257                     parameterNameProvider,
258                     clockProvider,
259                     temporalValidationTolerance,
260                     scriptEvaluatorFactory,
261                     failFast,
262                     traversableResolverResultCacheEnabled,
263                     constraintValidatorPayload,
264                     HibernateConstraintValidatorInitializationContextImpl.of(
265                             constraintValidatorInitializationContext,
266                             scriptEvaluatorFactory,
267                             clockProvider,
268                             temporalValidationTolerance
269                     )
270             );
271         }
272     }
273 }
274