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 2009/01/03 19:19:55 UTC

svn commit: r731061 - in /tapestry/tapestry5/trunk: src/site/apt/ tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ tapestry-ioc/src/site/apt/ tapestry-ioc/src/test/java/org/apache/tapest...

Author: hlship
Date: Sat Jan  3 10:19:54 2009
New Revision: 731061

URL: http://svn.apache.org/viewvc?rev=731061&view=rev
Log:
TAP5-437: The OrderedConfiguration and MappedConfiguration interfaces should allow for override() methods (similar to add()

Added:
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/MappedConfigurationOverride.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/StringLookup.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/NonmatchingMappedConfigurationOverrideModule.java
Modified:
    tapestry/tapestry5/trunk/src/site/apt/index.apt
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Configuration.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/MappedConfiguration.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/OrderedConfiguration.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapper.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/configuration.apt
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/BarneyModule.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/ConfigurationOverrideModule.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/DuplicateConfigurationOverrideModule.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FredModule.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapperTest.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/resources/log4j.properties

Modified: tapestry/tapestry5/trunk/src/site/apt/index.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/index.apt?rev=731061&r1=731060&r2=731061&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/index.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/index.apt Sat Jan  3 10:19:54 2009
@@ -52,6 +52,8 @@
 *--+--+--+
 | {{{http://www.arsmachina.com.br}Ars Machina}} |   Thiago H. de Paula Figueiredo |  Tapestry/Hibernate extensions for Generic DAOs, standard CRUD interfaces, and user access logging and tracking |
 *--+--+--+
+| {{{http://www.chenillekit.org/}Chenille Kit}} |  Massimo Lusetti  |   Collection of modules, services, utilities and components (many of which require only tapestry-ioc) \
+*--+--+--+
 | {{{http://equanda.org/equanda-tapestry5/}equanda-tapestry5}} |   Joachim Van der Auwera |      Components useful for building enterprise applications. Includes Accordion, Tabs, Formtraversal. Amongst other things, these focus on easy input of data without the need for a mouse.
 *--+--+--+
 | {{{http://code.google.com/p/gc-tapestry-components/}Godcode Components}} |   Chris Lewis |         A mixed collection of components providing simple but time-saving functionality, as well as more exotic ones; built on top of the prototype and script.aculo.us javascript libraries. |
@@ -77,7 +79,9 @@
 
 New And Of Note
 
-  * Property expressions have been improved: You can now invoke methods with parameters, or create a list.
+  * Ordered and mapped configurations can now have overrides.
+
+  * Property expressions have been improved: You can now invoke methods with parameters, or create a list (very useful for link contexts).
 
   * IoC Service contributions may now be made in terms of classes (that are automatically instantiated) as well as
     instances.

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Configuration.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Configuration.java?rev=731061&r1=731060&r2=731061&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Configuration.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Configuration.java Sat Jan  3 10:19:54 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2008 The Apache Software Foundation
+// Copyright 2006, 2008, 2009 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.
@@ -19,7 +19,7 @@
  * configuration.
  * <p/>
  * A service can <em>collect</em> contributions in three different ways: <ul> <li>As an un-ordered collection of
- * values</li> <li>As an ordered list of values (where each value has a unique id, pre-requisited and
+ * values</li> <li>As an ordered list of values (where each value has a unique id, pre-requisites and
  * post-requisites)</li> <li>As a map of keys and values </ul>
  * <p/>
  * This implementation is used for un-ordered configuration data.

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/MappedConfiguration.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/MappedConfiguration.java?rev=731061&r1=731060&r2=731061&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/MappedConfiguration.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/MappedConfiguration.java Sat Jan  3 10:19:54 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2008 The Apache Software Foundation
+// Copyright 2006, 2008, 2009 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.
@@ -19,7 +19,7 @@
  * configuration.
  * <p/>
  * A service can <em>collect</em> contributions in three different ways: <ul> <li>As an un-ordered collection of
- * values</li> <li>As an ordered list of values (where each value has a unique id, pre-requisited and
+ * values</li> <li>As an ordered list of values (where each value has a unique id, pre-requisites and
  * post-requisites)</li> <li>As a map of keys and values </ul>
  * <p/>
  * The service defines the <em>type</em> of contribution, in terms of a base class or service interface. Contributions
@@ -38,6 +38,15 @@
     void add(K key, V value);
 
     /**
+     * Overrides an existing contribution by its key.
+     *
+     * @param key   unique id of value to override
+     * @param value new value, or null to remove the key entirely
+     * @since 5.1.0.0
+     */
+    void override(K key, V value);
+
+    /**
      * Adds a keyed object as an instantiated instance (with dependencies injected) of a class.
      *
      * @param key   unique id for the value
@@ -45,4 +54,12 @@
      * @since 5.1.0.0
      */
     void addInstance(K key, Class<? extends V> clazz);
+
+    /**
+     * Overrides an existing contribution with a new instance.
+     *
+     * @param key   unique id of value to override
+     * @param clazz class to instantiate as override
+     */
+    void overrideInstance(K key, Class<? extends V> clazz);
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/OrderedConfiguration.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/OrderedConfiguration.java?rev=731061&r1=731060&r2=731061&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/OrderedConfiguration.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/OrderedConfiguration.java Sat Jan  3 10:19:54 2009
@@ -19,7 +19,7 @@
  * configuration.
  * <p/>
  * A service can <em>collect</em> contributions in three different ways: <ul> <li>As an un-ordered collection of
- * values</li> <li>As an ordered list of values (where each value has a unique id, pre-requisited and
+ * values</li> <li>As an ordered list of values (where each value has a unique id, pre-requisites and
  * post-requisites)</li> <li>As a map of keys and values </ul>
  * <p/>
  * The service defines the <em>type</em> of contribution, in terms of a base class or service interface. Contributions

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/MappedConfigurationOverride.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/MappedConfigurationOverride.java?rev=731061&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/MappedConfigurationOverride.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/MappedConfigurationOverride.java Sat Jan  3 10:19:54 2009
@@ -0,0 +1,55 @@
+// Copyright 2009 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
+//
+// 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.apache.tapestry5.ioc.internal;
+
+import org.apache.tapestry5.ioc.def.ContributionDef;
+
+import java.util.Map;
+
+public class MappedConfigurationOverride<K, V>
+{
+    private final Map<K, V> configuration;
+
+    private final K key;
+
+    private final V overrideValue;
+
+    private final ContributionDef contribDef;
+
+    public MappedConfigurationOverride(ContributionDef contribDef, Map<K, V> configuration, K key, V overrideValue)
+    {
+        this.contribDef = contribDef;
+        this.configuration = configuration;
+        this.key = key;
+        this.overrideValue = overrideValue;
+    }
+
+    void apply()
+    {
+        if (!configuration.containsKey(key))
+            throw new IllegalArgumentException(
+                    String.format("Override for key %s (at %s) does not match an existing key.", key, contribDef));
+
+        if (overrideValue == null)
+            configuration.remove(key);
+        else
+            configuration.put(key, overrideValue);
+    }
+
+    public ContributionDef getContribDef()
+    {
+        return contribDef;
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java?rev=731061&r1=731060&r2=731061&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java Sat Jan  3 10:19:54 2009
@@ -408,11 +408,17 @@
 
         // When the key type is String, then a case insensitive map is used.
 
-        final Map<K, V> result = newConfigurationMap(keyType);
+        Map<K, V> result = newConfigurationMap(keyType);
         Map<K, ContributionDef> keyToContribution = newConfigurationMap(keyType);
+        Map<K, MappedConfigurationOverride<K, V>> overrides = newConfigurationMap(keyType);
 
         for (Module m : moduleToServiceDefs.keySet())
-            addToMappedConfiguration(result, keyToContribution, keyType, objectType, serviceDef, m);
+            addToMappedConfiguration(result, overrides, keyToContribution, keyType, objectType, serviceDef, m);
+
+        for (MappedConfigurationOverride<K, V> override : overrides.values())
+        {
+            override.apply();
+        }
 
         return result;
     }
@@ -431,6 +437,7 @@
     }
 
     private <K, V> void addToMappedConfiguration(Map<K, V> map,
+                                                 Map<K, MappedConfigurationOverride<K, V>> overrides,
                                                  Map<K, ContributionDef> keyToContribution, Class<K> keyClass,
                                                  Class<V> valueType, ServiceDef serviceDef, final Module module)
     {
@@ -445,15 +452,11 @@
 
         final ServiceResources resources = new ServiceResourcesImpl(this, module, serviceDef, classFactory, logger);
 
-
         for (final ContributionDef def : contributions)
         {
-            final MappedConfiguration<K, V> validating = new ValidatingMappedConfigurationWrapper<K, V>(map, serviceId,
-                                                                                                        def,
-                                                                                                        keyClass,
-                                                                                                        valueType,
-                                                                                                        keyToContribution,
-                                                                                                        resources);
+            final MappedConfiguration<K, V> validating =
+                    new ValidatingMappedConfigurationWrapper<K, V>(map, overrides, serviceId, def, keyClass, valueType,
+                                                                   keyToContribution, resources);
 
             String description = IOCMessages.invokingMethod(def);
 
@@ -505,12 +508,12 @@
         }
     }
 
-    private <T> void addToOrderedConfiguration(final Orderer<T> orderer,
-                                               final Map<String, OrderedConfigurationOverride<T>> overrides,
-                                               final Class<T> valueType,
+    private <T> void addToOrderedConfiguration(Orderer<T> orderer,
+                                               Map<String, OrderedConfigurationOverride<T>> overrides,
+                                               Class<T> valueType,
                                                ServiceDef serviceDef, final Module module)
     {
-        final String serviceId = serviceDef.getServiceId();
+        String serviceId = serviceDef.getServiceId();
         Set<ContributionDef> contributions = module.getContributorDefsForService(serviceId);
 
         if (contributions.isEmpty()) return;
@@ -522,6 +525,10 @@
 
         for (final ContributionDef def : contributions)
         {
+            final OrderedConfiguration<T> validating =
+                    new ValidatingOrderedConfigurationWrapper<T>(orderer, overrides, def, serviceId, valueType,
+                                                                 resources);
+
             String description = IOCMessages.invokingMethod(def);
 
             if (debug)
@@ -531,9 +538,6 @@
             {
                 public void run()
                 {
-                    OrderedConfiguration<T> validating =
-                            new ValidatingOrderedConfigurationWrapper<T>(orderer, overrides, def, serviceId, valueType,
-                                                                         resources);
 
                     def.contribute(module, resources, validating);
                 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapper.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapper.java?rev=731061&r1=731060&r2=731061&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapper.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapper.java Sat Jan  3 10:19:54 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009 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.
@@ -37,6 +37,8 @@
 {
     private final Map<K, V> map;
 
+    private final Map<K, MappedConfigurationOverride<K, V>> overrides;
+
     private final String serviceId;
 
     private final ContributionDef contributionDef;
@@ -49,12 +51,14 @@
 
     private final ObjectLocator locator;
 
-    public ValidatingMappedConfigurationWrapper(Map<K, V> map, String serviceId, ContributionDef contributionDef,
+    public ValidatingMappedConfigurationWrapper(Map<K, V> map, Map<K, MappedConfigurationOverride<K, V>> overrides,
+                                                String serviceId, ContributionDef contributionDef,
                                                 Class<K> expectedKeyType, Class<V> expectedValueType,
                                                 Map<K, ContributionDef> keyToContributor,
                                                 ObjectLocator locator)
     {
         this.map = map;
+        this.overrides = overrides;
         this.serviceId = serviceId;
         this.contributionDef = contributionDef;
         this.expectedKeyType = expectedKeyType;
@@ -65,21 +69,13 @@
 
     public void add(K key, V value)
     {
-        if (key == null)
-            throw new NullPointerException(IOCMessages.contributionKeyWasNull(serviceId));
-
-        if (!expectedKeyType.isInstance(key))
-            throw new IllegalArgumentException(
-                    IOCMessages.contributionWrongKeyType(serviceId, key
-                            .getClass(), expectedKeyType));
+        validateKey(key);
 
         if (value == null)
             throw new NullPointerException(IOCMessages.contributionWasNull(serviceId));
 
 
-        if (!expectedValueType.isInstance(value))
-            throw new IllegalArgumentException(IOCMessages.contributionWrongValueType(serviceId, value
-                    .getClass(), expectedValueType));
+        validateValue(value);
 
         ContributionDef existing = keyToContributor.get(key);
 
@@ -94,10 +90,51 @@
         keyToContributor.put(key, contributionDef);
     }
 
+    private void validateValue(V value)
+    {
+        if (!expectedValueType.isInstance(value))
+            throw new IllegalArgumentException(IOCMessages.contributionWrongValueType(serviceId, value
+                    .getClass(), expectedValueType));
+    }
+
+    private void validateKey(K key)
+    {
+        if (key == null)
+            throw new NullPointerException(IOCMessages.contributionKeyWasNull(serviceId));
+
+        if (!expectedKeyType.isInstance(key))
+            throw new IllegalArgumentException(
+                    IOCMessages.contributionWrongKeyType(serviceId, key
+                            .getClass(), expectedKeyType));
+    }
+
     public void addInstance(K key, Class<? extends V> clazz)
     {
         V value = locator.autobuild(clazz);
 
         add(key, value);
     }
+
+    public void override(K key, V value)
+    {
+        validateKey(key);
+
+        if (value != null) validateValue(value);
+
+        MappedConfigurationOverride<K, V> existing = overrides.get(key);
+
+        if (existing != null)
+            throw new IllegalArgumentException(
+                    String.format("Contribution key %s has already been overridden (by %s).",
+                                  key, existing.getContribDef()));
+
+
+        overrides.put(key, new MappedConfigurationOverride<K, V>(contributionDef, map, key, value));
+    }
+
+
+    public void overrideInstance(K key, Class<? extends V> clazz)
+    {
+        override(key, locator.autobuild(clazz));
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/configuration.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/configuration.apt?rev=731061&r1=731060&r2=731061&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/configuration.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/configuration.apt Sat Jan  3 10:19:54 2009
@@ -10,10 +10,11 @@
   
   So ... nice term, what does it mean?
   
-  Distributed configuration is the key feature of Tapestry IoC that supports <extensibility>.
+  Distributed configuration is the key feature of Tapestry IoC that supports <extensibility>
+  and <modularity>.
   
   The distributed part refers to the fact that <any module> may make <contributions> to 
-  any service's configuration (subject to the normal visibility rules for private services).
+  any service's configuration.
   
   This seems esoteric, but is quite handy, and is best explained by example.
   
@@ -249,3 +250,17 @@
   []
   
   No annotation is needed for these cases.
+
+Configuration Overrides
+
+  <<New in 5.1>> The OrderedConfiguration and MappedConfiguration interfaces now support overrides.  An override is a replacement
+  for a normally contributed object. An override <must> match a contributed object, and each contributed object may be overidden
+  at most once.
+
+  The new object replaces the original object; alternately, you may override the original object with null.
+
+  This allows you to fine tune configuration values that are contributed from modules that you are using, rather than just those
+  that you write yourself.  It is powerful and a bit dangerous.
+
+  In Tapestry 5.0, services that wanted to support this kind of override behavior had to implement it on an ad-hoc basis,
+  such as ApplicationDefaults overriding FactoryDefaults.  In many cases, that is stil useful.
\ No newline at end of file

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/BarneyModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/BarneyModule.java?rev=731061&r1=731060&r2=731061&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/BarneyModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/BarneyModule.java Sat Jan  3 10:19:54 2009
@@ -30,7 +30,7 @@
 public class BarneyModule
 {
     @Match(
-            { "UnorderedNames", "Fred", "PrivateFredAlias" })
+            {"UnorderedNames", "Fred", "PrivateFredAlias"})
     @Order("after:Beta")
     public Object decorateGamma(Object delegate, DecoratorList list)
     {
@@ -53,7 +53,6 @@
 
                 return 1;
             }
-
         };
     }
 
@@ -112,4 +111,10 @@
     {
         configuration.add("Gamma");
     }
+
+    public void contributeStringLookup(MappedConfiguration<String, String> configuration)
+    {
+        configuration.add("barney", "BARNEY");
+        configuration.add("betty", "BETTY");
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/ConfigurationOverrideModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/ConfigurationOverrideModule.java?rev=731061&r1=731060&r2=731061&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/ConfigurationOverrideModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/ConfigurationOverrideModule.java Sat Jan  3 10:19:54 2009
@@ -21,4 +21,10 @@
         configuration.add("wilma", "WILMA", "after:barney");
         configuration.override("fred", "Mr. Flintstone", "after:*");
     }
+
+    public void contributeStringLookup(MappedConfiguration<String, String> configuration)
+    {
+        configuration.override("fred", "Mr. Flintstone");
+        configuration.override("wilma", null);
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/DuplicateConfigurationOverrideModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/DuplicateConfigurationOverrideModule.java?rev=731061&r1=731060&r2=731061&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/DuplicateConfigurationOverrideModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/DuplicateConfigurationOverrideModule.java Sat Jan  3 10:19:54 2009
@@ -20,5 +20,10 @@
     {
         configuration.override("fred", "Fred Flintstone");
     }
+
+    public void contributeStringLookup(MappedConfiguration<String, String> configuration)
+    {
+        configuration.override("fred", "Frederick Flintstone");
+    }
 }
 

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FredModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FredModule.java?rev=731061&r1=731060&r2=731061&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FredModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FredModule.java Sat Jan  3 10:19:54 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2009 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.
@@ -17,10 +17,12 @@
 import org.apache.tapestry5.ioc.annotations.Match;
 import org.apache.tapestry5.ioc.annotations.Order;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Module used to demonstrate decorator ordering.
@@ -43,7 +45,7 @@
     }
 
     @Match(
-            { "UnorderedNames", "Fred" })
+            {"UnorderedNames", "Fred"})
     @Order("before:Beta")
     public Object decorateAlpha(Object delegate, DecoratorList list)
     {
@@ -53,7 +55,7 @@
     }
 
     @Match(
-            { "UnorderedNames", "Fred" })
+            {"UnorderedNames", "Fred"})
     public Object decorateBeta(Object delegate, DecoratorList list)
     {
         list.add("beta");
@@ -74,7 +76,6 @@
             {
                 return sorted;
             }
-
         };
     }
 
@@ -87,7 +88,6 @@
             {
                 return configuration;
             }
-
         };
     }
 
@@ -104,4 +104,26 @@
         configuration.add("UnorderedNames");
         configuration.add("Beta");
     }
+
+    public StringLookup buildStringLookup(final Map<String, String> configuration)
+    {
+        return new StringLookup()
+        {
+            public String lookup(String key)
+            {
+                return configuration.get(key);
+            }
+
+            public List<String> keys()
+            {
+                return InternalUtils.sortedKeys(configuration);
+            }
+        };
+    }
+
+    public void contributeStringLookup(MappedConfiguration<String, String> configuration)
+    {
+        configuration.add("fred", "FRED");
+        configuration.add("wilma", "WILMA");
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java?rev=731061&r1=731060&r2=731061&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java Sat Jan  3 10:19:54 2009
@@ -16,6 +16,7 @@
 
 import org.apache.tapestry5.ioc.internal.*;
 import org.apache.tapestry5.ioc.services.*;
+import org.apache.tapestry5.ioc.util.NonmatchingMappedConfigurationOverrideModule;
 import org.easymock.EasyMock;
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -1120,6 +1121,9 @@
         r.shutdown();
     }
 
+    /**
+     * TAP5-430
+     */
     @Test
     public void bind_service_marked_for_no_decoration_explicitly()
     {
@@ -1132,6 +1136,9 @@
         r.shutdown();
     }
 
+    /**
+     * TAP5-430
+     */
     @Test
     public void bind_service_with_prevent_service_decoration_annotations_on_implementation_class()
     {
@@ -1144,6 +1151,9 @@
         r.shutdown();
     }
 
+    /**
+     * TAP5-437
+     */
     @Test
     public void successful_ordered_configuration_override()
     {
@@ -1156,6 +1166,9 @@
         assertEquals(names, Arrays.asList("BARNEY", "WILMA", "Mr. Flintstone"));
     }
 
+    /**
+     * TAP5-437
+     */
     @Test
     public void failed_ordered_configuration_override()
     {
@@ -1176,6 +1189,9 @@
         }
     }
 
+    /**
+     * TAP5-437
+     */
     @Test
     public void duplicate_ordered_configuration_override()
     {
@@ -1197,4 +1213,71 @@
                                   "Contribution 'fred' has already been overridden");
         }
     }
+
+    /**
+     * TAP5-437
+     */
+    @Test
+    public void mapped_configuration_override()
+    {
+        Registry r = buildRegistry(FredModule.class, BarneyModule.class, ConfigurationOverrideModule.class);
+
+        StringLookup sl = r.getService(StringLookup.class);
+
+        // Due to override wilma to null:
+
+        assertListsEquals(sl.keys(), "barney", "betty", "fred");
+
+        assertEquals(sl.lookup("fred"), "Mr. Flintstone");
+    }
+
+    /**
+     * TAP5-437
+     */
+    @Test
+    public void nonmatching_mapped_configuration_override()
+    {
+        Registry r = buildRegistry(FredModule.class, BarneyModule.class,
+                                   NonmatchingMappedConfigurationOverrideModule.class);
+
+        StringLookup sl = r.getService(StringLookup.class);
+
+        try
+        {
+            sl.keys();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex,
+                                  "Exception constructing service 'StringLookup'",
+                                  "Error invoking service builder method org.apache.tapestry5.ioc.FredModule.buildStringLookup(Map) ",
+                                  "Override for key alley cat (at org.apache.tapestry5.ioc.util.NonmatchingMappedConfigurationOverrideModule.contributeStringLookup(MappedConfiguration)",
+                                  "does not match an existing key.");
+        }
+    }
+
+    /**
+     * TAP-437
+     */
+    @Test
+    public void duplicate_override_for_mapped_configuration()
+    {
+        Registry r = buildRegistry(FredModule.class, BarneyModule.class,
+                                   ConfigurationOverrideModule.class, DuplicateConfigurationOverrideModule.class);
+
+        StringLookup sl = r.getService(StringLookup.class);
+
+        try
+        {
+            sl.keys();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex,
+                                  "Error invoking service contribution method org.apache.tapestry5.ioc.ConfigurationOverrideModule.contributeStringLookup(MappedConfiguration)",
+                                  "Contribution key fred has already been overridden");
+        }
+    }
 }

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/StringLookup.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/StringLookup.java?rev=731061&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/StringLookup.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/StringLookup.java Sat Jan  3 10:19:54 2009
@@ -0,0 +1,30 @@
+// Copyright 2009 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
+//
+// 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.apache.tapestry5.ioc;
+
+import java.util.List;
+
+public interface StringLookup
+{
+    /**
+     * Returns value for given key.
+     */
+    String lookup(String key);
+
+    /**
+     * Returns sorted list of keys.
+     */
+    List<String> keys();
+}

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapperTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapperTest.java?rev=731061&r1=731060&r2=731061&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapperTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapperTest.java Sat Jan  3 10:19:54 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009 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.
@@ -42,7 +42,7 @@
         replay();
 
         MappedConfiguration<Class, Runnable> wrapper = new ValidatingMappedConfigurationWrapper<Class, Runnable>(
-                map, SERVICE_ID, def, Class.class, Runnable.class, keyToContribution, locator);
+                map, null, SERVICE_ID, def, Class.class, Runnable.class, keyToContribution, locator);
 
         wrapper.add(key, value);
 
@@ -69,7 +69,7 @@
         replay();
 
         MappedConfiguration<Class, Runnable> wrapper = new ValidatingMappedConfigurationWrapper<Class, Runnable>(
-                map, SERVICE_ID, def2, Class.class, Runnable.class, keyToContribution, locator);
+                map, null, SERVICE_ID, def2, Class.class, Runnable.class, keyToContribution, locator);
 
         try
         {
@@ -100,7 +100,7 @@
         replay();
 
         MappedConfiguration<Class, Runnable> wrapper = new ValidatingMappedConfigurationWrapper<Class, Runnable>(
-                map, SERVICE_ID, def, Class.class, Runnable.class, keyToContribution, locator);
+                map, null, SERVICE_ID, def, Class.class, Runnable.class, keyToContribution, locator);
 
         try
         {
@@ -129,7 +129,7 @@
 
         replay();
 
-        MappedConfiguration wrapper = new ValidatingMappedConfigurationWrapper(map, SERVICE_ID, def,
+        MappedConfiguration wrapper = new ValidatingMappedConfigurationWrapper(map, null, SERVICE_ID, def,
                                                                                Class.class, Runnable.class,
                                                                                keyToContribution, locator);
 
@@ -161,7 +161,7 @@
 
         replay();
 
-        MappedConfiguration wrapper = new ValidatingMappedConfigurationWrapper(map, SERVICE_ID, def,
+        MappedConfiguration wrapper = new ValidatingMappedConfigurationWrapper(map, null, SERVICE_ID, def,
                                                                                Class.class, Runnable.class,
                                                                                keyToContribution, locator);
 
@@ -192,7 +192,7 @@
         replay();
 
         MappedConfiguration<Class, Runnable> wrapper = new ValidatingMappedConfigurationWrapper<Class, Runnable>(
-                map, SERVICE_ID, def, Class.class, Runnable.class, keyToContribution, locator);
+                map, null, SERVICE_ID, def, Class.class, Runnable.class, keyToContribution, locator);
 
         try
         {

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/NonmatchingMappedConfigurationOverrideModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/NonmatchingMappedConfigurationOverrideModule.java?rev=731061&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/NonmatchingMappedConfigurationOverrideModule.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/NonmatchingMappedConfigurationOverrideModule.java Sat Jan  3 10:19:54 2009
@@ -0,0 +1,25 @@
+// Copyright 2009 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
+//
+// 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.apache.tapestry5.ioc.util;
+
+import org.apache.tapestry5.ioc.MappedConfiguration;
+
+public class NonmatchingMappedConfigurationOverrideModule
+{
+    public void contributeStringLookup(MappedConfiguration<String, String> configuration)
+    {
+        configuration.override("alley cat", "ALLEY CAT");
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/resources/log4j.properties?rev=731061&r1=731060&r2=731061&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/resources/log4j.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/resources/log4j.properties Sat Jan  3 10:19:54 2009
@@ -1,17 +1,17 @@
-# Copyright 2005, 2006 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
-#
-# 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.
-
+# Copyright 2005, 2006, 2009 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
+#
+# 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.
+
 log4j.rootCategory=WARN, A1
 
 # A1 is set to be a ConsoleAppender. 
@@ -25,3 +25,6 @@
 log4j.category.tapestry=error
 log4j.category.tapestry.ioc.ClassFactory=error
 
+log4j.category.org.apache.tapestry5.ioc.FredModule=debug
+
+