Author: hardy.ferentschik
Date: 2010-04-28 10:33:12 -0400 (Wed, 28 Apr 2010)
New Revision: 19314
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/messageinterpolation/
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/messageinterpolation/package.html
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/resourceloading/
Removed:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/Constants.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ResourceBundleMessageInterpolator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/
Modified:
validator/trunk/hibernate-validator/pom.xml
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConfigurationImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConstraintTree.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/AggregateResourceBundleLocator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/CachingResourceBundleLocator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/DelegatingResourceBundleLocator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/PlatformResourceBundleLocator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/ResourceBundleLocator.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/HibernateValidatorConfigurationTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/messageinterpolation/MessageInterpolationTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/messageinterpolation/MessageInterpolationWithDefaultBundleTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/resourceloading/AggregateBundleTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/resourceloading/AggregateResourceBundleLocatorTest.java
validator/trunk/hibernate-validator/src/test/resources/log4j.properties
Log:
HV-310
Modified: validator/trunk/hibernate-validator/pom.xml
===================================================================
--- validator/trunk/hibernate-validator/pom.xml 2010-04-28 11:05:26 UTC (rev 19313)
+++ validator/trunk/hibernate-validator/pom.xml 2010-04-28 14:33:12 UTC (rev 19314)
@@ -135,7 +135,12 @@
org.xml.sax.*;version="0",
org.slf4j.*;version="[1.5.6,2.0.0)"
</Import-Package>
-
<Export-Package>org.hibernate.validator.*;version="${pom.version}"</Export-Package>
+ <Export-Package>
+ org.hibernate.validator;version="${pom.version}",
+
org.hibernate.validator.constraints;version="${pom.version}",
+
org.hibernate.validator.messageinterpolation;version="${pom.version}",
+
org.hibernate.validator.resourceloading;version="${pom.version}",
+ </Export-Package>
</instructions>
</configuration>
<executions>
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java 2010-04-28
11:05:26 UTC (rev 19313)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -19,8 +19,7 @@
import javax.validation.Configuration;
-import org.hibernate.validator.engine.ResourceBundleMessageInterpolator;
-import org.hibernate.validator.engine.resourceloading.ResourceBundleLocator;
+import org.hibernate.validator.resourceloading.ResourceBundleLocator;
/**
* Uniquely identifies Hibernate Validator in the Bean Validation bootstrap
@@ -41,7 +40,7 @@
* </p>
* <p>
* This locator can be used as delegate for custom locators when setting a
- * customized {@link ResourceBundleMessageInterpolator}:
+ * customized {@link
org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator}:
* </p>
* <p/>
* <pre>
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConfigurationImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConfigurationImpl.java 2010-04-28
11:05:26 UTC (rev 19313)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConfigurationImpl.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -37,8 +37,9 @@
import org.hibernate.validator.HibernateValidatorConfiguration;
import org.hibernate.validator.engine.resolver.DefaultTraversableResolver;
-import org.hibernate.validator.engine.resourceloading.PlatformResourceBundleLocator;
-import org.hibernate.validator.engine.resourceloading.ResourceBundleLocator;
+import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
+import org.hibernate.validator.resourceloading.PlatformResourceBundleLocator;
+import org.hibernate.validator.resourceloading.ResourceBundleLocator;
import org.hibernate.validator.util.LoggerFactory;
import org.hibernate.validator.util.Version;
import org.hibernate.validator.xml.ValidationBootstrapParameters;
@@ -59,7 +60,9 @@
private static final Logger log = LoggerFactory.make();
- private final ResourceBundleLocator defaultResourceBundleLocator = new
PlatformResourceBundleLocator( Constants.USER_VALIDATION_MESSAGES );
+ private final ResourceBundleLocator defaultResourceBundleLocator = new
PlatformResourceBundleLocator(
+ ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES
+ );
private final MessageInterpolator defaultMessageInterpolator = new
ResourceBundleMessageInterpolator(
defaultResourceBundleLocator
);
Deleted:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/Constants.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/Constants.java 2010-04-28
11:05:26 UTC (rev 19313)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/Constants.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -1,40 +0,0 @@
-/*
- * $Id:$
- *
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * Licensed 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.hibernate.validator.engine;
-
-/**
- * Constants used throughout the Hibernate Validator project.
- *
- * @author Gunnar Morling
- */
-public final class Constants {
-
- private Constants() {
- }
-
- /**
- * The name of the default message bundle.
- */
- public static final String DEFAULT_VALIDATION_MESSAGES =
"org.hibernate.validator.ValidationMessages";
-
- /**
- * The name of the user-provided message bundle as defined in the specification.
- */
- public static final String USER_VALIDATION_MESSAGES = "ValidationMessages";
-}
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConstraintTree.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConstraintTree.java 2010-04-28
11:05:26 UTC (rev 19313)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConstraintTree.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -1,20 +1,24 @@
+/*
+ * $Id:$
+ *
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.
+ */
+
// $Id$
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* Licensed 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.hibernate.validator.engine;
import java.lang.annotation.Annotation;
Deleted:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ResourceBundleMessageInterpolator.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ResourceBundleMessageInterpolator.java 2010-04-28
11:05:26 UTC (rev 19313)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ResourceBundleMessageInterpolator.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -1,281 +0,0 @@
-// $Id$
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* Licensed 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.hibernate.validator.engine;
-
-import java.util.Locale;
-import java.util.Map;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-import java.util.WeakHashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.validation.MessageInterpolator;
-
-import org.hibernate.validator.engine.resourceloading.CachingResourceBundleLocator;
-import org.hibernate.validator.engine.resourceloading.PlatformResourceBundleLocator;
-import org.hibernate.validator.engine.resourceloading.ResourceBundleLocator;
-
-/**
- * Resource bundle backed message interpolator.
- *
- * @author Emmanuel Bernard
- * @author Hardy Ferentschik
- * @author Gunnar Morling
- */
-public class ResourceBundleMessageInterpolator implements MessageInterpolator {
-
- /**
- * Regular expression used to do message interpolation.
- */
- private static final Pattern messageParameterPattern = Pattern.compile(
"(\\{[^\\}]+?\\})" );
-
- /**
- * The default locale for the current user.
- */
- private final Locale defaultLocale;
-
- /**
- * Loads user-specified resource bundles.
- */
- private final ResourceBundleLocator userResourceBundleLocator;
-
- /**
- * Loads built-in resource bundles.
- */
- private final ResourceBundleLocator defaultResourceBundleLocator;
-
- /**
- * Step 1-3 of message interpolation can be cached. We do this in this map.
- */
- private final Map<LocalisedMessage, String> resolvedMessages = new
WeakHashMap<LocalisedMessage, String>();
-
- public ResourceBundleMessageInterpolator() {
- this( ( ResourceBundleLocator ) null );
- }
-
- /**
- * @param resourceBundle the resource bundle to use
- *
- * @deprecated Use {@link
ResourceBundleMessageInterpolator#ResourceBundleMessageInterpolator(ResourceBundleLocator)}
instead.
- */
- @Deprecated
- public ResourceBundleMessageInterpolator(final ResourceBundle resourceBundle) {
- this(
- new PlatformResourceBundleLocator( Constants.USER_VALIDATION_MESSAGES ) {
- public ResourceBundle getResourceBundle(Locale locale) {
- return locale == Locale.getDefault() ? resourceBundle : super.getResourceBundle(
locale );
- }
- }
- );
- }
-
- public ResourceBundleMessageInterpolator(ResourceBundleLocator
userResourceBundleLocator) {
-
- defaultLocale = Locale.getDefault();
-
- if ( userResourceBundleLocator == null ) {
- userResourceBundleLocator = new PlatformResourceBundleLocator(
Constants.USER_VALIDATION_MESSAGES );
- }
-
- this.userResourceBundleLocator = new CachingResourceBundleLocator(
userResourceBundleLocator );
-
- this.defaultResourceBundleLocator =
- new CachingResourceBundleLocator(
- new PlatformResourceBundleLocator( Constants.DEFAULT_VALIDATION_MESSAGES )
- );
- }
-
- public String interpolate(String message, Context context) {
- // probably no need for caching, but it could be done by parameters since the map
- // is immutable and uniquely built per Validation definition, the comparison has to be
based on == and not equals though
- return interpolateMessage( message, context.getConstraintDescriptor().getAttributes(),
defaultLocale );
- }
-
- public String interpolate(String message, Context context, Locale locale) {
- return interpolateMessage( message, context.getConstraintDescriptor().getAttributes(),
locale );
- }
-
- /**
- * Runs the message interpolation according to algorithm specified in JSR 303.
- * <br/>
- * Note:
- * <br/>
- * Look-ups in user bundles is recursive whereas look-ups in default bundle are not!
- *
- * @param message the message to interpolate
- * @param annotationParameters the parameters of the annotation for which to interpolate
this message
- * @param locale the <code>Locale</code> to use for the resource bundle.
- *
- * @return the interpolated message.
- */
- private String interpolateMessage(String message, Map<String, Object>
annotationParameters, Locale locale) {
- LocalisedMessage localisedMessage = new LocalisedMessage( message, locale );
- String resolvedMessage = resolvedMessages.get( localisedMessage );
-
- // if the message is not already in the cache we have to run step 1-3 of the message
resolution
- if ( resolvedMessage == null ) {
- ResourceBundle userResourceBundle = userResourceBundleLocator
- .getResourceBundle( locale );
- ResourceBundle defaultResourceBundle = defaultResourceBundleLocator
- .getResourceBundle( locale );
-
- String userBundleResolvedMessage;
- resolvedMessage = message;
- boolean evaluatedDefaultBundleOnce = false;
- do {
- // search the user bundle recursive (step1)
- userBundleResolvedMessage = replaceVariables(
- resolvedMessage, userResourceBundle, locale, true
- );
-
- // exit condition - we have at least tried to validate against the default bundle and
there was no
- // further replacements
- if ( evaluatedDefaultBundleOnce
- && !hasReplacementTakenPlace( userBundleResolvedMessage, resolvedMessage )
) {
- break;
- }
-
- // search the default bundle non recursive (step2)
- resolvedMessage = replaceVariables( userBundleResolvedMessage, defaultResourceBundle,
locale, false );
- evaluatedDefaultBundleOnce = true;
- resolvedMessages.put( localisedMessage, resolvedMessage );
- } while ( true );
- }
-
- // resolve annotation attributes (step 4)
- resolvedMessage = replaceAnnotationAttributes( resolvedMessage, annotationParameters
);
-
- // last but not least we have to take care of escaped literals
- resolvedMessage = resolvedMessage.replace( "\\{", "{" );
- resolvedMessage = resolvedMessage.replace( "\\}", "}" );
- resolvedMessage = resolvedMessage.replace( "\\\\", "\\" );
- return resolvedMessage;
- }
-
- private boolean hasReplacementTakenPlace(String origMessage, String newMessage) {
- return !origMessage.equals( newMessage );
- }
-
- private String replaceVariables(String message, ResourceBundle bundle, Locale locale,
boolean recurse) {
- Matcher matcher = messageParameterPattern.matcher( message );
- StringBuffer sb = new StringBuffer();
- String resolvedParameterValue;
- while ( matcher.find() ) {
- String parameter = matcher.group( 1 );
- resolvedParameterValue = resolveParameter(
- parameter, bundle, locale, recurse
- );
-
- matcher.appendReplacement( sb, escapeMetaCharacters( resolvedParameterValue ) );
- }
- matcher.appendTail( sb );
- return sb.toString();
- }
-
- private String replaceAnnotationAttributes(String message, Map<String, Object>
annotationParameters) {
- Matcher matcher = messageParameterPattern.matcher( message );
- StringBuffer sb = new StringBuffer();
- while ( matcher.find() ) {
- String resolvedParameterValue;
- String parameter = matcher.group( 1 );
- Object variable = annotationParameters.get( removeCurlyBrace( parameter ) );
- if ( variable != null ) {
- resolvedParameterValue = escapeMetaCharacters( variable.toString() );
- }
- else {
- resolvedParameterValue = parameter;
- }
- matcher.appendReplacement( sb, resolvedParameterValue );
- }
- matcher.appendTail( sb );
- return sb.toString();
- }
-
- private String resolveParameter(String parameterName, ResourceBundle bundle, Locale
locale, boolean recurse) {
- String parameterValue;
- try {
- if ( bundle != null ) {
- parameterValue = bundle.getString( removeCurlyBrace( parameterName ) );
- if ( recurse ) {
- parameterValue = replaceVariables( parameterValue, bundle, locale, recurse );
- }
- }
- else {
- parameterValue = parameterName;
- }
- }
- catch ( MissingResourceException e ) {
- // return parameter itself
- parameterValue = parameterName;
- }
- return parameterValue;
- }
-
- private String removeCurlyBrace(String parameter) {
- return parameter.substring( 1, parameter.length() - 1 );
- }
-
- /**
- * @param s The string in which to replace the meta characters '$' and
'\'.
- *
- * @return A string where meta characters relevant for {@link Matcher#appendReplacement}
are escaped.
- */
- private String escapeMetaCharacters(String s) {
- String escapedString = s.replace( "\\", "\\\\" );
- escapedString = escapedString.replace( "$", "\\$" );
- return escapedString;
- }
-
- private static class LocalisedMessage {
- private final String message;
- private final Locale locale;
-
- LocalisedMessage(String message, Locale locale) {
- this.message = message;
- this.locale = locale;
- }
-
- @Override
- public boolean equals(Object o) {
- if ( this == o ) {
- return true;
- }
- if ( o == null || getClass() != o.getClass() ) {
- return false;
- }
-
- LocalisedMessage that = ( LocalisedMessage ) o;
-
- if ( locale != null ? !locale.equals( that.locale ) : that.locale != null ) {
- return false;
- }
- if ( message != null ? !message.equals( that.message ) : that.message != null ) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = message != null ? message.hashCode() : 0;
- result = 31 * result + ( locale != null ? locale.hashCode() : 0 );
- return result;
- }
- }
-}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -0,0 +1,291 @@
+// $Id: ResourceBundleMessageInterpolator.java 19081 2010-03-22 20:19:52Z
hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed 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.hibernate.validator.messageinterpolation;
+
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.WeakHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.validation.MessageInterpolator;
+
+import org.hibernate.validator.resourceloading.CachingResourceBundleLocator;
+import org.hibernate.validator.resourceloading.PlatformResourceBundleLocator;
+import org.hibernate.validator.resourceloading.ResourceBundleLocator;
+
+/**
+ * Resource bundle backed message interpolator.
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ * @author Gunnar Morling
+ */
+public class ResourceBundleMessageInterpolator implements MessageInterpolator {
+
+ /**
+ * The name of the default message bundle.
+ */
+ public static final String DEFAULT_VALIDATION_MESSAGES =
"org.hibernate.validator.ValidationMessages";
+
+ /**
+ * The name of the user-provided message bundle as defined in the specification.
+ */
+ public static final String USER_VALIDATION_MESSAGES = "ValidationMessages";
+
+ /**
+ * Regular expression used to do message interpolation.
+ */
+ private static final Pattern messageParameterPattern = Pattern.compile(
"(\\{[^\\}]+?\\})" );
+
+ /**
+ * The default locale for the current user.
+ */
+ private final Locale defaultLocale;
+
+ /**
+ * Loads user-specified resource bundles.
+ */
+ private final ResourceBundleLocator userResourceBundleLocator;
+
+ /**
+ * Loads built-in resource bundles.
+ */
+ private final ResourceBundleLocator defaultResourceBundleLocator;
+
+ /**
+ * Step 1-3 of message interpolation can be cached. We do this in this map.
+ */
+ private final Map<LocalisedMessage, String> resolvedMessages = new
WeakHashMap<LocalisedMessage, String>();
+
+ public ResourceBundleMessageInterpolator() {
+ this( ( ResourceBundleLocator ) null );
+ }
+
+ /**
+ * @param resourceBundle the resource bundle to use
+ *
+ * @deprecated Use {@link
ResourceBundleMessageInterpolator#ResourceBundleMessageInterpolator(ResourceBundleLocator)}
instead.
+ */
+ @Deprecated
+ public ResourceBundleMessageInterpolator(final ResourceBundle resourceBundle) {
+ this(
+ new PlatformResourceBundleLocator( USER_VALIDATION_MESSAGES ) {
+ public ResourceBundle getResourceBundle(Locale locale) {
+ return locale == Locale.getDefault() ? resourceBundle : super.getResourceBundle(
locale );
+ }
+ }
+ );
+ }
+
+ public ResourceBundleMessageInterpolator(ResourceBundleLocator
userResourceBundleLocator) {
+
+ defaultLocale = Locale.getDefault();
+
+ if ( userResourceBundleLocator == null ) {
+ userResourceBundleLocator = new PlatformResourceBundleLocator(
USER_VALIDATION_MESSAGES );
+ }
+
+ this.userResourceBundleLocator = new CachingResourceBundleLocator(
userResourceBundleLocator );
+
+ this.defaultResourceBundleLocator =
+ new CachingResourceBundleLocator(
+ new PlatformResourceBundleLocator( DEFAULT_VALIDATION_MESSAGES )
+ );
+ }
+
+ public String interpolate(String message, Context context) {
+ // probably no need for caching, but it could be done by parameters since the map
+ // is immutable and uniquely built per Validation definition, the comparison has to be
based on == and not equals though
+ return interpolateMessage( message, context.getConstraintDescriptor().getAttributes(),
defaultLocale );
+ }
+
+ public String interpolate(String message, Context context, Locale locale) {
+ return interpolateMessage( message, context.getConstraintDescriptor().getAttributes(),
locale );
+ }
+
+ /**
+ * Runs the message interpolation according to algorithm specified in JSR 303.
+ * <br/>
+ * Note:
+ * <br/>
+ * Look-ups in user bundles is recursive whereas look-ups in default bundle are not!
+ *
+ * @param message the message to interpolate
+ * @param annotationParameters the parameters of the annotation for which to interpolate
this message
+ * @param locale the <code>Locale</code> to use for the resource bundle.
+ *
+ * @return the interpolated message.
+ */
+ private String interpolateMessage(String message, Map<String, Object>
annotationParameters, Locale locale) {
+ LocalisedMessage localisedMessage = new LocalisedMessage( message, locale );
+ String resolvedMessage = resolvedMessages.get( localisedMessage );
+
+ // if the message is not already in the cache we have to run step 1-3 of the message
resolution
+ if ( resolvedMessage == null ) {
+ ResourceBundle userResourceBundle = userResourceBundleLocator
+ .getResourceBundle( locale );
+ ResourceBundle defaultResourceBundle = defaultResourceBundleLocator
+ .getResourceBundle( locale );
+
+ String userBundleResolvedMessage;
+ resolvedMessage = message;
+ boolean evaluatedDefaultBundleOnce = false;
+ do {
+ // search the user bundle recursive (step1)
+ userBundleResolvedMessage = replaceVariables(
+ resolvedMessage, userResourceBundle, locale, true
+ );
+
+ // exit condition - we have at least tried to validate against the default bundle and
there was no
+ // further replacements
+ if ( evaluatedDefaultBundleOnce
+ && !hasReplacementTakenPlace( userBundleResolvedMessage, resolvedMessage )
) {
+ break;
+ }
+
+ // search the default bundle non recursive (step2)
+ resolvedMessage = replaceVariables( userBundleResolvedMessage, defaultResourceBundle,
locale, false );
+ evaluatedDefaultBundleOnce = true;
+ resolvedMessages.put( localisedMessage, resolvedMessage );
+ } while ( true );
+ }
+
+ // resolve annotation attributes (step 4)
+ resolvedMessage = replaceAnnotationAttributes( resolvedMessage, annotationParameters
);
+
+ // last but not least we have to take care of escaped literals
+ resolvedMessage = resolvedMessage.replace( "\\{", "{" );
+ resolvedMessage = resolvedMessage.replace( "\\}", "}" );
+ resolvedMessage = resolvedMessage.replace( "\\\\", "\\" );
+ return resolvedMessage;
+ }
+
+ private boolean hasReplacementTakenPlace(String origMessage, String newMessage) {
+ return !origMessage.equals( newMessage );
+ }
+
+ private String replaceVariables(String message, ResourceBundle bundle, Locale locale,
boolean recurse) {
+ Matcher matcher = messageParameterPattern.matcher( message );
+ StringBuffer sb = new StringBuffer();
+ String resolvedParameterValue;
+ while ( matcher.find() ) {
+ String parameter = matcher.group( 1 );
+ resolvedParameterValue = resolveParameter(
+ parameter, bundle, locale, recurse
+ );
+
+ matcher.appendReplacement( sb, escapeMetaCharacters( resolvedParameterValue ) );
+ }
+ matcher.appendTail( sb );
+ return sb.toString();
+ }
+
+ private String replaceAnnotationAttributes(String message, Map<String, Object>
annotationParameters) {
+ Matcher matcher = messageParameterPattern.matcher( message );
+ StringBuffer sb = new StringBuffer();
+ while ( matcher.find() ) {
+ String resolvedParameterValue;
+ String parameter = matcher.group( 1 );
+ Object variable = annotationParameters.get( removeCurlyBrace( parameter ) );
+ if ( variable != null ) {
+ resolvedParameterValue = escapeMetaCharacters( variable.toString() );
+ }
+ else {
+ resolvedParameterValue = parameter;
+ }
+ matcher.appendReplacement( sb, resolvedParameterValue );
+ }
+ matcher.appendTail( sb );
+ return sb.toString();
+ }
+
+ private String resolveParameter(String parameterName, ResourceBundle bundle, Locale
locale, boolean recurse) {
+ String parameterValue;
+ try {
+ if ( bundle != null ) {
+ parameterValue = bundle.getString( removeCurlyBrace( parameterName ) );
+ if ( recurse ) {
+ parameterValue = replaceVariables( parameterValue, bundle, locale, recurse );
+ }
+ }
+ else {
+ parameterValue = parameterName;
+ }
+ }
+ catch ( MissingResourceException e ) {
+ // return parameter itself
+ parameterValue = parameterName;
+ }
+ return parameterValue;
+ }
+
+ private String removeCurlyBrace(String parameter) {
+ return parameter.substring( 1, parameter.length() - 1 );
+ }
+
+ /**
+ * @param s The string in which to replace the meta characters '$' and
'\'.
+ *
+ * @return A string where meta characters relevant for {@link Matcher#appendReplacement}
are escaped.
+ */
+ private String escapeMetaCharacters(String s) {
+ String escapedString = s.replace( "\\", "\\\\" );
+ escapedString = escapedString.replace( "$", "\\$" );
+ return escapedString;
+ }
+
+ private static class LocalisedMessage {
+ private final String message;
+ private final Locale locale;
+
+ LocalisedMessage(String message, Locale locale) {
+ this.message = message;
+ this.locale = locale;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+
+ LocalisedMessage that = ( LocalisedMessage ) o;
+
+ if ( locale != null ? !locale.equals( that.locale ) : that.locale != null ) {
+ return false;
+ }
+ if ( message != null ? !message.equals( that.message ) : that.message != null ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = message != null ? message.hashCode() : 0;
+ result = 31 * result + ( locale != null ? locale.hashCode() : 0 );
+ return result;
+ }
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/messageinterpolation/package.html
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/messageinterpolation/package.html
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/messageinterpolation/package.html 2010-04-28
14:33:12 UTC (rev 19314)
@@ -0,0 +1,45 @@
+<!--
+ ~ $Id:$
+ ~
+ ~ JBoss, Home of Professional Open Source
+ ~ Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual contributors
+ ~ by the @authors tag. See the copyright.txt in the distribution for a
+ ~ full listing of individual contributors.
+ ~
+ ~ Licensed 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.
+ -->
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+ <!--
+
+ JBoss, Home of Professional Open Source
+ Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual contributors
+ by the @authors tag. See the copyright.txt in the distribution for a
+ full listing of individual contributors.
+
+ Licensed 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.
+
+-->
+</head>
+<body>
+This package contains implementations of the MessageInterpolator interface.
+</body>
+</html>
Copied:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading
(from rev 19292,
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading)
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/AggregateResourceBundleLocator.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocator.java 2010-04-26
02:06:03 UTC (rev 19292)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/AggregateResourceBundleLocator.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.hibernate.validator.engine.resourceloading;
+package org.hibernate.validator.resourceloading;
import java.util.ArrayList;
import java.util.Collections;
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/CachingResourceBundleLocator.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/CachingResourceBundleLocator.java 2010-04-26
02:06:03 UTC (rev 19292)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/CachingResourceBundleLocator.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.hibernate.validator.engine.resourceloading;
+package org.hibernate.validator.resourceloading;
import java.util.Locale;
import java.util.ResourceBundle;
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/DelegatingResourceBundleLocator.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/DelegatingResourceBundleLocator.java 2010-04-26
02:06:03 UTC (rev 19292)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/DelegatingResourceBundleLocator.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.hibernate.validator.engine.resourceloading;
+package org.hibernate.validator.resourceloading;
import java.util.Locale;
import java.util.ResourceBundle;
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/PlatformResourceBundleLocator.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/PlatformResourceBundleLocator.java 2010-04-26
02:06:03 UTC (rev 19292)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/PlatformResourceBundleLocator.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.hibernate.validator.engine.resourceloading;
+package org.hibernate.validator.resourceloading;
import java.security.AccessController;
import java.util.Locale;
@@ -24,7 +24,6 @@
import org.slf4j.Logger;
-import org.hibernate.validator.engine.ResourceBundleMessageInterpolator;
import org.hibernate.validator.util.GetClassLoader;
import org.hibernate.validator.util.LoggerFactory;
@@ -67,7 +66,7 @@
}
if ( rb == null ) {
action = GetClassLoader
- .fromClass( ResourceBundleMessageInterpolator.class );
+ .fromClass( PlatformResourceBundleLocator.class );
classLoader = isSecured ? AccessController.doPrivileged( action )
: action.run();
rb = loadBundle(
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/ResourceBundleLocator.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/ResourceBundleLocator.java 2010-04-26
02:06:03 UTC (rev 19292)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/resourceloading/ResourceBundleLocator.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -15,16 +15,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.hibernate.validator.engine.resourceloading;
+package org.hibernate.validator.resourceloading;
import java.util.Locale;
import java.util.ResourceBundle;
-import org.hibernate.validator.engine.ResourceBundleMessageInterpolator;
-
/**
* <p>
- * Used by {@link ResourceBundleMessageInterpolator} to load resource bundles
+ * Used by {@link
org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator} to load
resource bundles
* containing message texts to be displayed in case of validation errors.
* </p>
* <p>
Modified:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/HibernateValidatorConfigurationTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/HibernateValidatorConfigurationTest.java 2010-04-28
11:05:26 UTC (rev 19313)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/HibernateValidatorConfigurationTest.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -1,5 +1,5 @@
/*
- * $Id:$
+ * $Id$
*
* JBoss, Home of Professional Open Source
* Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual contributors
@@ -22,7 +22,7 @@
import org.testng.annotations.Test;
-import org.hibernate.validator.engine.resourceloading.ResourceBundleLocator;
+import org.hibernate.validator.resourceloading.ResourceBundleLocator;
import static org.testng.Assert.assertNotNull;
Modified:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/messageinterpolation/MessageInterpolationTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/messageinterpolation/MessageInterpolationTest.java 2010-04-28
11:05:26 UTC (rev 19313)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/messageinterpolation/MessageInterpolationTest.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -32,8 +32,8 @@
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
-import org.hibernate.validator.engine.ResourceBundleMessageInterpolator;
-import org.hibernate.validator.engine.resourceloading.ResourceBundleLocator;
+import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
+import org.hibernate.validator.resourceloading.ResourceBundleLocator;
import static org.testng.Assert.assertEquals;
Modified:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/messageinterpolation/MessageInterpolationWithDefaultBundleTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/messageinterpolation/MessageInterpolationWithDefaultBundleTest.java 2010-04-28
11:05:26 UTC (rev 19313)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/messageinterpolation/MessageInterpolationWithDefaultBundleTest.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -27,7 +27,7 @@
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
-import org.hibernate.validator.engine.ResourceBundleMessageInterpolator;
+import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
import org.hibernate.validator.util.TestUtil;
import static
org.hibernate.validator.util.TestUtil.assertCorrectConstraintViolationMessages;
Modified:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java 2010-04-28
11:05:26 UTC (rev 19313)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -33,8 +33,8 @@
import org.testng.annotations.Test;
import org.hibernate.validator.engine.MessageInterpolatorContext;
-import org.hibernate.validator.engine.ResourceBundleMessageInterpolator;
-import org.hibernate.validator.engine.resourceloading.ResourceBundleLocator;
+import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
+import org.hibernate.validator.resourceloading.ResourceBundleLocator;
import org.hibernate.validator.metadata.ConstraintDescriptorImpl;
import org.hibernate.validator.metadata.ConstraintHelper;
import org.hibernate.validator.metadata.ConstraintOrigin;
Copied:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/resourceloading
(from rev 19292,
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading)
Modified:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/resourceloading/AggregateBundleTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateBundleTest.java 2010-04-26
02:06:03 UTC (rev 19292)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/resourceloading/AggregateBundleTest.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.hibernate.validator.engine.resourceloading;
+package org.hibernate.validator.resourceloading;
import java.util.Arrays;
import java.util.Collections;
@@ -26,7 +26,7 @@
import org.testng.annotations.Test;
-import
org.hibernate.validator.engine.resourceloading.AggregateResourceBundleLocator.AggregateBundle;
+import
org.hibernate.validator.resourceloading.AggregateResourceBundleLocator.AggregateBundle;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
Modified:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/resourceloading/AggregateResourceBundleLocatorTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocatorTest.java 2010-04-26
02:06:03 UTC (rev 19292)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/resourceloading/AggregateResourceBundleLocatorTest.java 2010-04-28
14:33:12 UTC (rev 19314)
@@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.hibernate.validator.engine.resourceloading;
+package org.hibernate.validator.resourceloading;
import java.util.Arrays;
import java.util.Locale;
Modified: validator/trunk/hibernate-validator/src/test/resources/log4j.properties
===================================================================
--- validator/trunk/hibernate-validator/src/test/resources/log4j.properties 2010-04-28
11:05:26 UTC (rev 19313)
+++ validator/trunk/hibernate-validator/src/test/resources/log4j.properties 2010-04-28
14:33:12 UTC (rev 19314)
@@ -22,4 +22,4 @@
log4j.logger.org.hibernate.validator.engine.ValidatorImpl=trace
#log4j.logger.org.hibernate.validatorengine.ConstraintTree=trace
-log4j.logger.org.hibernate.validator.engine.ResourceBundleMessageInterpolator=info
+log4j.logger.org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator=info