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/26 01:37:10 UTC

svn commit: r425558 - 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/ test/java/org/apache/tapestry/internal/ioc/ test/java/org/apache/ta...

Author: hlship
Date: Tue Jul 25 16:37:09 2006
New Revision: 425558

URL: http://svn.apache.org/viewvc?rev=425558&view=rev
Log:
Add supported for ordered configurations and contributions.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingOrderedConfigurationWrapper.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ValidatingOrderedConfigurationWrapperTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/NameListHolder.java
      - copied, changed from r425525, tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/UnorderedNames.java
Removed:
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/UnorderedNames.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ConfigurationType.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ContributionDefImpl.java
    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/ValidatingConfigurationWrapper.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/test/BaseTestCase.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/ioc/FredModule.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/ConfigurationType.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ConfigurationType.java?rev=425558&r1=425557&r2=425558&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ConfigurationType.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ConfigurationType.java Tue Jul 25 16:37:09 2006
@@ -4,7 +4,7 @@
 // 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,

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ContributionDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ContributionDefImpl.java?rev=425558&r1=425557&r2=425558&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ContributionDefImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ContributionDefImpl.java Tue Jul 25 16:37:09 2006
@@ -82,16 +82,6 @@
 
         parameterDefaults.put(parameterType, parameterValue);
 
-        invokeMethod(moduleBuilder, locator, parameterDefaults);
-    }
-
-    private void invokeMethod(Object moduleBuilder, ServiceLocator locator,
-            Map<Class, Object> parameterDefaults)
-    {
-        // Alas, logging of this will occur elsewhere, since
-        // I don't want to clutter up the parameters by passing
-        // in the Log for the service.
-
         Throwable fail = null;
 
         try
@@ -105,7 +95,7 @@
         }
         catch (InvocationTargetException ex)
         {
-            fail = ex;
+            fail = ex.getTargetException();
         }
         catch (Exception ex)
         {

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=425558&r1=425557&r2=425558&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 Tue Jul 25 16:37:09 2006
@@ -95,5 +95,20 @@
      *            identifies the type of object allowed into the collection
      * @return the final collection
      */
-    <T> Collection<T> getUnorderedCollection(ServiceDef serviceDef, Class objectType);
+    <T> Collection<T> getUnorderedConfiguration(ServiceDef serviceDef, Class<T> objectType);
+
+    /**
+     * Builds up an ordered collection by invoking service contributor methods that target the
+     * service (from any module, unless the service is private). Once all values have been added
+     * (each with an id, and pre/post constraints), the values are ordered, null values dropped, and
+     * the final sorted list is returned.
+     * 
+     * @param <T>
+     * @param serviceDef
+     *            defines the service for which configuration data is being assembled
+     * @param objectType
+     *            identifies the type of object allowed into the collection
+     * @return the final ordered list
+     */
+    <T> List<T> getOrderedConfiguration(ServiceDef serviceDef, Class<T> objectType);
 }

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=425558&r1=425557&r2=425558&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 Tue Jul 25 16:37:09 2006
@@ -95,7 +95,12 @@
     /** Finds any contributions that are targetted at the indicated service. */
     Set<ContributionDef> getContributorDefsForService(String serviceId);
 
-    /** Assembles an unordered contribution by invoking any appropriate service contribution methods. */
+    /**
+     * 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=425558&r1=425557&r2=425558&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 Tue Jul 25 16:37:09 2006
@@ -370,7 +370,14 @@
     {
         ServiceDef def = _moduleDef.getServiceDef(serviceId);
 
-        return _registry.getUnorderedCollection(def, objectType);
+        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=425558&r1=425557&r2=425558&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 Tue Jul 25 16:37:09 2006
@@ -14,6 +14,7 @@
 
 package org.apache.tapestry.internal.ioc;
 
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -26,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.OrderedConfiguration;
 import org.apache.tapestry.ioc.Registry;
 import org.apache.tapestry.ioc.ServiceDecorator;
 import org.apache.tapestry.ioc.ServiceLifecycle;
@@ -45,6 +47,28 @@
  */
 public class RegistryImpl implements Registry, InternalRegistry
 {
+    @SuppressNullCheck
+    public static final class OrderedConfigurationToOrdererAdaptor<T> implements
+            OrderedConfiguration<T>
+    {
+        private final Orderer<T> _orderer;
+
+        public OrderedConfigurationToOrdererAdaptor(Orderer<T> orderer)
+        {
+            _orderer = orderer;
+        }
+
+        public void add(String id, String prerequisites, String postrequisites, T object)
+        {
+            _orderer.add(id, prerequisites, postrequisites, object);
+        }
+
+        public void add(String id, T object)
+        {
+            _orderer.add(id, object);
+        }
+    }
+
     private final LogSource _logSource;
 
     /** Keyed on module id. */
@@ -100,7 +124,7 @@
         return module;
     }
 
-    public <T> Collection<T> getUnorderedCollection(ServiceDef serviceDef, Class objectType)
+    public <T> Collection<T> getUnorderedConfiguration(ServiceDef serviceDef, Class<T> objectType)
     {
         final Collection<T> result = newList();
 
@@ -110,32 +134,47 @@
             {
                 result.add(object);
             }
-
         };
 
+        Collection<Module> modules = modulesThatContributeToService(serviceDef);
+
+        for (Module m : modules)
+            addToUnorderedConfiguration(configuration, objectType, serviceDef, m);
+
+        return result;
+    }
+
+    public <T> List<T> getOrderedConfiguration(ServiceDef serviceDef, Class<T> objectType)
+    {
+        Log log = getLog(serviceDef.getServiceId());
+
+        final Orderer<T> orderer = new Orderer<T>(log);
+
+        OrderedConfiguration<T> configuration = new OrderedConfigurationToOrdererAdaptor<T>(orderer);
+
+        Collection<Module> modules = modulesThatContributeToService(serviceDef);
+
+        for (Module m : modules)
+            addToOrderedConfiguration(configuration, objectType, serviceDef, m);
+
+        return orderer.getOrdered();
+    }
+
+    private Collection<Module> modulesThatContributeToService(ServiceDef serviceDef)
+    {
         if (serviceDef.isPrivate())
         {
-            String serviceId = serviceDef.getServiceId();
+            String moduleId = IOCUtilities.extractModuleId(serviceDef.getServiceId());
+            Module module = _modules.get(moduleId);
 
-            addToUnorderedConfiguration(
-                    configuration,
-                    objectType,
-                    serviceDef,
-                    locateModuleForService(serviceId));
-        }
-        else
-        {
-            for (Module m : _modules.values())
-            {
-                addToUnorderedConfiguration(configuration, objectType, serviceDef, m);
-            }
+            return Arrays.asList(module);
         }
 
-        return result;
+        return _modules.values();
     }
 
-    private <T> void addToUnorderedConfiguration(Configuration<T> configuration, Class objectType,
-            ServiceDef serviceDef, Module module)
+    private <T> void addToUnorderedConfiguration(Configuration<T> configuration,
+            Class<T> objectType, ServiceDef serviceDef, Module module)
     {
         String serviceId = serviceDef.getServiceId();
         Set<ContributionDef> contributions = module.getContributorDefsForService(serviceId);
@@ -157,6 +196,29 @@
         }
     }
 
+    private <T> void addToOrderedConfiguration(OrderedConfiguration<T> configuration,
+            Class<T> objectType, 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)
+        {
+            OrderedConfiguration<T> validating = new ValidatingOrderedConfigurationWrapper<T>(
+                    serviceId, module.getModuleId(), def, log, objectType, configuration);
+
+            def.contribute(moduleBuilder, locator, validating);
+        }
+    }
+
     // Seems like something that could be cached.
     @SuppressNullCheck
     public <T> T getService(Class<T> serviceInterface, Module module)
@@ -298,4 +360,5 @@
     {
         return _logSource.getLog(name);
     }
+
 }

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=425558&r1=425557&r2=425558&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 Tue Jul 25 16:37:09 2006
@@ -110,15 +110,20 @@
 
             type = thisType;
 
+            Type genericType = _builderMethod.getGenericParameterTypes()[i];
+
             switch (type)
             {
 
                 case UNORDERED:
 
-                    Class valueType = parameterizedType(_builderMethod.getGenericParameterTypes()[i]);
-                    Collection configuration = _resources.getUnorderedConfiguration(valueType);
+                    addUnorderedConfigurationParameter(result, genericType);
+
+                    break;
+
+                case ORDERED:
 
-                    result.put(Collection.class, configuration);
+                    addOrderedConfigurationParameter(result, genericType);
 
                     break;
 
@@ -129,6 +134,24 @@
         }
 
         return result;
+    }
+
+    private void addOrderedConfigurationParameter(Map<Class, Object> parameterDefaults,
+            Type genericType)
+    {
+        Class valueType = parameterizedType(genericType);
+        List configuration = _resources.getOrderedConfiguration(valueType);
+
+        parameterDefaults.put(List.class, configuration);
+    }
+
+    private void addUnorderedConfigurationParameter(Map<Class, Object> parameterDefaults,
+            Type genericType)
+    {
+        Class valueType = parameterizedType(genericType);
+        Collection configuration = _resources.getUnorderedConfiguration(valueType);
+
+        parameterDefaults.put(Collection.class, configuration);
     }
 
     /**

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=425558&r1=425557&r2=425558&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 Tue Jul 25 16:37:09 2006
@@ -15,6 +15,7 @@
 package org.apache.tapestry.internal.ioc;
 
 import java.util.Collection;
+import java.util.List;
 
 import org.apache.commons.logging.Log;
 import org.apache.tapestry.ioc.ServiceCreatorResources;
@@ -83,4 +84,10 @@
     {
         return _module.getUnorderedConfiguration(_serviceDef.getServiceId(), objectType);
     }
+
+    public <T> List<T> getOrderedConfiguration(Class<T> objectType)
+    {
+        return _module.getOrderedConfiguration(_serviceDef.getServiceId(), objectType);
+    }
+
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingConfigurationWrapper.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingConfigurationWrapper.java?rev=425558&r1=425557&r2=425558&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingConfigurationWrapper.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingConfigurationWrapper.java Tue Jul 25 16:37:09 2006
@@ -24,7 +24,6 @@
  * 
  * @author Howard M. Lewis Ship
  */
-@SuppressNullCheck
 public class ValidatingConfigurationWrapper<T> implements Configuration<T>
 {
     private final String _serviceId;
@@ -35,20 +34,21 @@
 
     private final Configuration _delegate;
 
-    private final Class _expectedClass;
+    private final Class _expectedType;
 
     // Need a strategy for determing the right order for this mass of parameters!
 
-    public ValidatingConfigurationWrapper(String serviceId, Log log, Class expectedClass,
+    public ValidatingConfigurationWrapper(String serviceId, Log log, Class expectedType,
             ContributionDef contributionDef, Configuration delegate)
     {
         _serviceId = serviceId;
-        _contributionDef = contributionDef;
         _log = log;
+        _expectedType = expectedType;
+        _contributionDef = contributionDef;
         _delegate = delegate;
-        _expectedClass = expectedClass;
     }
 
+    @SuppressNullCheck
     public void add(T object)
     {
         if (object == null)
@@ -59,10 +59,10 @@
 
         // Sure, we say it is type T ... but is it really?
 
-        if (!_expectedClass.isInstance(object))
+        if (!_expectedType.isInstance(object))
         {
             _log.warn(IOCMessages.contributionWrongValueType(_serviceId, _contributionDef, object
-                    .getClass(), _expectedClass));
+                    .getClass(), _expectedType));
             return;
         }
 

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingOrderedConfigurationWrapper.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingOrderedConfigurationWrapper.java?rev=425558&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingOrderedConfigurationWrapper.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingOrderedConfigurationWrapper.java Tue Jul 25 16:37:09 2006
@@ -0,0 +1,89 @@
+// 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 org.apache.commons.logging.Log;
+import org.apache.tapestry.internal.annotations.SuppressNullCheck;
+import org.apache.tapestry.ioc.OrderedConfiguration;
+import org.apache.tapestry.ioc.def.ContributionDef;
+
+import static org.apache.tapestry.ioc.IOCUtilities.qualifySimpleIdList;
+import static org.apache.tapestry.ioc.IOCUtilities.toQualifiedId;
+
+/**
+ * Implements validation of values provided to an
+ * {@link org.apache.tapestry.ioc.OrderedConfiguration}. It also takes care of qualifying any ids.
+ * If you provide an incorrect value type, the value is converted to null but added anyway. This
+ * ensures that incorrect values contributed in don't screw up the
+ * {@link org.apache.tapestry.internal.util.Orderer} (and generate a bunch of error messages there).
+ * 
+ * @author Howard M. Lewis Ship
+ * @param <T>
+ */
+public class ValidatingOrderedConfigurationWrapper<T> implements OrderedConfiguration<T>
+{
+    private final String _serviceId;
+
+    /** Module id containing the contribution (not necessarily the service). */
+    private final String _moduleId;
+
+    private final ContributionDef _contributionDef;
+
+    private final Log _log;
+
+    private final Class _expectedType;
+
+    private final OrderedConfiguration<T> _delegate;
+
+    public ValidatingOrderedConfigurationWrapper(String serviceId, String moduleId,
+            ContributionDef contributionDef, Log log, Class expectedType,
+            OrderedConfiguration<T> delegate)
+    {
+        _serviceId = serviceId;
+        _moduleId = moduleId;
+        _contributionDef = contributionDef;
+        _log = log;
+        _expectedType = expectedType;
+        _delegate = delegate;
+    }
+
+    @SuppressNullCheck
+    public void add(String id, String prerequisites, String postrequisites, T object)
+    {
+        _delegate.add(
+                toQualifiedId(_moduleId, id),
+                qualifySimpleIdList(_moduleId, prerequisites),
+                qualifySimpleIdList(_moduleId, postrequisites),
+                validVersionOf(object));
+    }
+
+    @SuppressNullCheck
+    public void add(String id, T object)
+    {
+        _delegate.add(toQualifiedId(_moduleId, id), validVersionOf(object));
+    }
+
+    private T validVersionOf(T object)
+    {
+        if (object == null || _expectedType.isInstance(object))
+            return object;
+
+        if (!_expectedType.isInstance(object))
+            _log.warn(IOCMessages.contributionWrongValueType(_serviceId, _contributionDef, object
+                    .getClass(), _expectedType));
+
+        return null;
+    }
+}

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=425558&r1=425557&r2=425558&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 Tue Jul 25 16:37:09 2006
@@ -15,6 +15,7 @@
 package org.apache.tapestry.ioc;
 
 import java.util.Collection;
+import java.util.List;
 
 /**
  * Extends {@link org.apache.tapestry.ioc.ServiceResources} with additional methods needed only by
@@ -25,6 +26,8 @@
 public interface ServiceCreatorResources extends ServiceResources
 {
     <T> Collection<T> getUnorderedConfiguration(Class<T> objectType);
+
+    <T> List<T> getOrderedConfiguration(Class<T> objectType);
 
     // More to come!
 }

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=425558&r1=425557&r2=425558&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 Tue Jul 25 16:37:09 2006
@@ -225,7 +225,8 @@
         setReturnValue(serviceId);
     }
 
-    protected final void trainCreateInterceptor(ServiceDecorator decorator, Object coreObject, Object interceptor)
+    protected final void trainCreateInterceptor(ServiceDecorator decorator, Object coreObject,
+            Object interceptor)
     {
         decorator.createInterceptor(coreObject);
         setReturnValue(interceptor);
@@ -249,7 +250,7 @@
             if (method.getName().equals(methodName))
                 return method;
         }
-    
+
         throw new IllegalArgumentException(String.format(
                 "Class %s does not provide a method named '%s'.",
                 clazz.getName(),
@@ -271,7 +272,7 @@
         return newMock(ServiceLocator.class);
     }
 
-    protected final OrderedConfiguration newOrderedConfiguration()
+    protected final <T> OrderedConfiguration<T> newOrderedConfiguration()
     {
         return newMock(OrderedConfiguration.class);
     }
@@ -307,7 +308,8 @@
         return newMock(ModuleDef.class);
     }
 
-    protected final void trainMatches(DecoratorDef decoratorDef, ServiceDef serviceDef, boolean matches)
+    protected final void trainMatches(DecoratorDef decoratorDef, ServiceDef serviceDef,
+            boolean matches)
     {
         decoratorDef.matches(serviceDef);
         setReturnValue(matches);

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=425558&r1=425557&r2=425558&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 Tue Jul 25 16:37:09 2006
@@ -146,6 +146,35 @@
     }
 
     @Test
+    public void injected_ordered_collection()
+    {
+        ServiceCreatorResources resources = newServiceCreatorResources();
+        Log log = newLog();
+
+        _fie = newFieService();
+        _expectedConfiguration = newMock(List.class);
+
+        trainForConstructor(resources, log);
+
+        trainIsDebugEnabled(log, false);
+
+        resources.getOrderedConfiguration(Runnable.class);
+        setReturnValue(_expectedConfiguration);
+
+        replay();
+
+        ServiceCreator sc = new ServiceBuilderMethodInvoker(
+                findMethod("buildWithOrderedConfiguration"), this, resources);
+
+        Object actual = sc.createService();
+
+        assertSame(actual, _fie);
+
+        verify();
+
+    }
+
+    @Test
     public void injected_unordered_collection()
     {
         ServiceCreatorResources resources = newServiceCreatorResources();
@@ -174,6 +203,13 @@
     }
 
     public FieService buildWithUnorderedConfiguration(Collection<Runnable> configuration)
+    {
+        assertSame(configuration, _expectedConfiguration);
+
+        return _fie;
+    }
+
+    public FieService buildWithOrderedConfiguration(List<Runnable> configuration)
     {
         assertSame(configuration, _expectedConfiguration);
 

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ValidatingOrderedConfigurationWrapperTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ValidatingOrderedConfigurationWrapperTest.java?rev=425558&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ValidatingOrderedConfigurationWrapperTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ValidatingOrderedConfigurationWrapperTest.java Tue Jul 25 16:37:09 2006
@@ -0,0 +1,125 @@
+// 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.lang.reflect.Method;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.OrderedConfiguration;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.testng.annotations.Test;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class ValidatingOrderedConfigurationWrapperTest extends InternalBaseTestCase
+{
+    @Test
+    public void valid_type_long_form()
+    {
+        ContributionDef def = newContributionDef();
+        Log log = newLog();
+        OrderedConfiguration<Runnable> configuration = newOrderedConfiguration();
+        Runnable contribution = newRunnable();
+
+        configuration.add("fred.id", "fred.pre", "fred.post", contribution);
+
+        replay();
+
+        OrderedConfiguration<Runnable> wrapper = new ValidatingOrderedConfigurationWrapper<Runnable>(
+                "barney.Service", "fred", def, log, Runnable.class, configuration);
+
+        wrapper.add("id", "pre", "post", contribution);
+
+        verify();
+    }
+
+    @Test
+    public void valid_type_short_form()
+    {
+        ContributionDef def = newContributionDef();
+        Log log = newLog();
+        OrderedConfiguration<Runnable> configuration = newOrderedConfiguration();
+        Runnable contribution = newRunnable();
+
+        configuration.add("fred.id", contribution);
+
+        replay();
+
+        OrderedConfiguration<Runnable> wrapper = new ValidatingOrderedConfigurationWrapper<Runnable>(
+                "barney.Service", "fred", def, log, Runnable.class, configuration);
+
+        wrapper.add("id", contribution);
+
+        verify();
+    }
+
+    @Test
+    public void null_object_passed_through()
+    {
+        ContributionDef def = newContributionDef();
+        Log log = newLog();
+        OrderedConfiguration<Runnable> configuration = newOrderedConfiguration();
+
+        configuration.add("fred.id", null);
+
+        replay();
+
+        OrderedConfiguration<Runnable> wrapper = new ValidatingOrderedConfigurationWrapper<Runnable>(
+                "barney.Service", "fred", def, log, Runnable.class, configuration);
+
+        wrapper.add("id", null);
+
+        verify();
+    }
+
+    @Test
+    public void incorrect_contribution_type_is_passed_through_as_null()
+    {
+        Method method = findMethod("contributeBarneyService");
+
+        ContributionDef def = new ContributionDefImpl("barney.Service", method);
+        Log log = newLog();
+        OrderedConfiguration<Runnable> configuration = newOrderedConfiguration();
+
+        log.warn(IOCMessages.contributionWrongValueType(
+                "barney.Service",
+                def,
+                String.class,
+                Runnable.class));
+
+        configuration.add("fred.id", null);
+
+        replay();
+
+        OrderedConfiguration wrapper = new ValidatingOrderedConfigurationWrapper("barney.Service",
+                "fred", def, log, Runnable.class, configuration);
+
+        wrapper.add("id", "string");
+
+        verify();
+    }
+
+    public void contributeBarneyService(OrderedConfiguration<Runnable> configuration)
+    {
+
+    }
+
+    private Runnable newRunnable()
+    {
+        return newMock(Runnable.class);
+    }
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/FredModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/FredModule.java?rev=425558&r1=425557&r2=425558&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/FredModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/FredModule.java Tue Jul 25 16:37:09 2006
@@ -15,6 +15,8 @@
 package org.apache.tapestry.ioc;
 
 import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 
 import org.apache.tapestry.annotations.Match;
 import org.apache.tapestry.ioc.annotations.Before;
@@ -23,6 +25,8 @@
 import org.apache.tapestry.ioc.annotations.InjectService;
 import org.apache.tapestry.ioc.annotations.Private;
 
+import static org.apache.tapestry.util.CollectionFactory.newList;
+
 /**
  * Module used to demonstrate decorator ordering.
  * 
@@ -76,12 +80,29 @@
         return null;
     }
 
-    public UnorderedNames buildUnorderedNames(final Collection<String> configuration)
+    public NameListHolder buildUnorderedNames(Collection<String> configuration)
+    {
+        final List<String> sorted = newList(configuration);
+
+        Collections.sort(sorted);
+
+        return new NameListHolder()
+        {
+
+            public List<String> getNames()
+            {
+                return sorted;
+            }
+
+        };
+    }
+
+    public NameListHolder buildOrderedNames(final List<String> configuration)
     {
-        return new UnorderedNames()
+        return new NameListHolder()
         {
 
-            public Collection<String> getNames()
+            public List<String> getNames()
             {
                 return configuration;
             }
@@ -89,6 +110,14 @@
         };
     }
 
+    public void contributeOrderedNames(OrderedConfiguration<String> configuration)
+    {
+        // Order "FRED" after "BARNEY"
+
+        configuration.add("fred", "barney", null, "FRED");
+        configuration.add("barney", "BARNEY");
+    }
+
     public void contributeUnorderedNames(Configuration<String> configuration)
     {
         configuration.add("UnorderedNames");
@@ -101,7 +130,7 @@
     }
 
     @Private
-    public UnorderedNames buildPrivateUnorderedNames(final Collection<String> configuration)
+    public NameListHolder buildPrivateUnorderedNames(final Collection<String> configuration)
     {
         return buildUnorderedNames(configuration);
     }
@@ -117,8 +146,8 @@
         configuration.add("Omega");
     }
 
-    public UnorderedNames buildPrivateUnorderedNamesAlias(@InjectService("PrivateUnorderedNames")
-    UnorderedNames privateService)
+    public NameListHolder buildPrivateUnorderedNamesAlias(@InjectService("PrivateUnorderedNames")
+    NameListHolder privateService)
     {
         return privateService;
     }

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=425558&r1=425557&r2=425558&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 Tue Jul 25 16:37:09 2006
@@ -15,16 +15,12 @@
 package org.apache.tapestry.ioc;
 
 import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 
 import org.apache.tapestry.internal.ioc.TapestryIOCModule;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
-import org.apache.tapestry.util.CollectionFactory;
 import org.testng.annotations.Test;
 
-import static org.apache.tapestry.util.CollectionFactory.newList;
 import static org.testng.Assert.assertEquals;
 
 /**
@@ -95,33 +91,43 @@
     {
         Registry r = buildRegistry();
 
-        UnorderedNames service = r.getService("fred.UnorderedNames", UnorderedNames.class);
+        NameListHolder service = r.getService("fred.UnorderedNames", NameListHolder.class);
 
-        List<String> names = sortedNames(service);
+        List<String> names = service.getNames();
 
         assertEquals(names, Arrays.asList("Beta", "Gamma", "UnorderedNames"));
     }
 
-    @Test
-    public void private_service_unordered_configuration()
+    /**
+     * We don't have to do as many public/private etc. tests for the other types of configuration,
+     * because the code paths are so similar.
+     */
+
+    @Test 
+    public void service_ordered_configuration()
     {
         Registry r = buildRegistry();
 
-        UnorderedNames service = r.getService(
-                "fred.PrivateUnorderedNamesAlias",
-                UnorderedNames.class);
+        NameListHolder service = r.getService("fred.OrderedNames", NameListHolder.class);
 
-        List<String> names = sortedNames(service);
+        List<String> names = service.getNames();
 
-        assertEquals(names, Arrays.asList("Omega", "PrivateUnorderedNames"));
+        assertEquals(names, Arrays.asList("BARNEY", "FRED"));
 
     }
 
-    private List<String> sortedNames(UnorderedNames service)
+    @Test
+    public void private_service_unordered_configuration()
     {
-        List<String> names = newList(service.getNames());
+        Registry r = buildRegistry();
+
+        NameListHolder service = r.getService(
+                "fred.PrivateUnorderedNamesAlias",
+                NameListHolder.class);
+
+        List<String> names = service.getNames();
+
+        assertEquals(names, Arrays.asList("Omega", "PrivateUnorderedNames"));
 
-        Collections.sort(names);
-        return names;
     }
 }

Copied: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/NameListHolder.java (from r425525, tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/UnorderedNames.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/NameListHolder.java?p2=tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/NameListHolder.java&p1=tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/UnorderedNames.java&r1=425525&r2=425558&rev=425558&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/UnorderedNames.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/NameListHolder.java Tue Jul 25 16:37:09 2006
@@ -14,14 +14,16 @@
 
 package org.apache.tapestry.ioc;
 
-import java.util.Collection;
+import java.util.List;
 
 /**
- * Used for testing of unordered contributions. The names are contributed in from multiple modules.
+ * Used for testing of ordered and unordered contributions. The names are contributed in from
+ * multiple modules. For unordered contributions, the values are sorted alphabetically. For ordered
+ * contributions, the values are ordered as per the contributions.
  * 
  * @author Howard M. Lewis Ship
  */
-public interface UnorderedNames
+public interface NameListHolder
 {
-    public Collection<String> getNames();
+    public List<String> getNames();
 }