Title: [waffle-scm] [838] trunk/waffle-core/src/test/resources: WAFFLE-97: Refactored bundle-based message resources to support multiple bundles encoded as CSV in the URI.

Diff

Modified: trunk/waffle-core/src/main/java/org/codehaus/waffle/i18n/DefaultMessageResources.java (837 => 838)

--- trunk/waffle-core/src/main/java/org/codehaus/waffle/i18n/DefaultMessageResources.java	2008-09-15 15:24:15 UTC (rev 837)
+++ trunk/waffle-core/src/main/java/org/codehaus/waffle/i18n/DefaultMessageResources.java	2008-09-15 16:04:36 UTC (rev 838)
@@ -4,20 +4,26 @@
 package org.codehaus.waffle.i18n;
 
 import static java.text.MessageFormat.format;
+import static java.util.Arrays.asList;
 import static java.util.ResourceBundle.getBundle;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
 
 /**
- * Default [EMAIL PROTECTED] ResourceBundle}-based implementation of MessageResorces.
+ * Default [EMAIL PROTECTED] ResourceBundle}-based implementation of MessageResorces. Supports a URI defining multiple resource
+ * bundle names as CSV-list. The decoding of the bundle names from the URI (including the separator string) is
+ * overrideable by subclassing the method [EMAIL PROTECTED] DefaultMessageResources#bundleNames(String)}.
  * 
  * @author Michael Ward
  * @author Mauro Talevi
  */
 public class DefaultMessageResources implements MessageResources {
     private static final ResourceBundle EMPTY_BUNDLE = new EmptyResourceBundle();
+    private final ResourceBundleMerger merger = new ResourceBundleMerger();
     private String uri;
     private Locale locale;
     private ResourceBundle bundle;
@@ -27,13 +33,18 @@
     }
 
     public DefaultMessageResources(MessageResourcesConfiguration configuration) {
-        this.uri = configuration.getDefaultURI();
-        this.locale = configuration.getDefaultLocale();
+        this.uri = configuration.getURI();
+        this.locale = configuration.getLocale();
         lookupBundle();
     }
 
-    private void lookupBundle() {        
-        bundle = lookupBunde(uri);
+    private void lookupBundle() {
+        List<String> bundleNames = bundleNames(uri);
+        List<ResourceBundle> bundles = new ArrayList<ResourceBundle>();
+        for (String bundleName : bundleNames) {
+            bundles.add(lookupBunde(bundleName));
+        }
+        bundle = merger.merge(bundles);
     }
 
     private ResourceBundle lookupBunde(String bundleName) {
@@ -43,6 +54,11 @@
             return EMPTY_BUNDLE;
         }
     }
+
+    protected List<String> bundleNames(String uri) {
+        return asList(uri.split(","));
+    }
+
     public String getURI() {
         return uri;
     }
@@ -61,7 +77,7 @@
         lookupBundle();
     }
 
-    public String getMessage(String key, Object... arguments) {        
+    public String getMessage(String key, Object... arguments) {
         return format(bundle.getString(key), arguments);
     }
 

Modified: trunk/waffle-core/src/main/java/org/codehaus/waffle/i18n/DefaultMessageResourcesConfiguration.java (837 => 838)

--- trunk/waffle-core/src/main/java/org/codehaus/waffle/i18n/DefaultMessageResourcesConfiguration.java	2008-09-15 15:24:15 UTC (rev 837)
+++ trunk/waffle-core/src/main/java/org/codehaus/waffle/i18n/DefaultMessageResourcesConfiguration.java	2008-09-15 16:04:36 UTC (rev 838)
@@ -6,37 +6,43 @@
 import java.util.Locale;
 
 /**
- * Default MessageResourcesConfiguration which simply allows the injection of default locale and resource.
+ * Default MessageResourcesConfiguration which allows the injection of locale and resource.
  * 
  * @author Mauro Talevi
  */
 public class DefaultMessageResourcesConfiguration implements MessageResourcesConfiguration {
 
-    private final String defaultURI;
-    private final Locale defaultLocale;
+    private static final String DEFAULT_URI = "ApplicationResources";
+    private static final Locale DEFAULT_LOCALE = Locale.getDefault();
+    private final String uri;
+    private final Locale locale;
 
     public DefaultMessageResourcesConfiguration() {
-        this("ApplicationResources", Locale.getDefault());
+        this(DEFAULT_URI, DEFAULT_LOCALE);
     }
+    
+    public DefaultMessageResourcesConfiguration(String defaultURI) {
+        this(defaultURI, DEFAULT_LOCALE);
+    }
 
-    public DefaultMessageResourcesConfiguration(String defaultURI, Locale defaultLocale) {
-        this.defaultLocale = defaultLocale;
-        this.defaultURI = defaultURI;
+    public DefaultMessageResourcesConfiguration(String uri, Locale locale) {
+        this.uri = uri;
+        this.locale = locale;
     }
 
     /**
-     * @deprecated Use DefaultMessageResourcesConfiguration(String defaultURI, Locale defaultLocale)
+     * @deprecated Use DefaultMessageResourcesConfiguration(String uri, Locale locale)
      */
-    public DefaultMessageResourcesConfiguration(Locale defaultLocale, String defaultURI) {
-        this(defaultURI, defaultLocale);
+    public DefaultMessageResourcesConfiguration(Locale locale, String uri) {
+        this(uri, locale);
     }
 
-    public Locale getDefaultLocale() {
-        return defaultLocale;
+    public Locale getLocale() {
+        return locale;
     }
 
-    public String getDefaultURI() {
-        return defaultURI;
+    public String getURI() {
+        return uri;
     }
 
 }

Modified: trunk/waffle-core/src/main/java/org/codehaus/waffle/i18n/MessageResourcesConfiguration.java (837 => 838)

--- trunk/waffle-core/src/main/java/org/codehaus/waffle/i18n/MessageResourcesConfiguration.java	2008-09-15 15:24:15 UTC (rev 837)
+++ trunk/waffle-core/src/main/java/org/codehaus/waffle/i18n/MessageResourcesConfiguration.java	2008-09-15 16:04:36 UTC (rev 838)
@@ -13,7 +13,7 @@
  */
 public interface MessageResourcesConfiguration {
 
-    String getDefaultURI();
+    String getURI();
 
-    Locale getDefaultLocale();
+    Locale getLocale();
 }

Added: trunk/waffle-core/src/main/java/org/codehaus/waffle/i18n/ResourceBundleMerger.java (0 => 838)

--- trunk/waffle-core/src/main/java/org/codehaus/waffle/i18n/ResourceBundleMerger.java	                        (rev 0)
+++ trunk/waffle-core/src/main/java/org/codehaus/waffle/i18n/ResourceBundleMerger.java	2008-09-15 16:04:36 UTC (rev 838)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) terms as published in http://waffle.codehaus.org/license.html
+ */
+package org.codehaus.waffle.i18n;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+
+/**
+ * Merges resource bundles into a [EMAIL PROTECTED] PropertyResourceBundle}.
+ * The merged resource bundle will contain all distinct keys from all bundles,
+ * and any overlapping keys from a given bundle will the overwritten by the next.
+ * It thus employs a last-key-wins strategy.
+ * 
+ * @author Mauro Talevi
+ */
+public class ResourceBundleMerger {
+
+    private static final ResourceBundle EMPTY_BUNDLE = new EmptyResourceBundle();
+
+    private final ByteArrayOutputStream stream;
+
+    public ResourceBundleMerger() {
+        this(new ByteArrayOutputStream());
+    }
+
+    public ResourceBundleMerger(ByteArrayOutputStream stream) {
+        this.stream = stream;
+    }
+
+    public ResourceBundle merge(List<ResourceBundle> bundles) {
+        Properties merged = new Properties();
+        for (ResourceBundle bundle : bundles) {
+            for (Enumeration<String> e = bundle.getKeys(); e.hasMoreElements();) {
+                String key = e.nextElement();
+                merged.setProperty(key, bundle.getString(key));
+            }
+        }
+        try {
+            merged.store(stream, "Merged bundles");
+            return new PropertyResourceBundle(new ByteArrayInputStream(stream.toByteArray()));
+        } catch (Exception e) {
+            return EMPTY_BUNDLE;
+        }
+    }
+
+}

Modified: trunk/waffle-core/src/test/java/org/codehaus/waffle/bind/converters/AbstractValueConverterTest.java (837 => 838)

--- trunk/waffle-core/src/test/java/org/codehaus/waffle/bind/converters/AbstractValueConverterTest.java	2008-09-15 15:24:15 UTC (rev 837)
+++ trunk/waffle-core/src/test/java/org/codehaus/waffle/bind/converters/AbstractValueConverterTest.java	2008-09-15 16:04:36 UTC (rev 838)
@@ -25,12 +25,12 @@
 
     protected MessageResourcesConfiguration configuration = new MessageResourcesConfiguration() {
 
-        public Locale getDefaultLocale() {
+        public Locale getLocale() {
             return Locale.UK;
         }
 
-        public String getDefaultURI() {
-            return "FakeResourceBundle";
+        public String getURI() {
+            return "Bundle";
         }
 
     };

Modified: trunk/waffle-core/src/test/java/org/codehaus/waffle/i18n/DefaultMessageResourcesTest.java (837 => 838)

--- trunk/waffle-core/src/test/java/org/codehaus/waffle/i18n/DefaultMessageResourcesTest.java	2008-09-15 15:24:15 UTC (rev 837)
+++ trunk/waffle-core/src/test/java/org/codehaus/waffle/i18n/DefaultMessageResourcesTest.java	2008-09-15 16:04:36 UTC (rev 838)
@@ -1,28 +1,19 @@
 package org.codehaus.waffle.i18n;
 
+import static java.util.Arrays.asList;
 import static org.junit.Assert.assertEquals;
 
+import java.util.List;
 import java.util.Locale;
 
 import org.junit.Test;
 
 /**
- * 
  * @author Michael Ward
  * @author Mauro Talevi
  */
-public class DefaultMessageResourcesTest  {
+public class DefaultMessageResourcesTest {
 
-    private MessageResourcesConfiguration configuration = new MessageResourcesConfiguration() {
-        public String getDefaultURI() {
-            return "FakeResourceBundle";
-        }
-
-        public Locale getDefaultLocale() {
-            return Locale.US;
-        }
-    };
-
     @Test
     public void canGetDefaultLocaleIfNoLocaleSpecified() {
         MessageResources messageResources = new DefaultMessageResources();
@@ -30,21 +21,48 @@
     }
 
     @Test
-    public void canGetMessage() {
-        MessageResources messageResources = new DefaultMessageResources(configuration);
+    public void canGetMessageForDifferentURIsAndLocales() {
+        MessageResources messageResources = new DefaultMessageResources(new DefaultMessageResourcesConfiguration("Bundle"));
         assertEquals("thoughtworks", messageResources.getMessage("company"));
         assertEquals("hello mars", messageResources.getMessage("foo.bar", "mars"));
-
         messageResources.useLocale(Locale.UK);
         assertEquals("thoughtworks", messageResources.getMessage("company"));
         assertEquals("cheerio mars", messageResources.getMessage("foo.bar", "mars"));
+        messageResources.useLocale(Locale.ITALY);
+        assertEquals("thoughtworks", messageResources.getMessage("company"));
+        assertEquals("ciao mars", messageResources.getMessage("foo.bar", "mars"));
+        messageResources = new DefaultMessageResources(new DefaultMessageResourcesConfiguration("AnotherBundle"));
+        assertEquals("howdy mars", messageResources.getMessage("foo.bar", "mars"));
+
     }
 
     @Test
+    public void canGetMessageUsingMultipleBundles() {
+        assertMessagesUsingMultipleBundles(new DefaultMessageResources(new DefaultMessageResourcesConfiguration(
+                "Bundle,AnotherBundle")));
+        // can ignore trailing spaces in bundle names
+        assertMessagesUsingMultipleBundles(new DefaultMessageResources(new DefaultMessageResourcesConfiguration(
+                " Bundle, AnotherBundle ")));
+        // can configure other separators for bundle names
+        assertMessagesUsingMultipleBundles(new DefaultMessageResources(new DefaultMessageResourcesConfiguration(
+                "Bundle;AnotherBundle")){
+                    @Override
+                    protected List<String> bundleNames(String uri) {
+                        return asList(uri.split(";"));
+                    }            
+        });
+    }
+
+    private void assertMessagesUsingMultipleBundles(MessageResources messageResources) {
+        assertEquals("thoughtworks", messageResources.getMessage("company"));
+        assertEquals("howdy mars", messageResources.getMessage("foo.bar", "mars"));
+        assertEquals("waffle", messageResources.getMessage("project.name", "mars"));
+    }
+
+    @Test
     public void canGetMessageWithDefault() {
-        MessageResources messageResources = new DefaultMessageResources(configuration);
-
-        assertEquals("thoughtworks", messageResources.getMessageWithDefault("company", "BEARS"));
+        MessageResources messageResources = new DefaultMessageResources(new DefaultMessageResourcesConfiguration("Bundle"));
+        assertEquals("thoughtworks", messageResources.getMessageWithDefault("company", "should-be-ignored"));
         assertEquals("hello mars", messageResources.getMessageWithDefault("foo.bar", "should-be-ignored", "mars"));
         assertEquals("defaultValue", messageResources.getMessageWithDefault("should.not.exist", "defaultValue"));
     }

Added: trunk/waffle-core/src/test/java/org/codehaus/waffle/i18n/ResourceBundleMergerTest.java (0 => 838)

--- trunk/waffle-core/src/test/java/org/codehaus/waffle/i18n/ResourceBundleMergerTest.java	                        (rev 0)
+++ trunk/waffle-core/src/test/java/org/codehaus/waffle/i18n/ResourceBundleMergerTest.java	2008-09-15 16:04:36 UTC (rev 838)
@@ -0,0 +1,59 @@
+package org.codehaus.waffle.i18n;
+
+import static java.util.Arrays.asList;
+import static java.util.ResourceBundle.getBundle;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import org.junit.Test;
+
+/**
+ * @author Mauro Talevi
+ */
+public class ResourceBundleMergerTest {
+
+    private static final Locale LOCALE = Locale.getDefault();
+
+    @Test
+    public void canMergeMultipleBundles() {
+        ResourceBundleMerger merger = new ResourceBundleMerger();
+        ResourceBundle bundle = getBundle("Bundle", LOCALE);
+        ResourceBundle anotherBundle = getBundle("AnotherBundle", LOCALE);
+        List<ResourceBundle> bundles = asList(bundle, anotherBundle);
+        ResourceBundle merged = merger.merge(bundles);
+        assertEquals(bundle.getString("company"), merged.getString("company"));
+        assertEquals(anotherBundle.getString("foo.bar"), merged.getString("foo.bar"));
+    }
+
+    @Test
+    public void canAllowBundleToOverridePreviousBundles() {
+        ResourceBundleMerger merger = new ResourceBundleMerger();
+        ResourceBundle bundle = getBundle("Bundle", LOCALE);
+        ResourceBundle anotherBundle = getBundle("AnotherBundle", LOCALE);
+        List<ResourceBundle> bundles = asList(bundle, anotherBundle);
+        ResourceBundle merged = merger.merge(bundles);
+        assertEquals(anotherBundle.getString("project.name"), merged.getString("project.name"));
+    }
+
+    @Test
+    public void canMergeMultipleBundlesToEmptyBundleIfOutputStreamInvalid() {
+        ResourceBundleMerger merger = new ResourceBundleMerger(new ByteArrayOutputStream() {
+            @Override
+            public synchronized byte[] toByteArray() {
+                throw new RuntimeException("mock");
+            }
+
+        });
+        ResourceBundle bundle = getBundle("Bundle", LOCALE);
+        ResourceBundle anotherBundle = getBundle("AnotherBundle", LOCALE);
+        List<ResourceBundle> bundles = asList(bundle, anotherBundle);
+        ResourceBundle merged = merger.merge(bundles);
+        assertTrue(merged instanceof EmptyResourceBundle);
+    }
+
+}

Added: trunk/waffle-core/src/test/resources/AnotherBundle.properties (0 => 838)

--- trunk/waffle-core/src/test/resources/AnotherBundle.properties	                        (rev 0)
+++ trunk/waffle-core/src/test/resources/AnotherBundle.properties	2008-09-15 16:04:36 UTC (rev 838)
@@ -0,0 +1,4 @@
+foo.bar=howdy {0}
+project.name=waffle
+
+

Copied: trunk/waffle-core/src/test/resources/Bundle.properties (from rev 834, trunk/waffle-core/src/test/resources/FakeResourceBundle.properties) (0 => 838)

--- trunk/waffle-core/src/test/resources/Bundle.properties	                        (rev 0)
+++ trunk/waffle-core/src/test/resources/Bundle.properties	2008-09-15 16:04:36 UTC (rev 838)
@@ -0,0 +1,13 @@
+company=thoughtworks
+foo.bar=hello {0}
+project.name=waffle
+date.format=dd-MM-yyyy
+date.format.day=dd
+date.format.day.name=day.*
+date.format.time=HH:mm:ss
+date.format.time.name=time.*
+bind.error.date=Date {1} has invalid format {2} for field {0}
+bind.error.date.missing=Date field {0} is missing
+bind.error.list=No list values for field {0}
+bind.error.map=No map values for field {0}
+

Property changes: trunk/waffle-core/src/test/resources/Bundle.properties

Name: svn:mergeinfo
   + 

Copied: trunk/waffle-core/src/test/resources/Bundle_en_GB.properties (from rev 834, trunk/waffle-core/src/test/resources/FakeResourceBundle_en_GB.properties) (0 => 838)

--- trunk/waffle-core/src/test/resources/Bundle_en_GB.properties	                        (rev 0)
+++ trunk/waffle-core/src/test/resources/Bundle_en_GB.properties	2008-09-15 16:04:36 UTC (rev 838)
@@ -0,0 +1 @@
+foo.bar=cheerio {0}
\ No newline at end of file

Property changes: trunk/waffle-core/src/test/resources/Bundle_en_GB.properties

Name: svn:mergeinfo
   + 

Added: trunk/waffle-core/src/test/resources/Bundle_it_IT.properties (0 => 838)

--- trunk/waffle-core/src/test/resources/Bundle_it_IT.properties	                        (rev 0)
+++ trunk/waffle-core/src/test/resources/Bundle_it_IT.properties	2008-09-15 16:04:36 UTC (rev 838)
@@ -0,0 +1 @@
+foo.bar=ciao {0}
\ No newline at end of file
Property changes on: trunk/waffle-core/src/test/resources/Bundle_it_IT.properties
___________________________________________________________________
Name: svn:mergeinfo
   + 

Deleted: trunk/waffle-core/src/test/resources/FakeResourceBundle.properties (837 => 838)

--- trunk/waffle-core/src/test/resources/FakeResourceBundle.properties	2008-09-15 15:24:15 UTC (rev 837)
+++ trunk/waffle-core/src/test/resources/FakeResourceBundle.properties	2008-09-15 16:04:36 UTC (rev 838)
@@ -1,12 +0,0 @@
-company=thoughtworks
-foo.bar=hello {0}
-date.format=dd-MM-yyyy
-date.format.day=dd
-date.format.day.name=day.*
-date.format.time=HH:mm:ss
-date.format.time.name=time.*
-bind.error.date=Date {1} has invalid format {2} for field {0}
-bind.error.date.missing=Date field {0} is missing
-bind.error.list=No list values for field {0}
-bind.error.map=No map values for field {0}
-

Deleted: trunk/waffle-core/src/test/resources/FakeResourceBundle_en_GB.properties (837 => 838)

--- trunk/waffle-core/src/test/resources/FakeResourceBundle_en_GB.properties	2008-09-15 15:24:15 UTC (rev 837)
+++ trunk/waffle-core/src/test/resources/FakeResourceBundle_en_GB.properties	2008-09-15 16:04:36 UTC (rev 838)
@@ -1 +0,0 @@
-foo.bar=cheerio {0}
\ No newline at end of file


To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to