[hibernate-commits] Hibernate SVN: r19034 - in validator/trunk/hibernate-validator/src: main/java/org/hibernate/validator/engine and 6 other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Sun Mar 21 18:08:11 EDT 2010
Author: hardy.ferentschik
Date: 2010-03-21 18:08:06 -0400 (Sun, 21 Mar 2010)
New Revision: 19034
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/Constants.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/CachingResourceBundleLocator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/DelegatingResourceBundleLocator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/PlatformResourceBundleLocator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/ResourceBundleLocator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/package.html
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/IteratorEnumeration.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/HibernateValidatorConfigurationTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateBundleTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocatorTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocatorTestBundle1.properties
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocatorTestBundle2.properties
Modified:
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/ResourceBundleMessageInterpolator.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/ResourceBundleMessageInterpolatorTest.java
Log:
HV-238 Commited Gunnar's patch for this issue. Just made some formatting changes.
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-03-19 21:27:15 UTC (rev 19033)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -19,11 +19,48 @@
import javax.validation.Configuration;
+import org.hibernate.validator.engine.ResourceBundleMessageInterpolator;
+import org.hibernate.validator.engine.resourceloading.ResourceBundleLocator;
+
/**
- * Uniquely identify Hibernate Validator in the Bean Validation bootstrap strategy
- * Also contains Hibernate Validator specific configurations
- *
+ * Uniquely identifies Hibernate Validator in the Bean Validation bootstrap
+ * strategy. Also contains Hibernate Validator specific configurations.
+ *
* @author Emmanuel Bernard
+ * @author Gunnar Morling
*/
public interface HibernateValidatorConfiguration extends Configuration<HibernateValidatorConfiguration> {
+
+ /**
+ * <p>
+ * Returns the {@link ResourceBundleLocator} used by the
+ * {@link Configuration#getDefaultMessageInterpolator() default message
+ * interpolator} to load user-provided resource bundles. In conformance with
+ * the specification this default locator retrieves the bundle
+ * "ValidationMessages".
+ * </p>
+ * <p>
+ * This locator can be used as delegate for custom locators when setting a
+ * customized {@link ResourceBundleMessageInterpolator}:
+ * </p>
+ * <p/>
+ * <pre>
+ * {@code
+ * HibernateValidatorConfiguration configure =
+ * Validation.byProvider(HibernateValidator.class).configure();
+ * <p/>
+ * ResourceBundleLocator defaultResourceBundleLocator =
+ * configure.getDefaultResourceBundleLocator();
+ * ResourceBundleLocator myResourceBundleLocator =
+ * new MyResourceBundleLocator(defaultResourceBundleLocator);
+ * <p/>
+ * configure.messageInterpolator(
+ * new ResourceBundleMessageInterpolator(myResourceBundleLocator));
+ * }
+ * </pre>
+ *
+ * @return The default {@link ResourceBundleLocator}. Never null.
+ */
+ ResourceBundleLocator getDefaultResourceBundleLocator();
+
}
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-03-19 21:27:15 UTC (rev 19033)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConfigurationImpl.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -1,7 +1,7 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
-* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
+* 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.
*
@@ -33,18 +33,21 @@
import org.slf4j.Logger;
+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.util.LoggerFactory;
import org.hibernate.validator.util.Version;
import org.hibernate.validator.xml.ValidationBootstrapParameters;
import org.hibernate.validator.xml.ValidationXmlParser;
-import org.hibernate.validator.HibernateValidatorConfiguration;
/**
* Hibernate specific <code>Configuration</code> implementation.
*
* @author Emmanuel Bernard
* @author Hardy Ferentschik
+ * @author Gunnar Morling
*/
public class ConfigurationImpl implements HibernateValidatorConfiguration, ConfigurationState {
@@ -54,7 +57,10 @@
private static final Logger log = LoggerFactory.make();
- private final MessageInterpolator defaultMessageInterpolator = new ResourceBundleMessageInterpolator();
+ private final ResourceBundleLocator defaultResourceBundleLocator = new PlatformResourceBundleLocator( Constants.USER_VALIDATION_MESSAGES );
+ private final MessageInterpolator defaultMessageInterpolator = new ResourceBundleMessageInterpolator(
+ defaultResourceBundleLocator
+ );
private final TraversableResolver defaultTraversableResolver = new DefaultTraversableResolver();
private final ConstraintValidatorFactory defaultConstraintValidatorFactory = new ConstraintValidatorFactoryImpl();
private final ValidationProviderResolver providerResolver;
@@ -180,6 +186,10 @@
return defaultConstraintValidatorFactory;
}
+ public ResourceBundleLocator getDefaultResourceBundleLocator() {
+ return defaultResourceBundleLocator;
+ }
+
private boolean isSpecificProvider() {
return validationBootstrapParameters.provider != null;
}
Added: 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 (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/Constants.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -0,0 +1,40 @@
+/*
+ * $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/ResourceBundleMessageInterpolator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ResourceBundleMessageInterpolator.java 2010-03-19 21:27:15 UTC (rev 19033)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ResourceBundleMessageInterpolator.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -17,32 +17,27 @@
*/
package org.hibernate.validator.engine;
-import java.security.AccessController;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.WeakHashMap;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.validation.MessageInterpolator;
-import org.slf4j.Logger;
+import org.hibernate.validator.engine.resourceloading.CachingResourceBundleLocator;
+import org.hibernate.validator.engine.resourceloading.PlatformResourceBundleLocator;
+import org.hibernate.validator.engine.resourceloading.ResourceBundleLocator;
-import org.hibernate.validator.util.GetClassLoader;
-import org.hibernate.validator.util.LoggerFactory;
-
/**
* Resource bundle backed message interpolator.
*
* @author Emmanuel Bernard
* @author Hardy Ferentschik
+ * @author Gunnar Morling
*/
public class ResourceBundleMessageInterpolator implements MessageInterpolator {
- private static final String DEFAULT_VALIDATION_MESSAGES = "org.hibernate.validator.ValidationMessages";
- private static final String USER_VALIDATION_MESSAGES = "ValidationMessages";
- private static final Logger log = LoggerFactory.make();
/**
* Regular expression used to do message interpolation.
@@ -55,14 +50,14 @@
private final Locale defaultLocale;
/**
- * User specified resource bundles hashed against their locale.
+ * Loads user-specified resource bundles.
*/
- private final Map<Locale, ResourceBundle> userBundlesMap = new ConcurrentHashMap<Locale, ResourceBundle>();
+ private final ResourceBundleLocator userResourceBundleLocator;
/**
- * Built-in resource bundles hashed against there locale.
+ * Loads built-in resource bundles.
*/
- private final Map<Locale, ResourceBundle> defaultBundlesMap = new ConcurrentHashMap<Locale, ResourceBundle>();
+ private final ResourceBundleLocator defaultResourceBundleLocator;
/**
* Step 1-3 of message interpolation can be cached. We do this in this map.
@@ -70,25 +65,40 @@
private final Map<LocalisedMessage, String> resolvedMessages = new WeakHashMap<LocalisedMessage, String>();
public ResourceBundleMessageInterpolator() {
- this( null );
+ this( ( ResourceBundleLocator ) null );
}
- public ResourceBundleMessageInterpolator(ResourceBundle resourceBundle) {
+ /**
+ * @param resourceBundle the resource bundle to use
+ *
+ * @deprecated Use {@link ResourceBundleMessageInterpolator#ResourceBundleMessageInterpolator(ResourceBundleLocator)} instead.
+ */
+ // TODO GM: Do we still need this? It was only used in tests, but there might be 3rd party code using it.
+ @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 ( resourceBundle == null ) {
- ResourceBundle bundle = getFileBasedResourceBundle( defaultLocale );
- if ( bundle != null ) {
- userBundlesMap.put( defaultLocale, bundle );
- }
-
+ if ( userResourceBundleLocator == null ) {
+ userResourceBundleLocator = new PlatformResourceBundleLocator( Constants.USER_VALIDATION_MESSAGES );
}
- else {
- userBundlesMap.put( defaultLocale, resourceBundle );
- }
- defaultBundlesMap.put( defaultLocale, ResourceBundle.getBundle( DEFAULT_VALIDATION_MESSAGES, defaultLocale ) );
+ this.userResourceBundleLocator = new CachingResourceBundleLocator( userResourceBundleLocator );
+
+ this.defaultResourceBundleLocator =
+ new CachingResourceBundleLocator(
+ new PlatformResourceBundleLocator( Constants.DEFAULT_VALIDATION_MESSAGES )
+ );
}
public String interpolate(String message, Context context) {
@@ -120,8 +130,10 @@
// 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 = findUserResourceBundle( locale );
- ResourceBundle defaultResourceBundle = findDefaultResourceBundle( locale );
+ ResourceBundle userResourceBundle = userResourceBundleLocator
+ .getResourceBundle( locale );
+ ResourceBundle defaultResourceBundle = defaultResourceBundleLocator
+ .getResourceBundle( locale );
String userBundleResolvedMessage;
resolvedMessage = message;
@@ -160,53 +172,6 @@
return !origMessage.equals( newMessage );
}
- /**
- * Search current thread classloader for the resource bundle. If not found, search validator (this) classloader.
- *
- * @param locale The locale of the bundle to load.
- *
- * @return the resource bundle or <code>null</code> if none is found.
- */
- private ResourceBundle getFileBasedResourceBundle(Locale locale) {
- ResourceBundle rb = null;
- boolean isSecured = System.getSecurityManager() != null;
- GetClassLoader action = GetClassLoader.fromContext();
- ClassLoader classLoader = isSecured ? AccessController.doPrivileged( action ) : action.run();
-
- if ( classLoader != null ) {
- rb = loadBundle( classLoader, locale, USER_VALIDATION_MESSAGES + " not found by thread local classloader" );
- }
- if ( rb == null ) {
- action = GetClassLoader.fromClass( ResourceBundleMessageInterpolator.class );
- classLoader = isSecured ? AccessController.doPrivileged( action ) : action.run();
- rb = loadBundle(
- classLoader,
- locale,
- USER_VALIDATION_MESSAGES + " not found by validator classloader"
- );
- }
- if ( log.isDebugEnabled() ) {
- if ( rb != null ) {
- log.debug( USER_VALIDATION_MESSAGES + " found" );
- }
- else {
- log.debug( USER_VALIDATION_MESSAGES + " not found. Delegating to " + DEFAULT_VALIDATION_MESSAGES );
- }
- }
- return rb;
- }
-
- private ResourceBundle loadBundle(ClassLoader classLoader, Locale locale, String message) {
- ResourceBundle rb = null;
- try {
- rb = ResourceBundle.getBundle( USER_VALIDATION_MESSAGES, locale, classLoader );
- }
- catch ( MissingResourceException e ) {
- log.trace( message );
- }
- return rb;
- }
-
private String replaceVariables(String message, ResourceBundle bundle, Locale locale, boolean recurse) {
Matcher matcher = messageParameterPattern.matcher( message );
StringBuffer sb = new StringBuffer();
@@ -266,28 +231,6 @@
return parameter.substring( 1, parameter.length() - 1 );
}
- private ResourceBundle findDefaultResourceBundle(Locale locale) {
- if ( defaultBundlesMap.containsKey( locale ) ) {
- return defaultBundlesMap.get( locale );
- }
-
- ResourceBundle bundle = ResourceBundle.getBundle( DEFAULT_VALIDATION_MESSAGES, locale );
- defaultBundlesMap.put( locale, bundle );
- return bundle;
- }
-
- private ResourceBundle findUserResourceBundle(Locale locale) {
- if ( userBundlesMap.containsKey( locale ) ) {
- return userBundlesMap.get( locale );
- }
-
- ResourceBundle bundle = getFileBasedResourceBundle( locale );
- if ( bundle != null ) {
- userBundlesMap.put( locale, bundle );
- }
- return bundle;
- }
-
/**
* @param s The string in which to replace the meta characters '$' and '\'.
*
@@ -308,14 +251,6 @@
this.locale = locale;
}
- public String getMessage() {
- return message;
- }
-
- public Locale getLocale() {
- return locale;
- }
-
@Override
public boolean equals(Object o) {
if ( this == o ) {
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocator.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocator.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -0,0 +1,147 @@
+// $Id: AggregateResourceBundleLocator.java 17620 2009-10-04 19:19:28Z hardy.ferentschik $
+/*
+* 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.resourceloading;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import org.hibernate.validator.util.IteratorEnumeration;
+
+/**
+ * A {@link ResourceBundleLocator} implementation that provides access
+ * to multiple source {@link ResourceBundle}s by merging them into one
+ * aggregated bundle.
+ *
+ * @author Gunnar Morling
+ */
+public class AggregateResourceBundleLocator extends DelegatingResourceBundleLocator {
+
+ private final List<String> bundleNames;
+
+ /**
+ * Creates a locator that delivers a resource bundle merged from the given
+ * list of source bundles.
+ *
+ * @param bundleNames A list with source bundle names. The returned bundle will
+ * contain all entries from all source bundles. In case a key occurs
+ * in multiple source bundles, the value will be taken from the
+ * first bundle containing the key.
+ */
+ public AggregateResourceBundleLocator(List<String> bundleNames) {
+ this( bundleNames, null );
+ }
+
+ /**
+ * Creates a locator that delivers a resource bundle merged from the given
+ * list of source bundles.
+ *
+ * @param bundleNames A list with source bundle names. The returned bundle will
+ * contain all keys from all source bundles. In case a key occurs
+ * in multiple source bundles, the value will be taken from the
+ * first bundle containing the key.
+ * @param delegate A delegate resource bundle locator. The bundle returned by
+ * this locator will be added to the aggregate bundle after all
+ * source bundles.
+ */
+ public AggregateResourceBundleLocator(List<String> bundleNames, ResourceBundleLocator delegate) {
+ super( delegate );
+
+ if ( bundleNames == null ) {
+ throw new IllegalArgumentException( "bundleNames must not be null." );
+ }
+
+ List<String> tmpBundleNames = new ArrayList<String>();
+ tmpBundleNames.addAll( bundleNames );
+
+ this.bundleNames = Collections.unmodifiableList( tmpBundleNames );
+ }
+
+ public ResourceBundle getResourceBundle(Locale locale) {
+ List<ResourceBundle> sourceBundles = new ArrayList<ResourceBundle>();
+
+ for ( String oneBundleName : bundleNames ) {
+ ResourceBundleLocator oneLocator =
+ new PlatformResourceBundleLocator( oneBundleName );
+
+ ResourceBundle oneBundle = oneLocator.getResourceBundle( locale );
+
+ if ( oneBundle != null ) {
+ sourceBundles.add( oneBundle );
+ }
+ }
+
+ ResourceBundle bundleFromDelegate = super.getResourceBundle( locale );
+
+ if ( bundleFromDelegate != null ) {
+ sourceBundles.add( bundleFromDelegate );
+ }
+
+ return sourceBundles.isEmpty() ? null : new AggregateBundle( sourceBundles );
+ }
+
+ /**
+ * A {@link ResourceBundle} which's content is aggregated from multiple source bundles.
+ * <p/>
+ * This class is package-private for the sake of testability.
+ *
+ * @author Gunnar Morling
+ */
+ static class AggregateBundle extends ResourceBundle {
+ private Map<String, Object> contents = new HashMap<String, Object>();
+
+ /**
+ * Creates a new AggregateBundle.
+ *
+ * @param bundles A list of source bundles, which shall be merged into one
+ * aggregated bundle. The newly created bundle will contain
+ * all keys from all source bundles. In case a key occurs in
+ * multiple source bundles, the value will be taken from the
+ * first bundle containing the key.
+ */
+ public AggregateBundle(List<ResourceBundle> bundles) {
+ if ( bundles != null ) {
+
+ for ( ResourceBundle bundle : bundles ) {
+ Enumeration<String> keys = bundle.getKeys();
+ while ( keys.hasMoreElements() ) {
+ String oneKey = keys.nextElement();
+ if ( !contents.containsKey( oneKey ) ) {
+ contents.put( oneKey, bundle.getObject( oneKey ) );
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public Enumeration<String> getKeys() {
+ return new IteratorEnumeration<String>( contents.keySet().iterator() );
+ }
+
+ @Override
+ protected Object handleGetObject(String key) {
+ return contents.get( key );
+ }
+ }
+}
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/CachingResourceBundleLocator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/CachingResourceBundleLocator.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/CachingResourceBundleLocator.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -0,0 +1,56 @@
+// $Id: CachingResourceBundleLocator.java 17620 2009-10-04 19:19:28Z hardy.ferentschik $
+/*
+* 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.resourceloading;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * A {@link ResourceBundleLocator} implementation that wraps around another
+ * locator and caches values retrieved from that locator.
+ *
+ * @author Gunnar Morling
+ */
+public class CachingResourceBundleLocator extends DelegatingResourceBundleLocator {
+
+ private final ConcurrentMap<Locale, ResourceBundle> bundleCache = new ConcurrentHashMap<Locale, ResourceBundle>();
+
+ /**
+ * Creates a new CachingResourceBundleLocator.
+ *
+ * @param delegate The locator from which the values actually will be retrieved.
+ */
+ public CachingResourceBundleLocator(ResourceBundleLocator delegate) {
+ super( delegate );
+ }
+
+ public ResourceBundle getResourceBundle(Locale locale) {
+
+ if ( bundleCache.containsKey( locale ) ) {
+ return bundleCache.get( locale );
+ }
+
+ ResourceBundle bundle = super.getResourceBundle( locale );
+ if ( bundle != null ) {
+ bundleCache.put( locale, bundle );
+ }
+ return bundle;
+ }
+}
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/DelegatingResourceBundleLocator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/DelegatingResourceBundleLocator.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/DelegatingResourceBundleLocator.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -0,0 +1,41 @@
+// $Id: DelegatingResourceBundleLocator.java 17620 2009-10-04 19:19:28Z 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.engine.resourceloading;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+/**
+ * Abstract base for all {@link ResourceBundleLocator} implementations, that
+ * wish to delegate to some other locator.
+ *
+ * @author Gunnar Morling
+ */
+public abstract class DelegatingResourceBundleLocator implements ResourceBundleLocator {
+
+ private final ResourceBundleLocator delegate;
+
+ public DelegatingResourceBundleLocator(ResourceBundleLocator delegate) {
+ this.delegate = delegate;
+ }
+
+ public ResourceBundle getResourceBundle(Locale locale) {
+ return delegate == null ? null : delegate.getResourceBundle( locale );
+ }
+
+}
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/PlatformResourceBundleLocator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/PlatformResourceBundleLocator.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/PlatformResourceBundleLocator.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -0,0 +1,102 @@
+// $Id: PlatformResourceBundleLocator.java 17620 2009-10-04 19:19:28Z 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.engine.resourceloading;
+
+import java.security.AccessController;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.slf4j.Logger;
+
+import org.hibernate.validator.engine.ResourceBundleMessageInterpolator;
+import org.hibernate.validator.util.GetClassLoader;
+import org.hibernate.validator.util.LoggerFactory;
+
+/**
+ * A resource bundle locator, that loads resource bundles by simply
+ * invoking <code>ResourceBundle.loadBundle(...)</code>.
+ *
+ * @author Hardy Ferentschik
+ * @author Gunnar Morling
+ */
+public class PlatformResourceBundleLocator implements ResourceBundleLocator {
+
+ private static final Logger log = LoggerFactory.make();
+ private String bundleName;
+
+ public PlatformResourceBundleLocator(String bundleName) {
+ this.bundleName = bundleName;
+ }
+
+ /**
+ * Search current thread classloader for the resource bundle. If not found,
+ * search validator (this) classloader.
+ *
+ * @param locale The locale of the bundle to load.
+ *
+ * @return the resource bundle or <code>null</code> if none is found.
+ */
+ public ResourceBundle getResourceBundle(Locale locale) {
+ ResourceBundle rb = null;
+ boolean isSecured = System.getSecurityManager() != null;
+ GetClassLoader action = GetClassLoader.fromContext();
+ ClassLoader classLoader = isSecured ? AccessController
+ .doPrivileged( action ) : action.run();
+
+ if ( classLoader != null ) {
+ rb = loadBundle(
+ classLoader, locale, bundleName
+ + " not found by thread local classloader"
+ );
+ }
+ if ( rb == null ) {
+ action = GetClassLoader
+ .fromClass( ResourceBundleMessageInterpolator.class );
+ classLoader = isSecured ? AccessController.doPrivileged( action )
+ : action.run();
+ rb = loadBundle(
+ classLoader, locale, bundleName
+ + " not found by validator classloader"
+ );
+ }
+ if ( log.isDebugEnabled() ) {
+ if ( rb != null ) {
+ log.debug( bundleName + " found" );
+ }
+ else {
+ log.debug( bundleName + " not found." );
+ }
+ }
+ return rb;
+ }
+
+ private ResourceBundle loadBundle(ClassLoader classLoader, Locale locale, String message) {
+ ResourceBundle rb = null;
+ try {
+ rb = ResourceBundle.getBundle(
+ bundleName, locale,
+ classLoader
+ );
+ }
+ catch ( MissingResourceException e ) {
+ log.trace( message );
+ }
+ return rb;
+ }
+}
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/ResourceBundleLocator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/ResourceBundleLocator.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/ResourceBundleLocator.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -0,0 +1,54 @@
+// $Id: ResourceBundleLocator.java 17620 2009-10-04 19:19:28Z 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.engine.resourceloading;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import org.hibernate.validator.engine.ResourceBundleMessageInterpolator;
+
+/**
+ * <p>
+ * Used by {@link ResourceBundleMessageInterpolator} to load resource bundles
+ * containing message texts to be displayed in case of validation errors.
+ * </p>
+ * <p>
+ * The default implementation provides access to the bundle "ValidationMessages"
+ * as described in the BV specification. By providing additional implementations
+ * of this interface, alternative ways of bundle loading can be realized, e.g.
+ * by loading bundles based on XML files or from a database.
+ * </p>
+ * <p/>
+ * TODO GM: Note, that all implementations must be thread-safe?
+ *
+ * @author Gunnar Morling
+ */
+public interface ResourceBundleLocator {
+
+ /**
+ * Returns a resource bundle for the given locale.
+ *
+ * @param locale A locale, for which a resource bundle shall be retrieved. Must
+ * not be null.
+ *
+ * @return A resource bundle for the given locale. May be null, if no such
+ * bundle exists.
+ */
+ ResourceBundle getResourceBundle(Locale locale);
+
+}
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/package.html
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/package.html (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/resourceloading/package.html 2010-03-21 22:08:06 UTC (rev 19034)
@@ -0,0 +1,26 @@
+<!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 the ResourceBundleLocator interface and different implementations.
+</body>
+</html>
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/IteratorEnumeration.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/IteratorEnumeration.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/IteratorEnumeration.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -0,0 +1,56 @@
+/*
+ * $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.util;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+
+/**
+ * An {@link Enumeration} implementation, that wraps an {@link Iterator}. Can
+ * be used to integrate older APIs working with enumerations with iterators.
+ *
+ * @author Gunnar Morling
+ * @param <T> The enumerated type.
+ */
+public class IteratorEnumeration<T> implements Enumeration<T> {
+
+ private Iterator<T> source;
+
+ /**
+ * Creates a new IterationEnumeration.
+ *
+ * @param source The source iterator. Must not be null.
+ */
+ public IteratorEnumeration(Iterator<T> source) {
+
+ if ( source == null ) {
+ throw new IllegalArgumentException( "Source must not be null" );
+ }
+
+ this.source = source;
+ }
+
+ public boolean hasMoreElements() {
+ return source.hasNext();
+ }
+
+ public T nextElement() {
+ return source.next();
+ }
+}
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/HibernateValidatorConfigurationTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/HibernateValidatorConfigurationTest.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/HibernateValidatorConfigurationTest.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -0,0 +1,43 @@
+/*
+ * $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;
+
+import javax.validation.Validation;
+
+import org.testng.annotations.Test;
+
+import org.hibernate.validator.engine.resourceloading.ResourceBundleLocator;
+
+import static org.testng.Assert.assertNotNull;
+
+/**
+ * Test for {@link HibernateValidatorConfiguration}.
+ *
+ * @author Gunnar Morling
+ */
+public class HibernateValidatorConfigurationTest {
+
+ @Test
+ public void defaultResourceBundleLocatorCanBeRetrieved() {
+ HibernateValidatorConfiguration configure = Validation.byProvider( HibernateValidator.class ).configure();
+ ResourceBundleLocator defaultResourceBundleLocator = configure.getDefaultResourceBundleLocator();
+
+ assertNotNull( defaultResourceBundleLocator );
+ }
+}
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-03-19 21:27:15 UTC (rev 19033)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/messageinterpolation/MessageInterpolationTest.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -18,6 +18,7 @@
package org.hibernate.validator.engine.messageinterpolation;
import java.io.ByteArrayInputStream;
+import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import javax.validation.Configuration;
@@ -28,12 +29,14 @@
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
-import static org.testng.Assert.assertEquals;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.hibernate.validator.engine.ResourceBundleMessageInterpolator;
+import org.hibernate.validator.engine.resourceloading.ResourceBundleLocator;
+import static org.testng.Assert.assertEquals;
+
/**
* Tests for HV-184
*
@@ -52,10 +55,19 @@
final ResourceBundle bundle = new PropertyResourceBundle(
new ByteArrayInputStream( lines.toString().getBytes() )
);
- Configuration<?> config = ( Configuration<?> ) Validation.byDefaultProvider()
+ Configuration<?> config = Validation.byDefaultProvider()
.configure()
.messageInterpolator(
- new ResourceBundleMessageInterpolator( bundle )
+ new ResourceBundleMessageInterpolator(
+ new ResourceBundleLocator() {
+
+ public ResourceBundle getResourceBundle(
+ Locale locale) {
+ return bundle;
+ }
+
+ }
+ )
);
ValidatorFactory factory = config.buildValidatorFactory();
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-03-19 21:27:15 UTC (rev 19033)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -29,18 +29,20 @@
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
-import static org.testng.Assert.assertEquals;
import org.testng.annotations.BeforeTest;
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.metadata.ConstraintDescriptorImpl;
import org.hibernate.validator.metadata.ConstraintHelper;
import org.hibernate.validator.metadata.ConstraintOrigin;
import org.hibernate.validator.util.annotationfactory.AnnotationDescriptor;
import org.hibernate.validator.util.annotationfactory.AnnotationFactory;
+import static org.testng.Assert.assertEquals;
+
/**
* Tests for message interpolation.
*
@@ -75,7 +77,9 @@
@Test
public void testSuccessfulInterpolation() {
- interpolator = new ResourceBundleMessageInterpolator( new TestResourceBundle() );
+ interpolator = new ResourceBundleMessageInterpolator(
+ new TestResourceBundleLocator()
+ );
MessageInterpolator.Context context = new MessageInterpolatorContext( notNullDescriptor, null );
String expected = "message interpolation successful";
String actual = interpolator.interpolate( "{simple.key}", context );
@@ -97,7 +101,9 @@
@Test
public void testMessageLiterals() {
- interpolator = new ResourceBundleMessageInterpolator( new TestResourceBundle() );
+ interpolator = new ResourceBundleMessageInterpolator(
+ new TestResourceBundleLocator()
+ );
MessageInterpolator.Context context = new MessageInterpolatorContext( notNullDescriptor, null );
String expected = "{";
@@ -115,7 +121,9 @@
@Test
public void testUnSuccessfulInterpolation() {
- interpolator = new ResourceBundleMessageInterpolator( new TestResourceBundle() );
+ interpolator = new ResourceBundleMessageInterpolator(
+ new TestResourceBundleLocator()
+ );
MessageInterpolator.Context context = new MessageInterpolatorContext( notNullDescriptor, null );
String expected = "foo"; // missing {}
@@ -129,7 +137,9 @@
@Test
public void testUnknownTokenInterpolation() {
- interpolator = new ResourceBundleMessageInterpolator( new TestResourceBundle() );
+ interpolator = new ResourceBundleMessageInterpolator(
+ new TestResourceBundleLocator()
+ );
MessageInterpolator.Context context = new MessageInterpolatorContext( notNullDescriptor, null );
String expected = "{bar}"; // unknown token {}
@@ -139,7 +149,9 @@
@Test
public void testKeyWithDashes() {
- interpolator = new ResourceBundleMessageInterpolator( new TestResourceBundle() );
+ interpolator = new ResourceBundleMessageInterpolator(
+ new TestResourceBundleLocator()
+ );
MessageInterpolator.Context context = new MessageInterpolatorContext( notNullDescriptor, null );
String expected = "message interpolation successful"; // unknown token {}
@@ -149,7 +161,9 @@
@Test
public void testKeyWithSpaces() {
- interpolator = new ResourceBundleMessageInterpolator( new TestResourceBundle() );
+ interpolator = new ResourceBundleMessageInterpolator(
+ new TestResourceBundleLocator()
+ );
MessageInterpolator.Context context = new MessageInterpolatorContext( notNullDescriptor, null );
String expected = "message interpolation successful"; // unknown token {}
@@ -159,7 +173,9 @@
@Test
public void testDefaultInterpolation() {
- interpolator = new ResourceBundleMessageInterpolator( new TestResourceBundle() );
+ interpolator = new ResourceBundleMessageInterpolator(
+ new TestResourceBundleLocator()
+ );
MessageInterpolator.Context context = new MessageInterpolatorContext( notNullDescriptor, null );
String expected = "may not be null";
@@ -207,7 +223,9 @@
max, new ConstraintHelper(), java.lang.annotation.ElementType.FIELD, ConstraintOrigin.DEFINED_LOCALLY
);
- interpolator = new ResourceBundleMessageInterpolator( new TestResourceBundle() );
+ interpolator = new ResourceBundleMessageInterpolator(
+ new TestResourceBundleLocator()
+ );
MessageInterpolator.Context context = new MessageInterpolatorContext( constraintDescriptor, null );
String expected = "{replace.in.default.bundle2}";
@@ -233,7 +251,10 @@
max, new ConstraintHelper(), java.lang.annotation.ElementType.FIELD, ConstraintOrigin.DEFINED_LOCALLY
);
- interpolator = new ResourceBundleMessageInterpolator( new TestResourceBundle() );
+ interpolator = new ResourceBundleMessageInterpolator(
+ new TestResourceBundleLocator()
+ );
+
MessageInterpolator.Context context = new MessageInterpolatorContext( constraintDescriptor, null );
String actual = interpolator.interpolate( max.message(), context );
@@ -243,10 +264,22 @@
}
/**
+ * A dummy locator always returning a {@link TestResourceBundle}.
+ */
+ private static class TestResourceBundleLocator implements ResourceBundleLocator {
+
+ private TestResourceBundle resourceBundle = new TestResourceBundle();
+
+ public ResourceBundle getResourceBundle(Locale locale) {
+ return resourceBundle;
+ }
+ }
+
+ /**
* A dummy resource bundle which can be passed to the constructor of ResourceBundleMessageInterpolator to replace
* the user specified resource bundle.
*/
- class TestResourceBundle extends ResourceBundle implements Enumeration<String> {
+ private static class TestResourceBundle extends ResourceBundle implements Enumeration<String> {
private Map<String, String> testResources;
Iterator<String> iter;
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateBundleTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateBundleTest.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateBundleTest.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -0,0 +1,99 @@
+// $Id: AggregateBundleTest.java 17620 2009-10-04 19:19:28Z hardy.ferentschik $
+/*
+* 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.resourceloading;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.ResourceBundle;
+import java.util.Set;
+
+import org.testng.annotations.Test;
+
+import org.hibernate.validator.engine.resourceloading.AggregateResourceBundleLocator.AggregateBundle;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * Test for {@link AggregateBundle}.
+ *
+ * @author Gunnar Morling
+ */
+public class AggregateBundleTest {
+
+ private final static String BUNDLE_NAME_1 = AggregateResourceBundleLocatorTest.class.getPackage()
+ .getName() + ".AggregateResourceBundleLocatorTestBundle1";
+
+ private final static String BUNDLE_NAME_2 = AggregateResourceBundleLocatorTest.class.getPackage()
+ .getName() + ".AggregateResourceBundleLocatorTestBundle2";
+
+ @Test
+ public void aggregateBundleContainsKeysOfAllSourceBundles() {
+ ResourceBundle bundle_1 = ResourceBundle.getBundle( BUNDLE_NAME_1 );
+ ResourceBundle bundle_2 = ResourceBundle.getBundle( BUNDLE_NAME_2 );
+
+ ResourceBundle aggregateBundle = new AggregateBundle( Arrays.asList( bundle_1, bundle_2 ) );
+
+ Set<String> actualKeys = getAsSet( aggregateBundle.getKeys() );
+ Set<String> expectedKeys = new HashSet<String>( Arrays.asList( "key_1", "key_2", "key_3" ) );
+
+ assertEquals( actualKeys, expectedKeys );
+ }
+
+ @Test
+ public void aggregateBundleWithNoSourceBundlesContainsNoKeys() {
+ ResourceBundle aggregateBundle = new AggregateBundle( Collections.<ResourceBundle>emptyList() );
+ assertTrue( getAsSet( aggregateBundle.getKeys() ).isEmpty() );
+ }
+
+ @Test
+ public void valuesProperlyRetrievedFromAggregateBundle() {
+ ResourceBundle bundle_1 = ResourceBundle.getBundle( BUNDLE_NAME_1 );
+ ResourceBundle bundle_2 = ResourceBundle.getBundle( BUNDLE_NAME_2 );
+
+ ResourceBundle aggregateBundle = new AggregateBundle( Arrays.asList( bundle_1, bundle_2 ) );
+
+ assertEquals(
+ aggregateBundle.getString( "key_1" ),
+ "value 1 from bundle 1",
+ "Value for key_1 should be retrieved from bundle 1"
+ );
+ assertEquals(
+ aggregateBundle.getString( "key_2" ),
+ "value 2 from bundle 1",
+ "Value for key_2 should be retrieved from bundle 1"
+ );
+ assertEquals(
+ aggregateBundle.getString( "key_3" ),
+ "value 3 from bundle 2",
+ "Value for key_3 should be retrieved from bundle 2"
+ );
+ }
+
+ private Set<String> getAsSet(Enumeration<String> e) {
+ Set<String> theValue = new HashSet<String>();
+
+ while ( e.hasMoreElements() ) {
+ theValue.add( e.nextElement() );
+ }
+
+ return theValue;
+ }
+}
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocatorTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocatorTest.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocatorTest.java 2010-03-21 22:08:06 UTC (rev 19034)
@@ -0,0 +1,96 @@
+// $Id: AggregateResourceBundleLocatorTest.java 17620 2009-10-04 19:19:28Z hardy.ferentschik $
+/*
+* 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.resourceloading;
+
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+
+/**
+ * Test for {@link AggregateResourceBundleLocator}.
+ *
+ * @author Gunnar Morling
+ */
+public class AggregateResourceBundleLocatorTest {
+
+ private final static String BUNDLE_NAME_1 =
+ AggregateResourceBundleLocatorTest.class.getPackage()
+ .getName() + ".AggregateResourceBundleLocatorTestBundle1";
+
+ private final static String BUNDLE_NAME_2 =
+ AggregateResourceBundleLocatorTest.class.getPackage()
+ .getName() + ".AggregateResourceBundleLocatorTestBundle2";
+
+ @Test
+ public void valuesAreRetrievedFromBothSourceBundles() {
+
+ ResourceBundleLocator locator =
+ new AggregateResourceBundleLocator( Arrays.asList( BUNDLE_NAME_1, BUNDLE_NAME_2 ) );
+
+ ResourceBundle resourceBundle = locator.getResourceBundle( Locale.getDefault() );
+
+ assertNotNull( resourceBundle );
+
+ //contained in bundle 1
+ assertEquals( resourceBundle.getString( "key_1" ), "value 1 from bundle 1" );
+
+ //contained in both bundles, bundle 1 comes first
+ assertEquals( resourceBundle.getString( "key_2" ), "value 2 from bundle 1" );
+
+ //contained in bundle 2
+ assertEquals( resourceBundle.getString( "key_3" ), "value 3 from bundle 2" );
+ }
+
+ @Test
+ public void valuesAreRetrievedFromDelegate() {
+
+ ResourceBundleLocator locator =
+ new AggregateResourceBundleLocator(
+ Arrays.asList( BUNDLE_NAME_1 ),
+ new PlatformResourceBundleLocator( BUNDLE_NAME_2 )
+ );
+
+ ResourceBundle resourceBundle = locator.getResourceBundle( Locale.ENGLISH );
+
+ assertNotNull( resourceBundle );
+
+ //contained in bundle 1
+ assertEquals( resourceBundle.getString( "key_1" ), "value 1 from bundle 1" );
+
+ //contained in both bundles, but bundle 1 is queried before bundle 2 (delegate)
+ assertEquals( resourceBundle.getString( "key_2" ), "value 2 from bundle 1" );
+
+ //contained in bundle 2
+ assertEquals( resourceBundle.getString( "key_3" ), "value 3 from bundle 2" );
+ }
+
+ @Test
+ public void nullReturnedAsBundleDoesNotExist() {
+
+ ResourceBundleLocator locator = new AggregateResourceBundleLocator( Arrays.asList( "foo" ) );
+ ResourceBundle resourceBundle = locator.getResourceBundle( Locale.ENGLISH );
+
+ assertNull( resourceBundle );
+ }
+}
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocatorTestBundle1.properties
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocatorTestBundle1.properties (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocatorTestBundle1.properties 2010-03-21 22:08:06 UTC (rev 19034)
@@ -0,0 +1,2 @@
+key_1=value 1 from bundle 1
+key_2=value 2 from bundle 1
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocatorTestBundle2.properties
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocatorTestBundle2.properties (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/resourceloading/AggregateResourceBundleLocatorTestBundle2.properties 2010-03-21 22:08:06 UTC (rev 19034)
@@ -0,0 +1,2 @@
+key_2=value 2 from bundle 2
+key_3=value 3 from bundle 2
\ No newline at end of file
More information about the hibernate-commits
mailing list