Skip to content

Commit 91fc251

Browse files
committed
HV-1831 Do not create unnecessary term interpolators
Signed-off-by: marko-bekhta <[email protected]>
1 parent 5cfddaf commit 91fc251

File tree

8 files changed

+90
-111
lines changed

8 files changed

+90
-111
lines changed

engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/ElTermResolver.java

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
* @author Adam Stawicki
3333
* @author Guillaume Smet
3434
*/
35-
public class ElTermResolver implements TermResolver {
35+
public final class ElTermResolver implements TermResolver {
3636

3737
private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() );
3838

@@ -41,11 +41,6 @@ public class ElTermResolver implements TermResolver {
4141
*/
4242
private static final String VALIDATED_VALUE_NAME = "validatedValue";
4343

44-
/**
45-
* The locale for which to interpolate the expression.
46-
*/
47-
private final Locale locale;
48-
4944
/**
5045
* Factory for creating EL expressions
5146
*/
@@ -54,22 +49,20 @@ public class ElTermResolver implements TermResolver {
5449
/**
5550
* Construct the resolver. The expression factory has to be passed in to ensure that it is
5651
* set up early and to allow for application control.
57-
* @param locale the locale.
5852
* @param expressionFactory the expression factory.
5953
*/
60-
public ElTermResolver(Locale locale, ExpressionFactory expressionFactory) {
61-
this.locale = locale;
54+
public ElTermResolver(ExpressionFactory expressionFactory) {
6255
this.expressionFactory = expressionFactory;
6356
}
6457

6558
@Override
66-
public String interpolate(MessageInterpolator.Context context, String expression) {
59+
public String interpolate(MessageInterpolator.Context context, Locale locale, String expression) {
6760
String resolvedExpression = expression;
6861

6962
ELContext elContext = getElContext( context );
7063

7164
try {
72-
ValueExpression valueExpression = bindContextValues( expression, context, elContext );
65+
ValueExpression valueExpression = bindContextValues( expression, context, locale, elContext );
7366
resolvedExpression = (String) valueExpression.getValue( elContext );
7467
}
7568
catch (DisabledFeatureELException dfee) {
@@ -110,7 +103,7 @@ private ELContext getElContext(MessageInterpolator.Context context) {
110103
}
111104
}
112105

113-
private ValueExpression bindContextValues(String messageTemplate, MessageInterpolator.Context messageInterpolatorContext, ELContext elContext) {
106+
private ValueExpression bindContextValues(String messageTemplate, MessageInterpolator.Context messageInterpolatorContext, Locale locale, ELContext elContext) {
114107
// bind the validated value
115108
ValueExpression valueExpression = expressionFactory.createValueExpression(
116109
messageInterpolatorContext.getValidatedValue(),

engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/InterpolationTerm.java

Lines changed: 0 additions & 74 deletions
This file was deleted.

engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/ParameterTermResolver.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package org.hibernate.validator.internal.engine.messageinterpolation;
66

77
import java.util.Arrays;
8+
import java.util.Locale;
89

910
import jakarta.validation.MessageInterpolator.Context;
1011

@@ -18,10 +19,15 @@
1819
* @author Guillaume Smet
1920
* @author Alexander Gatsenko
2021
*/
21-
public class ParameterTermResolver implements TermResolver {
22+
public final class ParameterTermResolver implements TermResolver {
23+
24+
public static final ParameterTermResolver INSTANCE = new ParameterTermResolver();
25+
26+
private ParameterTermResolver() {
27+
}
2228

2329
@Override
24-
public String interpolate(Context context, String expression) {
30+
public String interpolate(Context context, Locale locale, String expression) {
2531
String resolvedExpression;
2632
Object variable = getVariable( context, removeCurlyBraces( expression ) );
2733
if ( variable != null ) {
@@ -34,8 +40,8 @@ public String interpolate(Context context, String expression) {
3440
}
3541

3642
private Object getVariable(Context context, String parameter) {
37-
if ( context instanceof HibernateMessageInterpolatorContext ) {
38-
Object variable = ( (HibernateMessageInterpolatorContext) context ).getMessageParameters().get( parameter );
43+
if ( context instanceof HibernateMessageInterpolatorContext hibernateMessageInterpolatorContext ) {
44+
Object variable = hibernateMessageInterpolatorContext.getMessageParameters().get( parameter );
3945
if ( variable != null ) {
4046
return variable;
4147
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.validator.internal.engine.messageinterpolation;
6+
7+
import java.util.Locale;
8+
9+
import jakarta.el.ExpressionFactory;
10+
import jakarta.validation.MessageInterpolator;
11+
12+
/**
13+
* Helper class dealing with the interpolation of a single message parameter or expression extracted from a message
14+
* descriptor.
15+
*
16+
* @author Hardy Ferentschik
17+
*/
18+
public class TermInterpolator {
19+
/**
20+
* Meta character to designate an EL expression.
21+
*/
22+
private static final String EL_DESIGNATION_CHARACTER = "$";
23+
24+
private final ElTermResolver elTermResolver;
25+
26+
/**
27+
* Create a term interpolator.
28+
*
29+
* @param expressionFactory the expression factory to use if the expression uses EL.
30+
*/
31+
public TermInterpolator(ExpressionFactory expressionFactory) {
32+
this.elTermResolver = new ElTermResolver( expressionFactory );
33+
}
34+
35+
public static boolean isElExpression(String expression) {
36+
return expression.startsWith( EL_DESIGNATION_CHARACTER );
37+
}
38+
39+
/**
40+
* Interpolate an expression.
41+
*
42+
* @param expression the expression.
43+
* @param locale the locale.
44+
*/
45+
public String interpolate(MessageInterpolator.Context context, String expression, Locale locale) {
46+
if ( isElExpression( expression ) ) {
47+
return elTermResolver.interpolate( context, locale, expression );
48+
}
49+
else {
50+
return ParameterTermResolver.INSTANCE.interpolate( context, locale, expression );
51+
}
52+
}
53+
}

engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/TermResolver.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55
package org.hibernate.validator.internal.engine.messageinterpolation;
66

7+
import java.util.Locale;
8+
79
import jakarta.validation.MessageInterpolator;
810

911
/**
@@ -16,10 +18,10 @@ public interface TermResolver {
1618
/**
1719
* Interpolates given term based on the constraint validation context.
1820
*
19-
* @param term the message to interpolate
2021
* @param context contextual information related to the interpolation
21-
*
22+
* @param locale the locale for which to interpolate the expression
23+
* @param term the message to interpolate
2224
* @return interpolated message
2325
*/
24-
String interpolate(MessageInterpolator.Context context, String term);
26+
String interpolate(MessageInterpolator.Context context, Locale locale, String term);
2527
}

engine/src/main/java/org/hibernate/validator/messageinterpolation/ParameterMessageInterpolator.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
import org.hibernate.validator.Incubating;
1313
import org.hibernate.validator.internal.engine.messageinterpolation.DefaultLocaleResolver;
14-
import org.hibernate.validator.internal.engine.messageinterpolation.InterpolationTerm;
1514
import org.hibernate.validator.internal.engine.messageinterpolation.ParameterTermResolver;
15+
import org.hibernate.validator.internal.engine.messageinterpolation.TermInterpolator;
1616
import org.hibernate.validator.internal.util.logging.Log;
1717
import org.hibernate.validator.internal.util.logging.LoggerFactory;
1818
import org.hibernate.validator.spi.messageinterpolation.LocaleResolver;
@@ -51,13 +51,12 @@ public ParameterMessageInterpolator(Set<Locale> locales, Locale defaultLocale, L
5151

5252
@Override
5353
protected String interpolate(Context context, Locale locale, String term) {
54-
if ( InterpolationTerm.isElExpression( term ) ) {
54+
if ( TermInterpolator.isElExpression( term ) ) {
5555
LOG.warnElIsUnsupported( term );
5656
return term;
5757
}
5858
else {
59-
ParameterTermResolver parameterTermResolver = new ParameterTermResolver();
60-
return parameterTermResolver.interpolate( context, term );
59+
return ParameterTermResolver.INSTANCE.interpolate( context, locale, term );
6160
}
6261
}
6362
}

engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import org.hibernate.validator.Incubating;
1818
import org.hibernate.validator.internal.engine.messageinterpolation.DefaultLocaleResolver;
19-
import org.hibernate.validator.internal.engine.messageinterpolation.InterpolationTerm;
19+
import org.hibernate.validator.internal.engine.messageinterpolation.TermInterpolator;
2020
import org.hibernate.validator.internal.util.actions.GetClassLoader;
2121
import org.hibernate.validator.internal.util.actions.SetContextClassLoader;
2222
import org.hibernate.validator.internal.util.logging.Log;
@@ -38,7 +38,7 @@ public class ResourceBundleMessageInterpolator extends AbstractMessageInterpolat
3838

3939
private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() );
4040

41-
private final ExpressionFactory expressionFactory;
41+
private final TermInterpolator termInterpolator;
4242

4343
public ResourceBundleMessageInterpolator() {
4444
this( Collections.emptySet(), Locale.getDefault(), new DefaultLocaleResolver(), false );
@@ -76,7 +76,7 @@ public ResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundl
7676
@Incubating
7777
public ResourceBundleMessageInterpolator(Set<Locale> locales, Locale defaultLocale, LocaleResolver localeResolver, boolean preloadResourceBundles) {
7878
super( locales, defaultLocale, localeResolver, preloadResourceBundles );
79-
this.expressionFactory = buildExpressionFactory();
79+
this.termInterpolator = new TermInterpolator( buildExpressionFactory() );
8080
}
8181

8282
/**
@@ -89,7 +89,7 @@ public ResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundl
8989
LocaleResolver localeResolver,
9090
boolean preloadResourceBundles) {
9191
super( userResourceBundleLocator, locales, defaultLocale, localeResolver, preloadResourceBundles );
92-
this.expressionFactory = buildExpressionFactory();
92+
this.termInterpolator = new TermInterpolator( buildExpressionFactory() );
9393
}
9494

9595
/**
@@ -103,7 +103,7 @@ public ResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundl
103103
LocaleResolver localeResolver,
104104
boolean preloadResourceBundles) {
105105
super( userResourceBundleLocator, contributorResourceBundleLocator, locales, defaultLocale, localeResolver, preloadResourceBundles );
106-
this.expressionFactory = buildExpressionFactory();
106+
this.termInterpolator = new TermInterpolator( buildExpressionFactory() );
107107
}
108108

109109
/**
@@ -119,7 +119,7 @@ public ResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundl
119119
boolean cachingEnabled) {
120120
super( userResourceBundleLocator, contributorResourceBundleLocator, locales, defaultLocale, localeResolver, preloadResourceBundles,
121121
cachingEnabled );
122-
this.expressionFactory = buildExpressionFactory();
122+
this.termInterpolator = new TermInterpolator( buildExpressionFactory() );
123123
}
124124

125125
/**
@@ -133,7 +133,7 @@ public ResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundl
133133
boolean preloadResourceBundles,
134134
boolean cachingEnabled) {
135135
super( userResourceBundleLocator, null, locales, defaultLocale, localeResolver, preloadResourceBundles, cachingEnabled );
136-
this.expressionFactory = buildExpressionFactory();
136+
this.termInterpolator = new TermInterpolator( buildExpressionFactory() );
137137
}
138138

139139
/**
@@ -148,13 +148,12 @@ public ResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundl
148148
boolean cachingEnabled,
149149
ExpressionFactory expressionFactory) {
150150
super( userResourceBundleLocator, null, locales, defaultLocale, localeResolver, preloadResourceBundles, cachingEnabled );
151-
this.expressionFactory = expressionFactory;
151+
this.termInterpolator = new TermInterpolator( expressionFactory );
152152
}
153153

154154
@Override
155155
protected String interpolate(Context context, Locale locale, String term) {
156-
InterpolationTerm expression = new InterpolationTerm( term, locale, expressionFactory );
157-
return expression.interpolate( context );
156+
return termInterpolator.interpolate( context, term, locale );
158157
}
159158

160159
/**

engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ParameterTermResolverTest.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import java.util.Arrays;
1010
import java.util.HashMap;
11+
import java.util.Locale;
1112
import java.util.Map;
1213

1314
import jakarta.validation.MessageInterpolator;
@@ -28,7 +29,7 @@
2829
*/
2930
public class ParameterTermResolverTest {
3031

31-
private final ParameterTermResolver resolver = new ParameterTermResolver();
32+
private final ParameterTermResolver resolver = ParameterTermResolver.INSTANCE;
3233

3334
@DataProvider(name = "interpolateByNotArrayValueArgs")
3435
public static Object[][] interpolateByNotArrayValueArgs() {
@@ -75,7 +76,7 @@ public void testInterpolateShouldResolveExpressionByNotArrayValue(
7576
);
7677
final String srcExpression = createVariableExpression( variableName );
7778

78-
final String actualResolvedExpression = resolver.interpolate( context, srcExpression );
79+
final String actualResolvedExpression = resolver.interpolate( context, Locale.ROOT, srcExpression );
7980
assertEquals( actualResolvedExpression, expectedResolvedExpression );
8081
}
8182

@@ -91,7 +92,7 @@ public void testInterpolateShouldResolveExpressionByArrayValue(
9192
);
9293
final String srcExpression = createVariableExpression( variableName );
9394

94-
final String actualResolvedExpression = resolver.interpolate( context, srcExpression );
95+
final String actualResolvedExpression = resolver.interpolate( context, Locale.ROOT, srcExpression );
9596
assertEquals( actualResolvedExpression, expectedResolvedExpression );
9697
}
9798

@@ -106,7 +107,7 @@ public void testInterpolateShouldAllowUseNotHibernateContext(
106107
);
107108
final String srcExpression = createVariableExpression( variableName );
108109

109-
final String actualResolvedExpression = resolver.interpolate( context, srcExpression );
110+
final String actualResolvedExpression = resolver.interpolate( context, Locale.ROOT, srcExpression );
110111
assertEquals( actualResolvedExpression, expectedResolvedExpression );
111112
}
112113

0 commit comments

Comments
 (0)