WebjetResourceBundleMessageInterpolator.java
package sk.iway.iwcm.system.spring.webjet_component;
import java.lang.invoke.MethodHandles;
import java.security.PrivilegedAction;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.el.ELManager;
import javax.el.ExpressionFactory;
import javax.validation.MessageInterpolator;
import javax.validation.ValidationException;
import org.hibernate.validator.internal.engine.messageinterpolation.InterpolationTerm;
import org.hibernate.validator.internal.engine.messageinterpolation.InterpolationTermType;
import org.hibernate.validator.internal.engine.messageinterpolation.parser.MessageDescriptorFormatException;
import org.hibernate.validator.internal.engine.messageinterpolation.parser.Token;
import org.hibernate.validator.internal.engine.messageinterpolation.parser.TokenCollector;
import org.hibernate.validator.internal.engine.messageinterpolation.parser.TokenIterator;
import org.hibernate.validator.internal.util.ConcurrentReferenceHashMap;
import org.hibernate.validator.internal.util.logging.Log;
import org.hibernate.validator.internal.util.logging.LoggerFactory;
import org.hibernate.validator.internal.util.privilegedactions.GetClassLoader;
import org.hibernate.validator.internal.util.privilegedactions.SetContextClassLoader;
import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
import org.hibernate.validator.resourceloading.PlatformResourceBundleLocator;
import org.hibernate.validator.spi.resourceloading.ResourceBundleLocator;
import org.springframework.validation.beanvalidation.MessageSourceResourceBundleLocator;
import sk.iway.iwcm.Logger;
public class WebjetResourceBundleMessageInterpolator implements MessageInterpolator {
private boolean cachingEnabled = false;
private ExpressionFactory expressionFactory;
private static final Log LOG = LoggerFactory.make(MethodHandles.lookup());
private final Locale defaultLocale;
private final ResourceBundleLocator userResourceBundleLocator;
private final ResourceBundleLocator defaultResourceBundleLocator;
private final ResourceBundleLocator contributorResourceBundleLocator;
private final ConcurrentReferenceHashMap<String, List<Token>> tokenizedParameterMessages;
private final ConcurrentReferenceHashMap<String, List<Token>> tokenizedELMessages;
private static final Pattern LEFT_BRACE = Pattern.compile("\\{", 16);
private static final Pattern RIGHT_BRACE = Pattern.compile("\\}", 16);
private static final Pattern SLASH = Pattern.compile("\\\\", 16);
private static final Pattern DOLLAR = Pattern.compile("\\$", 16);
public WebjetResourceBundleMessageInterpolator() {
this(new MessageSourceResourceBundleLocator( new WebjetMessageSource()), new PlatformResourceBundleLocator("org.hibernate.validator.ValidationMessages"), false);
this.expressionFactory = buildExpressionFactory();
}
public WebjetResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundleLocator, ResourceBundleLocator contributorResourceBundleLocator, boolean cacheMessages) {
this.defaultLocale = Locale.getDefault();
if (userResourceBundleLocator == null) {
this.userResourceBundleLocator = new PlatformResourceBundleLocator("ValidationMessages");
} else {
this.userResourceBundleLocator = userResourceBundleLocator;
}
if (contributorResourceBundleLocator == null) {
this.contributorResourceBundleLocator = new PlatformResourceBundleLocator("ContributorValidationMessages", (ClassLoader)null, true);
} else {
this.contributorResourceBundleLocator = contributorResourceBundleLocator;
}
this.defaultResourceBundleLocator = new PlatformResourceBundleLocator("org.hibernate.validator.ValidationMessages");
this.cachingEnabled = cacheMessages;
if (this.cachingEnabled) {
this.tokenizedParameterMessages = new ConcurrentReferenceHashMap<>(100, 0.75F, 16, ConcurrentReferenceHashMap.ReferenceType.SOFT, ConcurrentReferenceHashMap.ReferenceType.SOFT, EnumSet.noneOf(ConcurrentReferenceHashMap.Option.class));
this.tokenizedELMessages = new ConcurrentReferenceHashMap<>(100, 0.75F, 16, ConcurrentReferenceHashMap.ReferenceType.SOFT, ConcurrentReferenceHashMap.ReferenceType.SOFT, EnumSet.noneOf(ConcurrentReferenceHashMap.Option.class));
} else {
this.tokenizedParameterMessages = null;
this.tokenizedELMessages = null;
}
}
public String interpolate(String message, Context context) {
String interpolatedMessage = message;
try {
interpolatedMessage = this.interpolateMessage(message, context, this.defaultLocale);
} catch (MessageDescriptorFormatException var5) {
LOG.warn(var5.getMessage());
}
return interpolatedMessage;
}
public String interpolate(String message, Context context, Locale locale) {
String interpolatedMessage = message;
try {
interpolatedMessage = this.interpolateMessage(message, context, locale);
} catch (ValidationException var6) {
LOG.warn(var6.getMessage());
}
return interpolatedMessage;
}
private String interpolateMessage(String message, Context context, Locale locale) throws MessageDescriptorFormatException {
String resolvedMessage = this.resolveMessage(message, locale);
if (resolvedMessage.indexOf(123) > -1) {
resolvedMessage = this.interpolateExpression(new TokenIterator(this.getParameterTokens(resolvedMessage, this.tokenizedParameterMessages, InterpolationTermType.PARAMETER)), context, locale);
resolvedMessage = this.interpolateExpression(new TokenIterator(this.getParameterTokens(resolvedMessage, this.tokenizedELMessages, InterpolationTermType.EL)), context, locale);
}
resolvedMessage = this.replaceEscapedLiterals(resolvedMessage);
return resolvedMessage;
}
private List<Token> getParameterTokens(String resolvedMessage, ConcurrentReferenceHashMap<String, List<Token>> cache, InterpolationTermType termType) {
return this.cachingEnabled
?
cache.computeIfAbsent(resolvedMessage, rm -> (new TokenCollector(resolvedMessage, termType)).getTokenList())
:
(new TokenCollector(resolvedMessage, termType)).getTokenList();
}
private String resolveMessage(String message, Locale locale) {
String resolvedMessage = message;
ResourceBundle userResourceBundle = this.userResourceBundleLocator.getResourceBundle(locale);
ResourceBundle constraintContributorResourceBundle = this.contributorResourceBundleLocator.getResourceBundle(locale);
ResourceBundle defaultResourceBundle = this.defaultResourceBundleLocator.getResourceBundle(locale);
boolean evaluatedDefaultBundleOnce = false;
while(true) {
String userBundleResolvedMessage = userResourceBundle.getString(resolvedMessage);
if (this.hasReplacementNotTakenPlace(userBundleResolvedMessage, resolvedMessage)) {
userBundleResolvedMessage = this.interpolateBundleMessage(resolvedMessage, constraintContributorResourceBundle, locale, true);
}
if (evaluatedDefaultBundleOnce && this.hasReplacementNotTakenPlace(userBundleResolvedMessage, resolvedMessage)) {
return resolvedMessage;
}
resolvedMessage = this.interpolateBundleMessage(userBundleResolvedMessage, defaultResourceBundle, locale, false);
evaluatedDefaultBundleOnce = true;
}
}
private String replaceEscapedLiterals(String resolvedMessage) {
if (resolvedMessage.indexOf(92) > -1) {
resolvedMessage = LEFT_BRACE.matcher(resolvedMessage).replaceAll("{");
resolvedMessage = RIGHT_BRACE.matcher(resolvedMessage).replaceAll("}");
resolvedMessage = SLASH.matcher(resolvedMessage).replaceAll(Matcher.quoteReplacement("\\"));
resolvedMessage = DOLLAR.matcher(resolvedMessage).replaceAll(Matcher.quoteReplacement("$"));
}
return resolvedMessage;
}
private boolean hasReplacementNotTakenPlace(String origMessage, String newMessage) {
return origMessage.equals(newMessage);
}
private String interpolateBundleMessage(String message, ResourceBundle bundle, Locale locale, boolean recursive) throws MessageDescriptorFormatException {
TokenCollector tokenCollector = new TokenCollector(message, InterpolationTermType.PARAMETER);
TokenIterator tokenIterator = new TokenIterator(tokenCollector.getTokenList());
while(tokenIterator.hasMoreInterpolationTerms()) {
String term = tokenIterator.nextInterpolationTerm();
String resolvedParameterValue = this.resolveParameter(term, bundle, locale, recursive);
tokenIterator.replaceCurrentInterpolationTerm(resolvedParameterValue);
}
return tokenIterator.getInterpolatedMessage();
}
private String interpolateExpression(TokenIterator tokenIterator, Context context, Locale locale) throws MessageDescriptorFormatException {
while(tokenIterator.hasMoreInterpolationTerms()) {
String term = tokenIterator.nextInterpolationTerm();
String resolvedExpression = this.interpolate(context, locale, term);
tokenIterator.replaceCurrentInterpolationTerm(resolvedExpression);
}
return tokenIterator.getInterpolatedMessage();
}
private String resolveParameter(String parameterName, ResourceBundle bundle, Locale locale, boolean recursive) throws MessageDescriptorFormatException {
String parameterValue;
try {
if (bundle != null) {
parameterValue = bundle.getString(this.removeCurlyBraces(parameterName));
if (recursive) {
parameterValue = this.interpolateBundleMessage(parameterValue, bundle, locale, recursive);
}
} else {
parameterValue = parameterName;
}
} catch (MissingResourceException var7) {
parameterValue = parameterName;
}
return parameterValue;
}
private String removeCurlyBraces(String parameter) {
return parameter.substring(1, parameter.length() - 1);
}
public String interpolate(Context context, Locale locale, String message) {
InterpolationTerm expression = new InterpolationTerm(message, locale, expressionFactory);
return expression.interpolate(context);
}
private static ExpressionFactory buildExpressionFactory() {
if (canLoadExpressionFactory()) {
ExpressionFactory expressionFactory = ELManager.getExpressionFactory();
Logger.debug(WebjetResourceBundleMessageInterpolator.class, "Loaded expression factory via original TCCL");
return expressionFactory;
} else {
ClassLoader originalContextClassLoader = run(GetClassLoader.fromContext());
try {
run(SetContextClassLoader.action(ResourceBundleMessageInterpolator.class.getClassLoader()));
ExpressionFactory expressionFactory;
ExpressionFactory var2;
if (canLoadExpressionFactory()) {
expressionFactory = ELManager.getExpressionFactory();
Logger.debug(WebjetResourceBundleMessageInterpolator.class, "Loaded expression factory via HV classloader");
var2 = expressionFactory;
return var2;
}
run(SetContextClassLoader.action(ELManager.class.getClassLoader()));
if (canLoadExpressionFactory()) {
expressionFactory = ELManager.getExpressionFactory();
Logger.debug(WebjetResourceBundleMessageInterpolator.class, "Loaded expression factory via EL classloader");
var2 = expressionFactory;
return var2;
}
} catch (Exception var6) {
throw LOG.getUnableToInitializeELExpressionFactoryException(var6);
} finally {
run(SetContextClassLoader.action(originalContextClassLoader));
}
throw LOG.getUnableToInitializeELExpressionFactoryException((Throwable)null);
}
}
private static boolean canLoadExpressionFactory() {
try {
ExpressionFactory.newInstance();
return true;
} catch (Exception var1) {
return false;
}
}
private static <T> T run(PrivilegedAction<T> action) {
return action.run();
}
}