You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2010/04/29 18:11:06 UTC

svn commit: r939357 - in /tapestry/tapestry5/trunk: src/site/apt/ tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ tapestry-core/src/main/java/org/apache/tapestry5/services/ tapestry-core/src/main/resources/org/apache/tapestry5/inter...

Author: hlship
Date: Thu Apr 29 16:11:06 2010
New Revision: 939357

URL: http://svn.apache.org/viewvc?rev=939357&view=rev
Log:
TAP5-1120: It is not possible to override the default Translator contributions to the TranslatorSource service

Modified:
    tapestry/tapestry5/trunk/src/site/apt/upgrade.apt
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TranslatorSourceImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TranslatorSourceImplTest.java

Modified: tapestry/tapestry5/trunk/src/site/apt/upgrade.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/upgrade.apt?rev=939357&r1=939356&r2=939357&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/upgrade.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/upgrade.apt Thu Apr 29 16:11:06 2010
@@ -14,6 +14,12 @@ Upgrade Notes
 
 Release 5.2.0
 
+* TranslatorSource
+
+  The configuration type for TranslatorSource has changed in an <<incompatible>> way: from
+  an unordered collection to a mapped collection; this is to support overrides. This will break
+  existing module classes that contribute to the TranslatorSource service configuration.
+
 * Assets
 
   There have been some changes to how assets operate in Tapestry 5.2.
@@ -52,8 +58,8 @@ Release 5.2.0
 
 * Template Parser back to SAX
 
-  Tapestry no longer uses a StAX parser (it uses a normal SAX parser) to parse component templates. This change
-  reduces the number of dependencies for Tapestry, and is a stepping stone to compatibility with
+  Tapestry no longer uses a StAX parser to parse component templates, it has reverted to using a normal SAX parser. This change
+  reduces the number of dependencies for Tapestry, and is a stepping stone towards compatibility with
   Google App Engine.
 
 Release 5.1.0.4

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java?rev=939357&r1=939356&r2=939357&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java Thu Apr 29 16:11:06 2010
@@ -153,11 +153,6 @@ public class ServicesMessages
         return MESSAGES.format("unknown-validator-type", validatorType, InternalUtils.join(knownValidatorTypes));
     }
 
-    public static String unknownTranslatorType(String translatorType, List<String> knownTranslatorTypes)
-    {
-        return MESSAGES.format("unknown-translator-type", translatorType, InternalUtils.join(knownTranslatorTypes));
-    }
-
     public static String validatorSpecificationParseError(int cursor, String specification)
     {
         return MESSAGES.format("validator-specification-parse-error", specification.charAt(cursor), cursor + 1,

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TranslatorSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TranslatorSourceImpl.java?rev=939357&r1=939356&r2=939357&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TranslatorSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TranslatorSourceImpl.java Thu Apr 29 16:11:06 2010
@@ -1,10 +1,10 @@
-// Copyright 2007, 2008 The Apache Software Foundation
+// Copyright 2007, 2008, 2010 The Apache Software Foundation
 //
 // 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
+// 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,
@@ -14,34 +14,41 @@
 
 package org.apache.tapestry5.internal.services;
 
+import java.util.List;
+import java.util.Map;
+
 import org.apache.tapestry5.Translator;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.util.AvailableValues;
 import org.apache.tapestry5.ioc.util.StrategyRegistry;
+import org.apache.tapestry5.ioc.util.UnknownValueException;
 import org.apache.tapestry5.services.InvalidationListener;
 import org.apache.tapestry5.services.TranslatorSource;
 
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
 public class TranslatorSourceImpl implements TranslatorSource, InvalidationListener
 {
     private final Map<String, Translator> translators = CollectionFactory.newCaseInsensitiveMap();
 
     private final StrategyRegistry<Translator> registry;
 
-    public TranslatorSourceImpl(Collection<Translator> configuration)
+    public TranslatorSourceImpl(Map<Class, Translator> configuration)
     {
-        Map<Class, Translator> typeToTranslator = CollectionFactory.newMap();
-
-        for (Translator t : configuration)
+        for (Map.Entry<Class, Translator> me : configuration.entrySet())
         {
-            translators.put(t.getName(), t);
-            typeToTranslator.put(t.getType(), t);
+            Class type = me.getKey();
+            Translator translator = me.getValue();
+
+            if (!type.equals(translator.getType()))
+                throw new RuntimeException(
+                        String
+                                .format(
+                                        "Contributed translator for type %s reports its type as %s. Please change the contribution so that the key matches that translator type.",
+                                        type.getName(), translator.getType().getName()));
+
+            translators.put(translator.getName(), translator);
         }
 
-        registry = StrategyRegistry.newInstance(Translator.class, typeToTranslator, true);
+        registry = StrategyRegistry.newInstance(Translator.class, configuration, true);
     }
 
     public Translator get(String name)
@@ -50,8 +57,8 @@ public class TranslatorSourceImpl implem
         Translator result = translators.get(name);
 
         if (result == null)
-            throw new RuntimeException(ServicesMessages.unknownTranslatorType(name, InternalUtils
-                    .sortedKeys(translators)));
+            throw new UnknownValueException(String.format("Unknown translator type '%s'.", name), new AvailableValues(
+                    "translators", translators));
 
         return result;
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=939357&r1=939356&r2=939357&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Thu Apr 29 16:11:06 2010
@@ -1008,11 +1008,11 @@ public final class TapestryModule
      * <li>BigDecimal</li>
      * </ul>
      */
-    public static void contributeTranslatorSource(Configuration<Translator> configuration,
+    public static void contributeTranslatorSource(MappedConfiguration<Class, Translator> configuration,
             NumericTranslatorSupport support)
     {
 
-        configuration.add(new StringTranslator());
+        configuration.add(String.class, new StringTranslator());
 
         Class[] types = new Class[]
         { Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, BigInteger.class,
@@ -1022,7 +1022,7 @@ public final class TapestryModule
         {
             String name = type.getSimpleName().toLowerCase();
 
-            configuration.add(new NumericTranslator(name, type, support));
+            configuration.add(type, new NumericTranslator(name, type, support));
         }
     }
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties?rev=939357&r1=939356&r2=939357&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties Thu Apr 29 16:11:06 2010
@@ -41,7 +41,6 @@ asset-does-not-exist=Unable to locate as
 wrong-asset-digest=The asset digest in the request does not match the actual digest for asset '%s'. This indicates that the content of the asset has changed between requests. 
 unknown-validator-type=Unknown validator type '%s'.  Configured validators are %s.
 validator-specification-parse-error=Unexpected character '%s' at position %d of input string: %s
-unknown-translator-type=Unknown translator type '%s'.  Configured translators are %s.
 missing-from-environment=No object of type %s is available from the Environment.  Available types are %s.
 invalid-component-event-result=A component event handler method returned the value %s. Return type %s can not be handled.  Configured return types are %s.
 undefined-tapestry-attribute=Element <%s> does not support an attribute named '%s'. The only allowed attribute name is '%s'.

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TranslatorSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TranslatorSourceImplTest.java?rev=939357&r1=939356&r2=939357&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TranslatorSourceImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TranslatorSourceImplTest.java Thu Apr 29 16:11:06 2010
@@ -1,10 +1,10 @@
-// Copyright 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2007, 2008, 2009, 2010 The Apache Software Foundation
 //
 // 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
+// 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,
@@ -14,6 +14,13 @@
 
 package org.apache.tapestry5.internal.services;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.text.DecimalFormatSymbols;
+import java.text.ParseException;
+import java.util.Locale;
+import java.util.Map;
+
 import org.apache.tapestry5.Field;
 import org.apache.tapestry5.Translator;
 import org.apache.tapestry5.ValidationException;
@@ -22,19 +29,13 @@ import org.apache.tapestry5.internal.tra
 import org.apache.tapestry5.internal.translator.BigIntegerNumericFormatter;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.services.ThreadLocale;
+import org.apache.tapestry5.ioc.util.UnknownValueException;
 import org.apache.tapestry5.services.TranslatorSource;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.text.DecimalFormatSymbols;
-import java.text.ParseException;
-import java.util.Collection;
-import java.util.Locale;
-
 public class TranslatorSourceImplTest extends InternalBaseTestCase
 {
     private TranslatorSource source;
@@ -44,37 +45,68 @@ public class TranslatorSourceImplTest ex
     {
         source = getService(TranslatorSource.class);
     }
-    
+
     @BeforeMethod
     public void setupThreadLocale()
     {
         getService(ThreadLocale.class).setLocale(Locale.ENGLISH);
     }
 
-
     @Test
     public void found_translator_by_name()
     {
         Translator translator = mockTranslator("mock", String.class);
 
-        Collection<Translator> configuration = CollectionFactory.newList(translator);
-
         replay();
 
-        TranslatorSource source = new TranslatorSourceImpl(configuration);
+        TranslatorSource source = new TranslatorSourceImpl(newConfiguration(String.class, translator));
 
         assertSame(source.get("mock"), translator);
 
         verify();
     }
 
+    private Map<Class, Translator> newConfiguration(Class type, Translator t)
+    {
+        Map<Class, Translator> result = CollectionFactory.newMap();
+        result.put(type, t);
+
+        return result;
+    }
+
+    @Test
+    public void key_and_type_mismatch()
+    {
+        Translator t = mockTranslator();
+
+        train_getType(t, Long.class);
+
+        replay();
+
+        try
+        {
+            new TranslatorSourceImpl(newConfiguration(Integer.class, t));
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex,
+                    "Contributed translator for type java.lang.Integer reports its type as java.lang.Long.");
+        }
+
+        verify();
+    }
+
     @Test
     public void unknown_translator_is_failure()
     {
         Translator fred = mockTranslator("fred", String.class);
         Translator barney = mockTranslator("barney", Long.class);
 
-        Collection<Translator> configuration = CollectionFactory.newList(fred, barney);
+        Map<Class, Translator> configuration = CollectionFactory.newMap();
+
+        configuration.put(String.class, fred);
+        configuration.put(Long.class, barney);
 
         replay();
 
@@ -85,19 +117,17 @@ public class TranslatorSourceImplTest ex
             source.get("wilma");
             unreachable();
         }
-        catch (RuntimeException ex)
+        catch (UnknownValueException ex)
         {
-            assertEquals(
-                    ex.getMessage(),
-                    "Unknown translator type 'wilma'.  Configured translators are barney, fred.");
+            assertMessageContains(ex, "Unknown translator type 'wilma'.");
         }
     }
 
-
     @DataProvider
     public Object[][] to_client_data()
     {
-        return new Object[][] {
+        return new Object[][]
+        {
 
                 { Byte.class, (byte) 65, "65" },
 
@@ -105,7 +135,7 @@ public class TranslatorSourceImplTest ex
 
                 { Long.class, 12345l, "12345" },
 
-                // Is this a bug?  We seem to be using a JDK- or locale-defined level of precision.
+                // Is this a bug? We seem to be using a JDK- or locale-defined level of precision.
                 // Maybe translators need room for configuration just like validators, so that
                 // the correct decimal format string could be specified in the message catalog.
 
@@ -117,12 +147,10 @@ public class TranslatorSourceImplTest ex
 
                 { Float.class, (float) -22.7, "-22.7" },
 
-                { BigInteger.class, new BigInteger("123456789012345678901234567890"),
-                        "123456789012345678901234567890" },
+                { BigInteger.class, new BigInteger("123456789012345678901234567890"), "123456789012345678901234567890" },
 
                 { BigDecimal.class, new BigDecimal("-9876543219876543321987654321.12345123451234512345"),
-                        "-9876543219876543321987654321.12345123451234512345" }
-        };
+                        "-9876543219876543321987654321.12345123451234512345" } };
     }
 
     @Test(dataProvider = "to_client_data")
@@ -138,7 +166,8 @@ public class TranslatorSourceImplTest ex
     @DataProvider
     public Object[][] parse_client_success_data()
     {
-        return new Object[][] {
+        return new Object[][]
+        {
 
                 { Byte.class, " 23 ", (byte) 23 },
 
@@ -160,8 +189,7 @@ public class TranslatorSourceImplTest ex
                         new BigInteger("-123456789012345678901234567890") },
 
                 { BigDecimal.class, "-9,876,543,219,876,543,321,987,654,321.12345123451234512345",
-                        new BigDecimal("-9876543219876543321987654321.12345123451234512345") }
-        };
+                        new BigDecimal("-9876543219876543321987654321.12345123451234512345") } };
     }
 
     @Test(dataProvider = "parse_client_success_data")
@@ -180,20 +208,20 @@ public class TranslatorSourceImplTest ex
         String intError = "You must provide an integer value for Fred.";
         String floatError = "You must provide a numeric value for Fred.";
 
-        return new Object[][] {
+        return new Object[][]
+        {
 
-                { Byte.class, "fred", intError },
+        { Byte.class, "fred", intError },
 
-                { Integer.class, "fred", intError },
+        { Integer.class, "fred", intError },
 
-                { Long.class, "fred", intError },
+        { Long.class, "fred", intError },
 
-                { Double.class, "fred", floatError },
+        { Double.class, "fred", floatError },
 
-                { Float.class, "fred", floatError },
+        { Float.class, "fred", floatError },
 
-                { Short.class, "fred", intError }
-        };
+        { Short.class, "fred", intError } };
     }
 
     @Test(dataProvider = "parse_client_failure_data")
@@ -221,11 +249,10 @@ public class TranslatorSourceImplTest ex
     public void find_by_type()
     {
         Translator t = mockTranslator("string", String.class);
-        Collection<Translator> configuration = CollectionFactory.newList(t);
 
         replay();
 
-        TranslatorSource source = new TranslatorSourceImpl(configuration);
+        TranslatorSource source = new TranslatorSourceImpl(newConfiguration(String.class, t));
 
         assertSame(source.getByType(String.class), t);
         assertSame(source.findByType(String.class), t);
@@ -240,7 +267,9 @@ public class TranslatorSourceImplTest ex
         Translator string = mockTranslator("string", String.class);
         Translator bool = mockTranslator("bool", Boolean.class);
 
-        Collection<Translator> configuration = CollectionFactory.newList(string, bool);
+        Map<Class, Translator> configuration = CollectionFactory.newMap();
+        configuration.put(String.class, string);
+        configuration.put(Boolean.class, bool);
 
         replay();
 
@@ -254,7 +283,7 @@ public class TranslatorSourceImplTest ex
         catch (IllegalArgumentException ex)
         {
             assertEquals(ex.getMessage(),
-                         "No translator is defined for type java.lang.Integer.  Registered types: java.lang.Boolean, java.lang.String.");
+                    "No translator is defined for type java.lang.Integer.  Registered types: java.lang.Boolean, java.lang.String.");
         }
 
         verify();
@@ -293,5 +322,4 @@ public class TranslatorSourceImplTest ex
         assertEquals(f.toClient(big), "*123456#797956563434");
     }
 
-
 }