Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 13233a8

Browse files
HV-2004 Add constraint initialization payload
and use it to cache patterns in the predefined factory Signed-off-by: marko-bekhta <marko.prykladna@gmail.com>
1 parent eb85d34 commit 13233a8

13 files changed

+241
-23
lines changed

‎engine/src/main/java/org/hibernate/validator/BaseHibernateValidatorConfiguration.java‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,30 @@ public interface BaseHibernateValidatorConfiguration<S extends BaseHibernateVali
364364
@Incubating
365365
S constraintValidatorPayload(Object constraintValidatorPayload);
366366

367+
/**
368+
* Allows adding a payload which will be available during the constraint validators initialization.
369+
* If the method is called multiple times passing different instances of the same class,
370+
* only the payload passed last will be available for that type.
371+
*
372+
* @param constraintValidatorInitializationSharedService the payload to retrieve from the constraint validator initializers
373+
* @return {@code this} following the chaining method pattern
374+
* @since 9.1.0
375+
*/
376+
@Incubating
377+
S addConstraintValidatorInitializationSharedService(Object constraintValidatorInitializationSharedService);
378+
379+
/**
380+
* Allows adding a payload which will be available during the constraint validators initialization.
381+
* If the method is called multiple times passing different instances of the same class,
382+
* only the payload passed last will be available for that type.
383+
*
384+
* @param constraintValidatorInitializationSharedService the payload to retrieve from the constraint validator initializers
385+
* @return {@code this} following the chaining method pattern
386+
* @since 9.1.0
387+
*/
388+
@Incubating
389+
<T, V extends T> S addConstraintValidatorInitializationSharedService(Class<T> serviceClass, V constraintValidatorInitializationSharedService);
390+
367391
/**
368392
* Allows to set a getter property selection strategy defining the rules determining if a method is a getter
369393
* or not.

‎engine/src/main/java/org/hibernate/validator/constraintvalidation/HibernateConstraintValidatorInitializationContext.java‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,20 @@ public interface HibernateConstraintValidatorInitializationContext {
5656
*/
5757
@Incubating
5858
Duration getTemporalValidationTolerance();
59+
60+
/**
61+
* Returns an instance of the specified service type or {@code null} if the current context does not
62+
* contain such service.
63+
* The requested service type must match the one with which it was originally added with
64+
* {@link org.hibernate.validator.HibernateValidatorConfiguration#addConstraintValidatorInitializationSharedService(Object)}.
65+
*
66+
* @param type the type of service to retrieve
67+
* @return an instance of the specified type or {@code null} if the current constraint initialization context does not
68+
* contain an instance of such type
69+
*
70+
* @since 9.1.0
71+
* @see org.hibernate.validator.HibernateValidatorConfiguration#addConstraintValidatorInitializationSharedService(Object)
72+
*/
73+
@Incubating
74+
<C> C getConstraintValidatorInitializationSharedService(Class<C> type);
5975
}

‎engine/src/main/java/org/hibernate/validator/internal/constraintvalidators/bv/PatternValidator.java‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,40 @@
88
import java.util.regex.Matcher;
99
import java.util.regex.PatternSyntaxException;
1010

11-
import jakarta.validation.ConstraintValidator;
1211
import jakarta.validation.ConstraintValidatorContext;
1312
import jakarta.validation.constraints.Pattern;
13+
import jakarta.validation.metadata.ConstraintDescriptor;
1414

15+
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidator;
1516
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorContext;
17+
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorInitializationContext;
18+
import org.hibernate.validator.internal.engine.constraintvalidation.PatternConstraintInitializer;
1619
import org.hibernate.validator.internal.engine.messageinterpolation.util.InterpolationHelper;
1720
import org.hibernate.validator.internal.util.logging.Log;
1821
import org.hibernate.validator.internal.util.logging.LoggerFactory;
1922

2023
/**
2124
* @author Hardy Ferentschik
2225
*/
23-
public class PatternValidator implements ConstraintValidator<Pattern, CharSequence> {
26+
public class PatternValidator implements HibernateConstraintValidator<Pattern, CharSequence> {
2427

2528
private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() );
2629

2730
private java.util.regex.Pattern pattern;
2831
private String escapedRegexp;
2932

3033
@Override
31-
public void initialize(Pattern parameters) {
34+
public void initialize(ConstraintDescriptor<Pattern> constraintDescriptor, HibernateConstraintValidatorInitializationContext initializationContext) {
35+
Pattern parameters = constraintDescriptor.getAnnotation();
3236
Pattern.Flag[] flags = parameters.flags();
3337
int intFlag = 0;
3438
for ( Pattern.Flag flag : flags ) {
3539
intFlag = intFlag | flag.getValue();
3640
}
3741

3842
try {
39-
pattern = java.util.regex.Pattern.compile( parameters.regexp(), intFlag );
43+
pattern = initializationContext.getConstraintValidatorInitializationSharedService( PatternConstraintInitializer.class )
44+
.of( parameters.regexp(), intFlag );
4045
}
4146
catch (PatternSyntaxException e) {
4247
throw LOG.getInvalidRegularExpressionException( e );

‎engine/src/main/java/org/hibernate/validator/internal/engine/AbstractConfigurationImpl.java‎

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.hibernate.validator.cfg.ConstraintMapping;
3838
import org.hibernate.validator.constraintvalidation.spi.DefaultConstraintValidatorFactory;
3939
import org.hibernate.validator.internal.cfg.context.DefaultConstraintMapping;
40+
import org.hibernate.validator.internal.engine.constraintvalidation.HibernateConstraintValidatorInitializationSharedServiceManager;
4041
import org.hibernate.validator.internal.engine.resolver.TraversableResolvers;
4142
import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorDescriptor;
4243
import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager;
@@ -114,11 +115,12 @@ public abstract class AbstractConfigurationImpl<T extends BaseHibernateValidator
114115
private final Map<ValueExtractorDescriptor.Key, ValueExtractorDescriptor> valueExtractorDescriptors = new HashMap<>();
115116

116117
// HV-specific options
118+
private final HibernateConstraintValidatorInitializationSharedServiceManager constraintValidatorInitializationSharedServiceManager;
117119
private final Set<DefaultConstraintMapping> programmaticMappings = newHashSet();
120+
private final MethodValidationConfiguration.Builder methodValidationConfigurationBuilder = new MethodValidationConfiguration.Builder();
118121
private boolean failFast;
119122
private boolean failFastOnPropertyViolation;
120123
private ClassLoader externalClassLoader;
121-
private final MethodValidationConfiguration.Builder methodValidationConfigurationBuilder = new MethodValidationConfiguration.Builder();
122124
private boolean traversableResolverResultCacheEnabled = true;
123125
private ScriptEvaluatorFactory scriptEvaluatorFactory;
124126
private Duration temporalValidationTolerance;
@@ -159,6 +161,7 @@ private AbstractConfigurationImpl() {
159161
this.defaultParameterNameProvider = new DefaultParameterNameProvider();
160162
this.defaultClockProvider = DefaultClockProvider.INSTANCE;
161163
this.defaultPropertyNodeNameProvider = new DefaultPropertyNodeNameProvider();
164+
this.constraintValidatorInitializationSharedServiceManager = new HibernateConstraintValidatorInitializationSharedServiceManager();
162165
}
163166

164167
@Override
@@ -352,6 +355,23 @@ public T constraintValidatorPayload(Object constraintValidatorPayload) {
352355
return thisAsT();
353356
}
354357

358+
@Override
359+
public T addConstraintValidatorInitializationSharedService(Object constraintValidatorInitializationSharedService) {
360+
Contracts.assertNotNull( constraintValidatorInitializationSharedService, MESSAGES.parameterMustNotBeNull( "constraintValidatorInitializationSharedService" ) );
361+
362+
this.constraintValidatorInitializationSharedServiceManager.register( constraintValidatorInitializationSharedService );
363+
return thisAsT();
364+
}
365+
366+
@Override
367+
public <V, S extends V> T addConstraintValidatorInitializationSharedService(Class<V> serviceClass, S constraintValidatorInitializationSharedService) {
368+
Contracts.assertNotNull( constraintValidatorInitializationSharedService, MESSAGES.parameterMustNotBeNull( "serviceClass" ) );
369+
Contracts.assertNotNull( constraintValidatorInitializationSharedService, MESSAGES.parameterMustNotBeNull( "constraintValidatorInitializationSharedService" ) );
370+
this.constraintValidatorInitializationSharedServiceManager.register( serviceClass, constraintValidatorInitializationSharedService );
371+
372+
return thisAsT();
373+
}
374+
355375
@Override
356376
public T getterPropertySelectionStrategy(GetterPropertySelectionStrategy getterPropertySelectionStrategy) {
357377
Contracts.assertNotNull( getterPropertySelectionStrategy, MESSAGES.parameterMustNotBeNull( "getterPropertySelectionStrategy" ) );
@@ -548,6 +568,10 @@ public Object getConstraintValidatorPayload() {
548568
return constraintValidatorPayload;
549569
}
550570

571+
public HibernateConstraintValidatorInitializationSharedServiceManager getConstraintValidatorInitializationSharedServiceManager() {
572+
return constraintValidatorInitializationSharedServiceManager;
573+
}
574+
551575
public GetterPropertySelectionStrategy getGetterPropertySelectionStrategy() {
552576
return getterPropertySelectionStrategy;
553577
}

‎engine/src/main/java/org/hibernate/validator/internal/engine/PredefinedScopeValidatorFactoryImpl.java‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineBeanMetaDataClassNormalizer;
1111
import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintExpressionLanguageFeatureLevel;
1212
import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintMappings;
13+
import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintValidatorInitializationSharedServices;
1314
import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintValidatorPayload;
1415
import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineCustomViolationExpressionLanguageFeatureLevel;
1516
import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineExternalClassLoader;
@@ -47,6 +48,7 @@
4748
import org.hibernate.validator.internal.cfg.context.DefaultConstraintMapping;
4849
import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager;
4950
import org.hibernate.validator.internal.engine.constraintvalidation.HibernateConstraintValidatorInitializationContextImpl;
51+
import org.hibernate.validator.internal.engine.constraintvalidation.PatternConstraintInitializer;
5052
import org.hibernate.validator.internal.engine.constraintvalidation.PredefinedScopeConstraintValidatorManagerImpl;
5153
import org.hibernate.validator.internal.engine.groups.ValidationOrderGenerator;
5254
import org.hibernate.validator.internal.engine.tracking.DefaultProcessedBeansTrackingVoter;
@@ -124,9 +126,10 @@ public PredefinedScopeValidatorFactoryImpl(ConfigurationState configurationState
124126
ScriptEvaluatorFactory scriptEvaluatorFactory = determineScriptEvaluatorFactory( configurationState, properties, externalClassLoader );
125127
Duration temporalValidationTolerance = determineTemporalValidationTolerance( configurationState, properties );
126128

129+
PatternConstraintInitializer.CachingPatternConstraintInitializer patternConstraintInitializer = new PatternConstraintInitializer.CachingPatternConstraintInitializer();
127130
HibernateConstraintValidatorInitializationContextImpl constraintValidatorInitializationContext = new HibernateConstraintValidatorInitializationContextImpl(
128-
scriptEvaluatorFactory, configurationState.getClockProvider(), temporalValidationTolerance );
129-
131+
scriptEvaluatorFactory, configurationState.getClockProvider(), temporalValidationTolerance,
132+
determineConstraintValidatorInitializationSharedServices( hibernateSpecificConfig, patternConstraintInitializer ) );
130133

131134
this.validatorFactoryScopedContext = new ValidatorFactoryScopedContext(
132135
configurationState.getMessageInterpolator(),
@@ -248,6 +251,9 @@ public PredefinedScopeValidatorFactoryImpl(ConfigurationState configurationState
248251
beanClassesToInitialize
249252
);
250253

254+
// at this point all constraints had to be initialized, so we can clear up the pattern cache:
255+
patternConstraintInitializer.close();
256+
251257
if ( LOG.isDebugEnabled() ) {
252258
logValidatorFactoryScopedConfiguration( validatorFactoryScopedContext );
253259
}

‎engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryConfigurationHelper.java‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import org.hibernate.validator.cfg.ConstraintMapping;
2222
import org.hibernate.validator.internal.cfg.context.DefaultConstraintMapping;
2323
import org.hibernate.validator.internal.engine.constraintdefinition.ConstraintDefinitionContribution;
24+
import org.hibernate.validator.internal.engine.constraintvalidation.HibernateConstraintValidatorInitializationSharedServiceManager;
25+
import org.hibernate.validator.internal.engine.constraintvalidation.PatternConstraintInitializer;
2426
import org.hibernate.validator.internal.engine.messageinterpolation.DefaultLocaleResolver;
2527
import org.hibernate.validator.internal.engine.scripting.DefaultScriptEvaluatorFactory;
2628
import org.hibernate.validator.internal.metadata.DefaultBeanMetaDataClassNormalizer;
@@ -252,8 +254,7 @@ static Duration determineTemporalValidationTolerance(ConfigurationState configur
252254
}
253255

254256
static Object determineConstraintValidatorPayload(ConfigurationState configurationState) {
255-
if ( configurationState instanceof AbstractConfigurationImpl ) {
256-
AbstractConfigurationImpl<?> hibernateSpecificConfig = (AbstractConfigurationImpl<?>) configurationState;
257+
if ( configurationState instanceof AbstractConfigurationImpl<?> hibernateSpecificConfig ) {
257258
if ( hibernateSpecificConfig.getConstraintValidatorPayload() != null ) {
258259
LOG.logConstraintValidatorPayload( hibernateSpecificConfig.getConstraintValidatorPayload() );
259260
return hibernateSpecificConfig.getConstraintValidatorPayload();
@@ -263,6 +264,23 @@ static Object determineConstraintValidatorPayload(ConfigurationState configurati
263264
return null;
264265
}
265266

267+
static HibernateConstraintValidatorInitializationSharedServiceManager determineConstraintValidatorInitializationSharedServices(ConfigurationState configurationState,
268+
PatternConstraintInitializer patternConstraintInitializer) {
269+
HibernateConstraintValidatorInitializationSharedServiceManager configured = null;
270+
if ( configurationState instanceof AbstractConfigurationImpl<?> hibernateSpecificConfig ) {
271+
if ( hibernateSpecificConfig.getConstraintValidatorPayload() != null ) {
272+
configured = hibernateSpecificConfig.getConstraintValidatorInitializationSharedServiceManager();
273+
}
274+
}
275+
if ( configured == null ) {
276+
configured = new HibernateConstraintValidatorInitializationSharedServiceManager();
277+
}
278+
279+
return configured.immutableWithDefaultServices(
280+
Map.of( PatternConstraintInitializer.class, patternConstraintInitializer )
281+
);
282+
}
283+
266284
static ExpressionLanguageFeatureLevel determineConstraintExpressionLanguageFeatureLevel(AbstractConfigurationImpl<?> hibernateSpecificConfig,
267285
Map<String, String> properties) {
268286
if ( hibernateSpecificConfig != null && hibernateSpecificConfig.getConstraintExpressionLanguageFeatureLevel() != null ) {

‎engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineBeanMetaDataClassNormalizer;
1111
import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintExpressionLanguageFeatureLevel;
1212
import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintMappings;
13+
import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintValidatorInitializationSharedServices;
1314
import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintValidatorPayload;
1415
import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineCustomViolationExpressionLanguageFeatureLevel;
1516
import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineExternalClassLoader;
@@ -47,6 +48,7 @@
4748
import org.hibernate.validator.internal.cfg.context.DefaultConstraintMapping;
4849
import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager;
4950
import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManagerImpl;
51+
import org.hibernate.validator.internal.engine.constraintvalidation.PatternConstraintInitializer;
5052
import org.hibernate.validator.internal.engine.groups.ValidationOrderGenerator;
5153
import org.hibernate.validator.internal.engine.tracking.DefaultProcessedBeansTrackingVoter;
5254
import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager;
@@ -168,6 +170,7 @@ public ValidatorFactoryImpl(ConfigurationState configurationState) {
168170
determineTraversableResolverResultCacheEnabled( hibernateSpecificConfig, properties ),
169171
determineShowValidatedValuesInTraceLogs( hibernateSpecificConfig, properties ),
170172
determineConstraintValidatorPayload( hibernateSpecificConfig ),
173+
determineConstraintValidatorInitializationSharedServices( hibernateSpecificConfig, new PatternConstraintInitializer.SimplePatternConstraintInitializer() ),
171174
determineConstraintExpressionLanguageFeatureLevel( hibernateSpecificConfig, properties ),
172175
determineCustomViolationExpressionLanguageFeatureLevel( hibernateSpecificConfig, properties )
173176
);

‎engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryScopedContext.java‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorInitializationContext;
1515
import org.hibernate.validator.internal.engine.constraintvalidation.HibernateConstraintValidatorInitializationContextImpl;
16+
import org.hibernate.validator.internal.engine.constraintvalidation.HibernateConstraintValidatorInitializationSharedServiceManager;
1617
import org.hibernate.validator.internal.util.Contracts;
1718
import org.hibernate.validator.internal.util.ExecutableParameterNameProvider;
1819
import org.hibernate.validator.messageinterpolation.ExpressionLanguageFeatureLevel;
@@ -103,13 +104,15 @@ public class ValidatorFactoryScopedContext {
103104
boolean traversableResolverResultCacheEnabled,
104105
boolean showValidatedValuesInTraceLogs,
105106
Object constraintValidatorPayload,
107+
HibernateConstraintValidatorInitializationSharedServiceManager constraintValidatorInitializationSharedServiceManager,
106108
ExpressionLanguageFeatureLevel constraintExpressionLanguageFeatureLevel,
107109
ExpressionLanguageFeatureLevel customViolationExpressionLanguageFeatureLevel) {
108110
this( messageInterpolator, traversableResolver, parameterNameProvider, clockProvider, temporalValidationTolerance, scriptEvaluatorFactory, failFast,
109111
failFastOnPropertyViolation, traversableResolverResultCacheEnabled, showValidatedValuesInTraceLogs, constraintValidatorPayload, constraintExpressionLanguageFeatureLevel,
110112
customViolationExpressionLanguageFeatureLevel,
111113
new HibernateConstraintValidatorInitializationContextImpl( scriptEvaluatorFactory, clockProvider,
112-
temporalValidationTolerance ) );
114+
temporalValidationTolerance, constraintValidatorInitializationSharedServiceManager
115+
) );
113116
}
114117

115118
ValidatorFactoryScopedContext(MessageInterpolator messageInterpolator,
@@ -214,7 +217,7 @@ static class Builder {
214217
private ExpressionLanguageFeatureLevel constraintExpressionLanguageFeatureLevel;
215218
private ExpressionLanguageFeatureLevel customViolationExpressionLanguageFeatureLevel;
216219
private boolean showValidatedValuesInTraceLogs;
217-
private HibernateConstraintValidatorInitializationContextImpl constraintValidatorInitializationContext;
220+
private finalHibernateConstraintValidatorInitializationContextImpl constraintValidatorInitializationContext;
218221

219222
Builder(ValidatorFactoryScopedContext defaultContext) {
220223
Contracts.assertNotNull( defaultContext, "Default context cannot be null." );
@@ -348,7 +351,8 @@ public ValidatorFactoryScopedContext build() {
348351
constraintValidatorInitializationContext,
349352
scriptEvaluatorFactory,
350353
clockProvider,
351-
temporalValidationTolerance
354+
temporalValidationTolerance,
355+
constraintValidatorInitializationContext.getConstraintValidatorInitializationSharedServiceManager()
352356
)
353357
);
354358
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /