You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2006/07/27 20:11:13 UTC

svn commit: r426176 - in /tapestry/tapestry5/tapestry-core/trunk/src: main/java/org/apache/tapestry/internal/ioc/ main/java/org/apache/tapestry/ioc/ main/java/org/apache/tapestry/test/ main/java/org/apache/tapestry/util/ test/java/org/apache/tapestry/i...

Author: hlship
Date: Thu Jul 27 11:11:12 2006
New Revision: 426176

URL: http://svn.apache.org/viewvc?rev=426176&view=rev
Log:
Complete support for mapped configurations.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/Sizer.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InternalRegistry.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/Module.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvoker.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceResourcesImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingMappedConfigurationWrapper.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceCreatorResources.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceDecorator.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/BodyBuilder.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvokerTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ValidatingMappedConfigurationWrapperTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/BarneyModule.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InternalRegistry.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InternalRegistry.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InternalRegistry.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InternalRegistry.java Thu Jul 27 11:11:12 2006
@@ -16,6 +16,7 @@
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.tapestry.ioc.LogSource;
 import org.apache.tapestry.ioc.Registry;
@@ -91,11 +92,11 @@
      * @param <T>
      * @param serviceDef
      *            defines the service for which configuration data is being assembled
-     * @param objectType
+     * @param valueType
      *            identifies the type of object allowed into the collection
      * @return the final collection
      */
-    <T> Collection<T> getUnorderedConfiguration(ServiceDef serviceDef, Class<T> objectType);
+    <T> Collection<T> getUnorderedConfiguration(ServiceDef serviceDef, Class<T> valueType);
 
     /**
      * Builds up an ordered collection by invoking service contributor methods that target the
@@ -106,9 +107,28 @@
      * @param <T>
      * @param serviceDef
      *            defines the service for which configuration data is being assembled
-     * @param objectType
+     * @param valueType
      *            identifies the type of object allowed into the collection
      * @return the final ordered list
      */
-    <T> List<T> getOrderedConfiguration(ServiceDef serviceDef, Class<T> objectType);
+    <T> List<T> getOrderedConfiguration(ServiceDef serviceDef, Class<T> valueType);
+
+    /**
+     * Builds up a map of key/value pairs by invoking service contribution methods that tharget the
+     * service (from any module, unless the service is private). Values and keys may not be null.
+     * Invalid values (keys or values that are the wrong type, or duplicate keys) result in warnings
+     * and are ignored.
+     * 
+     * @param <K,
+     *            V>
+     * @param serviceDef
+     *            defines the service for which configuration data is being assembled
+     * @param keyType
+     *            identifies the type of key object allowed into the map
+     * @param valueType
+     *            identifies the type of value object allowed into the map
+     * @return the final ordered list
+     */
+    <K, V> Map<K, V> getMappedConfiguration(ServiceDef serviceDef, Class<K> keyType,
+            Class<V> valueType);
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/Module.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/Module.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/Module.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/Module.java Thu Jul 27 11:11:12 2006
@@ -94,13 +94,4 @@
 
     /** Finds any contributions that are targetted at the indicated service. */
     Set<ContributionDef> getContributorDefsForService(String serviceId);
-
-    /**
-     * Assembles an unordered configuration by invoking any appropriate service contribution
-     * methods.
-     */
-    <T> Collection<T> getUnorderedConfiguration(String serviceId, Class<T> objectType);
-
-    /** Assembles an ordered configuration by invoking any appropriate service contribution methods. */
-    <T> List<T> getOrderedConfiguration(String serviceId, Class<T> objectType);
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java Thu Jul 27 11:11:12 2006
@@ -365,19 +365,4 @@
 
         return result;
     }
-
-    public <T> Collection<T> getUnorderedConfiguration(String serviceId, Class<T> objectType)
-    {
-        ServiceDef def = _moduleDef.getServiceDef(serviceId);
-
-        return _registry.getUnorderedConfiguration(def, objectType);
-    }
-
-    public <T> List<T> getOrderedConfiguration(String serviceId, Class<T> objectType)
-    {
-        ServiceDef def = _moduleDef.getServiceDef(serviceId);
-
-        return _registry.getOrderedConfiguration(def, objectType);
-    }
-
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java Thu Jul 27 11:11:12 2006
@@ -27,6 +27,7 @@
 import org.apache.tapestry.ioc.Configuration;
 import org.apache.tapestry.ioc.IOCUtilities;
 import org.apache.tapestry.ioc.LogSource;
+import org.apache.tapestry.ioc.MappedConfiguration;
 import org.apache.tapestry.ioc.OrderedConfiguration;
 import org.apache.tapestry.ioc.Registry;
 import org.apache.tapestry.ioc.ServiceDecorator;
@@ -160,6 +161,36 @@
         return orderer.getOrdered();
     }
 
+    public <K, V> Map<K, V> getMappedConfiguration(ServiceDef serviceDef, Class<K> keyType,
+            Class<V> objectType)
+    {
+        final Map<K, V> result = newMap();
+
+        MappedConfiguration<K, V> configuration = new MappedConfiguration<K, V>()
+        {
+            @SuppressNullCheck
+            public void add(K key, V value)
+            {
+                result.put(key, value);
+            }
+        };
+
+        Map<K, ContributionDef> keyToContribution = newMap();
+
+        Collection<Module> modules = modulesThatContributeToService(serviceDef);
+
+        for (Module m : modules)
+            addToMappedConfiguration(
+                    configuration,
+                    keyToContribution,
+                    keyType,
+                    objectType,
+                    serviceDef,
+                    m);
+
+        return result;
+    }
+
     private Collection<Module> modulesThatContributeToService(ServiceDef serviceDef)
     {
         if (serviceDef.isPrivate())
@@ -173,8 +204,33 @@
         return _modules.values();
     }
 
+    private <K, V> void addToMappedConfiguration(MappedConfiguration<K, V> configuration,
+            Map<K, ContributionDef> keyToContribution, Class<K> keyClass, Class<V> valueType,
+            ServiceDef serviceDef, Module module)
+    {
+        String serviceId = serviceDef.getServiceId();
+        Set<ContributionDef> contributions = module.getContributorDefsForService(serviceId);
+
+        if (contributions.isEmpty())
+            return;
+
+        Log log = getLog(serviceId);
+
+        Object moduleBuilder = module.getModuleBuilder();
+        ServiceLocator locator = new ServiceResourcesImpl(this, module, serviceDef, log);
+
+        for (ContributionDef def : contributions)
+        {
+            MappedConfiguration<K, V> validating = new ValidatingMappedConfigurationWrapper<K, V>(
+                    serviceId, def, log, keyClass, valueType, keyToContribution, configuration);
+
+            def.contribute(moduleBuilder, locator, validating);
+        }
+
+    }
+
     private <T> void addToUnorderedConfiguration(Configuration<T> configuration,
-            Class<T> objectType, ServiceDef serviceDef, Module module)
+            Class<T> valueType, ServiceDef serviceDef, Module module)
     {
         String serviceId = serviceDef.getServiceId();
         Set<ContributionDef> contributions = module.getContributorDefsForService(serviceId);
@@ -189,15 +245,15 @@
 
         for (ContributionDef def : contributions)
         {
-            Configuration<T> validating = new ValidatingConfigurationWrapper(serviceId, log,
-                    objectType, def, configuration);
+            Configuration<T> validating = new ValidatingConfigurationWrapper<T>(serviceId, log,
+                    valueType, def, configuration);
 
             def.contribute(moduleBuilder, locator, validating);
         }
     }
 
     private <T> void addToOrderedConfiguration(OrderedConfiguration<T> configuration,
-            Class<T> objectType, ServiceDef serviceDef, Module module)
+            Class<T> valueType, ServiceDef serviceDef, Module module)
     {
         String serviceId = serviceDef.getServiceId();
         Set<ContributionDef> contributions = module.getContributorDefsForService(serviceId);
@@ -213,7 +269,7 @@
         for (ContributionDef def : contributions)
         {
             OrderedConfiguration<T> validating = new ValidatingOrderedConfigurationWrapper<T>(
-                    serviceId, module.getModuleId(), def, log, objectType, configuration);
+                    serviceId, module.getModuleId(), def, log, valueType, configuration);
 
             def.contribute(moduleBuilder, locator, validating);
         }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvoker.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvoker.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvoker.java Thu Jul 27 11:11:12 2006
@@ -127,8 +127,12 @@
 
                     break;
 
-                default:
-                    throw new IllegalArgumentException(type + " not yet supported.");
+                case MAPPED:
+
+                    addMappedConfigurationParameter(result, genericType);
+
+                    break;
+
             }
 
         }
@@ -136,24 +140,41 @@
         return result;
     }
 
+    @SuppressWarnings("unchecked")
     private void addOrderedConfigurationParameter(Map<Class, Object> parameterDefaults,
             Type genericType)
     {
-        Class valueType = parameterizedType(genericType);
+        Class valueType = findParameterizedTypeFromGenericType(genericType);
         List configuration = _resources.getOrderedConfiguration(valueType);
 
         parameterDefaults.put(List.class, configuration);
     }
 
+    @SuppressWarnings("unchecked")
     private void addUnorderedConfigurationParameter(Map<Class, Object> parameterDefaults,
             Type genericType)
     {
-        Class valueType = parameterizedType(genericType);
+        Class valueType = findParameterizedTypeFromGenericType(genericType);
         Collection configuration = _resources.getUnorderedConfiguration(valueType);
 
         parameterDefaults.put(Collection.class, configuration);
     }
 
+    @SuppressWarnings("unchecked")
+    private void addMappedConfigurationParameter(Map<Class, Object> parameterDefaults,
+            Type genericType)
+    {
+        Class keyType = findParameterizedTypeFromGenericType(genericType, 0);
+        Class valueType = findParameterizedTypeFromGenericType(genericType, 1);
+
+        if (keyType == null || valueType == null)
+            throw new IllegalArgumentException(IOCMessages.genericTypeNotSupported(genericType));
+
+        Map configuration = _resources.getMappedConfiguration(keyType, valueType);
+
+        parameterDefaults.put(Map.class, configuration);
+    }
+
     /**
      * Extracts from a generic type the underlying parameterized type. I.e., for List<Runnable>,
      * will return Runnable. This is limited to simple parameterized types, not the more complex
@@ -165,9 +186,9 @@
      */
 
     // package private for testing
-    static Class parameterizedType(Type type)
+    static Class findParameterizedTypeFromGenericType(Type type)
     {
-        Class result = findParameterizedTypeFromGenericType(type);
+        Class result = findParameterizedTypeFromGenericType(type, 0);
 
         if (result == null)
             throw new IllegalArgumentException(IOCMessages.genericTypeNotSupported(type));
@@ -175,7 +196,20 @@
         return result;
     }
 
-    private static Class findParameterizedTypeFromGenericType(Type type)
+    /**
+     * "Sniffs" a generic type to find the underlying parameterized type. If the Type is a class,
+     * then Object.class is returned. Otherwise, the type must be a ParameterizedType. We check to
+     * make sure it has the correct number of a actual types (1 for a Collection or List, 2 for a
+     * Map). The actual types must be classes (wildcards just aren't supported)
+     * 
+     * @param type
+     *            a Class or ParameterizedType to inspect
+     * @param typeIndex
+     *            the index within the ParameterizedType to extract
+     * @return the actual type, or Object.class if the input type is not generic, or null if any
+     *         other pre-condition is not met
+     */
+    private static Class findParameterizedTypeFromGenericType(Type type, int typeIndex)
     {
         // For a raw Class type, it means the parameter is not parameterized (i.e. Collection, not
         // Collection<Foo>), so we can return Object.class to allow no restriction.
@@ -189,10 +223,8 @@
         ParameterizedType pt = (ParameterizedType) type;
 
         Type[] types = pt.getActualTypeArguments();
-        if (types.length != 1)
-            return null;
 
-        Type actualType = types[0];
+        Type actualType = types[typeIndex];
 
         return actualType instanceof Class ? (Class) actualType : null;
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceResourcesImpl.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceResourcesImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceResourcesImpl.java Thu Jul 27 11:11:12 2006
@@ -16,6 +16,7 @@
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.commons.logging.Log;
 import org.apache.tapestry.ioc.ServiceCreatorResources;
@@ -80,14 +81,19 @@
         return _log;
     }
 
-    public <T> Collection<T> getUnorderedConfiguration(Class<T> objectType)
+    public <T> Collection<T> getUnorderedConfiguration(Class<T> valueType)
     {
-        return _module.getUnorderedConfiguration(_serviceDef.getServiceId(), objectType);
+        return _registry.getUnorderedConfiguration(_serviceDef, valueType);
     }
 
-    public <T> List<T> getOrderedConfiguration(Class<T> objectType)
+    public <T> List<T> getOrderedConfiguration(Class<T> valueType)
     {
-        return _module.getOrderedConfiguration(_serviceDef.getServiceId(), objectType);
+        return _registry.getOrderedConfiguration(_serviceDef, valueType);
+    }
+
+    public <K, V> Map<K, V> getMappedConfiguration(Class<K> keyType, Class<V> valueType)
+    {
+        return _registry.getMappedConfiguration(_serviceDef, keyType, valueType);
     }
 
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingMappedConfigurationWrapper.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingMappedConfigurationWrapper.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingMappedConfigurationWrapper.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingMappedConfigurationWrapper.java Thu Jul 27 11:11:12 2006
@@ -1,3 +1,17 @@
+// Copyright 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.
+
 package org.apache.tapestry.internal.ioc;
 
 import java.util.Map;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceCreatorResources.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceCreatorResources.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceCreatorResources.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceCreatorResources.java Thu Jul 27 11:11:12 2006
@@ -16,6 +16,7 @@
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Extends {@link org.apache.tapestry.ioc.ServiceResources} with additional methods needed only by
@@ -25,9 +26,9 @@
  */
 public interface ServiceCreatorResources extends ServiceResources
 {
-    <T> Collection<T> getUnorderedConfiguration(Class<T> objectType);
+    <T> Collection<T> getUnorderedConfiguration(Class<T> valueType);
 
-    <T> List<T> getOrderedConfiguration(Class<T> objectType);
+    <T> List<T> getOrderedConfiguration(Class<T> valueType);
 
-    // More to come!
+    <K, V> Map<K, V> getMappedConfiguration(Class<K> keyType, Class<V> valueType);
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceDecorator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceDecorator.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceDecorator.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceDecorator.java Thu Jul 27 11:11:12 2006
@@ -24,7 +24,8 @@
 public interface ServiceDecorator
 {
     /**
-     * Creates a new object implementing the same service interface as the delegate object.
+     * Creates a new interceptor object implementing the same service interface as the delegate
+     * object.
      * 
      * @param delegate
      *            an existing object implementing the service interface.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java Thu Jul 27 11:11:12 2006
@@ -272,12 +272,14 @@
         return newMock(ServiceLocator.class);
     }
 
+    @SuppressWarnings("unchecked")
     protected final <T> OrderedConfiguration<T> newOrderedConfiguration()
     {
         return newMock(OrderedConfiguration.class);
     }
 
-    protected final MappedConfiguration newMappedConfiguration()
+    @SuppressWarnings("unchecked")
+    protected final <K, V> MappedConfiguration<K, V> newMappedConfiguration()
     {
         return newMock(MappedConfiguration.class);
     }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/BodyBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/BodyBuilder.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/BodyBuilder.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/BodyBuilder.java Thu Jul 27 11:11:12 2006
@@ -17,11 +17,11 @@
 import java.util.Formatter;
 
 /**
- * Utility class for assembling the <em>body</em> used with Javassist as a method. Basically,
- * assists with formatting and with indentation. This makes the code that assembles a method body
- * much simpler ... and it makes the result neater, which will be easier to debug (debugging
- * dynamically generated code is hard enough that it should be easy to read the input code before
- * worrying about why it doesn't compile or execute properly).
+ * Utility class for assembling the <em>body</em> used with Javassist when defining a method or
+ * constructor. Basically, assists with formatting and with indentation. This makes the code that
+ * assembles a method body much simpler ... and it makes the result neater, which will be easier to
+ * debug (debugging dynamically generated code is hard enough that it should be easy to read the
+ * input code before worrying about why it doesn't compile or execute properly).
  * <p>
  * This class is not threadsafe.
  * 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvokerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvokerTest.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvokerTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvokerTest.java Thu Jul 27 11:11:12 2006
@@ -29,7 +29,7 @@
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import static org.apache.tapestry.internal.ioc.ServiceBuilderMethodInvoker.parameterizedType;
+import static org.apache.tapestry.internal.ioc.ServiceBuilderMethodInvoker.findParameterizedTypeFromGenericType;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertSame;
 
@@ -325,7 +325,7 @@
         Type type = m.getGenericParameterTypes()[0];
 
         assertEquals(type.toString(), "java.util.List<java.lang.Runnable>");
-        assertEquals(parameterizedType(type), Runnable.class);
+        assertEquals(findParameterizedTypeFromGenericType(type), Runnable.class);
     }
 
     public void methodWithParameterizedList(List<Runnable> list)
@@ -341,7 +341,7 @@
         Type type = m.getGenericParameterTypes()[0];
 
         assertEquals(type.toString(), "interface java.util.List");
-        assertEquals(parameterizedType(type), Object.class);
+        assertEquals(findParameterizedTypeFromGenericType(type), Object.class);
     }
 
     public void methodWithList(List list)
@@ -359,7 +359,7 @@
 
         try
         {
-            parameterizedType(type);
+            findParameterizedTypeFromGenericType(type);
             unreachable();
         }
         catch (IllegalArgumentException ex)

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ValidatingMappedConfigurationWrapperTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ValidatingMappedConfigurationWrapperTest.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ValidatingMappedConfigurationWrapperTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ValidatingMappedConfigurationWrapperTest.java Thu Jul 27 11:11:12 2006
@@ -1,5 +1,20 @@
+// Copyright 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.
+
 package org.apache.tapestry.internal.ioc;
 
+import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.logging.Log;
@@ -9,6 +24,7 @@
 import org.testng.annotations.Test;
 
 import static org.apache.tapestry.util.CollectionFactory.newMap;
+import static org.testng.Assert.assertSame;
 
 /**
  * @author Howard M. Lewis Ship
@@ -17,9 +33,6 @@
 {
     private static final String SERVICE_ID = "foo.bar.Baz";
 
-    private static final String CLASS_NAME = ValidatingMappedConfigurationWrapperTest.class
-            .getName();
-
     @Test
     public void proper_key_and_value()
     {
@@ -41,6 +54,37 @@
         wrapper.add(key, value);
 
         verify();
+
+        assertSame(keyToContribution.get(Integer.class), def);
+    }
+
+    @Test
+    public void duplicate_key()
+    {
+        ContributionDef def1 = newContributionDef("contributionPlaceholder1");
+        ContributionDef def2 = newContributionDef("contributionPlaceholder2");
+        Log log = newLog();
+        Map<Class, ContributionDef> keyToContribution = newMap();
+
+        keyToContribution.put(Integer.class, def1);
+
+        MappedConfiguration<Class, Runnable> delegate = newMappedConfiguration();
+
+        Class key = Integer.class;
+        Runnable value = newRunnable();
+
+        log.warn(IOCMessages.contributionDuplicateKey(SERVICE_ID, def2, def1));
+
+        replay();
+
+        MappedConfiguration<Class, Runnable> wrapper = new ValidatingMappedConfigurationWrapper<Class, Runnable>(
+                SERVICE_ID, def2, log, Class.class, Runnable.class, keyToContribution, delegate);
+
+        wrapper.add(key, value);
+
+        verify();
+
+        assertSame(keyToContribution.get(Integer.class), def1);
     }
 
     @Test
@@ -60,6 +104,53 @@
                 SERVICE_ID, def, log, Class.class, Runnable.class, keyToContribution, delegate);
 
         wrapper.add(null, value);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void wrong_key_type()
+    {
+        ContributionDef def = newContributionDef("contributionPlaceholder1");
+        Log log = newLog();
+        Map<?, ContributionDef> keyToContribution = newMap();
+        MappedConfiguration delegate = newMappedConfiguration();
+        Runnable value = newRunnable();
+
+        log.warn(IOCMessages.contributionWrongKeyType(SERVICE_ID, def, String.class, Class.class));
+
+        replay();
+
+        MappedConfiguration wrapper = new ValidatingMappedConfigurationWrapper(SERVICE_ID, def,
+                log, Class.class, Runnable.class, keyToContribution, delegate);
+
+        wrapper.add("java.util.List", value);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void wrong_value_type()
+    {
+        ContributionDef def = newContributionDef("contributionPlaceholder1");
+        Log log = newLog();
+        Map<?, ContributionDef> keyToContribution = newMap();
+        MappedConfiguration delegate = newMappedConfiguration();
+
+        log.warn(IOCMessages.contributionWrongValueType(
+                SERVICE_ID,
+                def,
+                String.class,
+                Runnable.class));
+
+        replay();
+
+        MappedConfiguration wrapper = new ValidatingMappedConfigurationWrapper(SERVICE_ID, def,
+                log, Class.class, Runnable.class, keyToContribution, delegate);
+
+        wrapper.add(List.class, "do something");
 
         verify();
     }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/BarneyModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/BarneyModule.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/BarneyModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/BarneyModule.java Thu Jul 27 11:11:12 2006
@@ -14,9 +14,13 @@
 
 package org.apache.tapestry.ioc;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.tapestry.annotations.Match;
+import org.apache.tapestry.internal.annotations.SuppressNullCheck;
 import org.apache.tapestry.ioc.annotations.After;
 import org.apache.tapestry.ioc.annotations.Contribute;
 import org.apache.tapestry.ioc.annotations.Id;
@@ -28,7 +32,7 @@
  * 
  * @author Howard M. Lewis Ship
  */
-
+@SuppressNullCheck
 @Id("barney")
 public class BarneyModule
 {
@@ -39,6 +43,55 @@
         list.add("gamma");
 
         return null;
+    }
+
+    public Sizer buildSizer(final Map<Class, Sizer> configuration)
+    {
+        return new Sizer()
+        {
+            public int size(Object object)
+            {
+                if (object == null)
+                    return 0;
+                
+                Sizer sizer = configuration.get(object.getClass());
+
+                if (sizer != null)
+                    return sizer.size(object);
+
+                return 1;
+            }
+
+        };
+    }
+
+    public void contributeSizer(MappedConfiguration<Class, Sizer> configuration)
+    {
+        Sizer listSizer = new Sizer()
+        {
+            public int size(Object object)
+            {
+                List list = (List) object;
+
+                return list.size();
+            }
+        };
+
+        Sizer mapSizer = new Sizer()
+        {
+            public int size(Object object)
+            {
+                Map map = (Map) object;
+
+                return map.size();
+            }
+        };
+
+        // Have to work on concrete class, rather than type, until we move the StrategyFactory
+        // over from HiveMind.
+
+        configuration.add(ArrayList.class, listSizer);
+        configuration.add(HashMap.class, mapSizer);
     }
 
     /**

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java?rev=426176&r1=426175&r2=426176&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java Thu Jul 27 11:11:12 2006
@@ -14,8 +14,11 @@
 
 package org.apache.tapestry.ioc;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.tapestry.internal.ioc.TapestryIOCModule;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
@@ -103,7 +106,7 @@
      * because the code paths are so similar.
      */
 
-    @Test 
+    @Test
     public void service_ordered_configuration()
     {
         Registry r = buildRegistry();
@@ -116,6 +119,36 @@
 
     }
 
+    @SuppressWarnings("unchecked")
+    @Test
+    public void service_mapped_configuration()
+    {
+        Registry r = buildRegistry();
+
+        Sizer sizer = r.getService("barney.Sizer", Sizer.class);
+
+        assertEquals(sizer.size(null), 0);
+
+        // Have to be exact on type here.
+
+        List list = new ArrayList();
+        list.add(1);
+        list.add(2);
+        list.add(3);
+
+        assertEquals(sizer.size(list), 3);
+
+        Map map = new HashMap();
+        map.put("fred", "flinstone");
+        map.put("barney", "rubble");
+
+        assertEquals(sizer.size(map), 2);
+
+        // Random objects are size 1
+
+        assertEquals(sizer.size(this), 1);
+    }
+
     @Test
     public void private_service_unordered_configuration()
     {
@@ -128,6 +161,5 @@
         List<String> names = service.getNames();
 
         assertEquals(names, Arrays.asList("Omega", "PrivateUnorderedNames"));
-
     }
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/Sizer.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/Sizer.java?rev=426176&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/Sizer.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/Sizer.java Thu Jul 27 11:11:12 2006
@@ -0,0 +1,26 @@
+// Copyright 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.
+
+package org.apache.tapestry.ioc;
+
+/**
+ * Encapsulates a strategy for determining the size of an object. Different implementations are
+ * mapped to different types.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public interface Sizer
+{
+    int size(Object object);
+}