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 2006/10/15 01:30:52 UTC

svn commit: r464060 [1/3] - in /tapestry/tapestry5/tapestry-core/trunk: .settings/ src/main/java/org/apache/tapestry/ src/main/java/org/apache/tapestry/internal/ioc/ src/main/java/org/apache/tapestry/internal/ioc/services/ src/main/java/org/apache/tape...

Author: hlship
Date: Sat Oct 14 16:30:48 2006
New Revision: 464060

URL: http://svn.apache.org/viewvc?view=rev&rev=464060
Log:
Support static methods inside Tapestry IOC Module classes.
Move TypeCoercer service from tapestry module to tapestry.ioc module.
Start a "Tapestry for Struts users" document.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/StrategyServiceBuilderImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/TypeCoercerImpl.java
      - copied, changed from r462686, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TypeCoercerImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ModuleBuilderSource.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/Coercion.java
      - copied, changed from r462686, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Coercion.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/CoercionTuple.java
      - copied, changed from r462686, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/CoercionTuple.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/StrategyServiceBuilder.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TypeCoercer.java
      - copied, changed from r462686, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TypeCoercer.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/StrategyRegistry.java
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/infrastructure.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/struts.apt
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/TypeCoercerImplTest.java
      - copied, changed from r463734, tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TypeCoercerImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StaticModule.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/StrategyRegistryTest.java
Removed:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TypeCoercerImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Coercion.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/CoercionTuple.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TypeCoercer.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TypeCoercerImplTest.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/.settings/org.eclipse.jdt.core.prefs
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryFilter.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/DecoratorDefImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.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/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/ServiceDecoratorImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceMessages.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/CompoundCoercion.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ExpansionPageElement.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/UtilMessages.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceBuilderResources.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/DecoratorDef.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/PropertyAccess.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.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/UtilMessages.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/services/ServiceStrings.properties
    tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties
    tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/util/UtilStrings.properties
    tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/util/UtilStrings.properties
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/command.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/configuration.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/decorator.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/index.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/module.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/pipeline.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/provider.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/shadow.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml
    tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ContributionDefImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentEventImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ExpansionPageElementImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties

Modified: tapestry/tapestry5/tapestry-core/trunk/.settings/org.eclipse.jdt.core.prefs
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/.settings/org.eclipse.jdt.core.prefs?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/.settings/org.eclipse.jdt.core.prefs (original)
+++ tapestry/tapestry5/tapestry-core/trunk/.settings/org.eclipse.jdt.core.prefs Sat Oct 14 16:30:48 2006
@@ -1,4 +1,4 @@
-#Tue Sep 19 11:09:26 PDT 2006
+#Sat Oct 14 06:55:27 PDT 2006
 eclipse.preferences.version=1
 org.eclipse.jdt.core.codeComplete.argumentPrefixes=
 org.eclipse.jdt.core.codeComplete.argumentSuffixes=
@@ -6,7 +6,7 @@
 org.eclipse.jdt.core.codeComplete.fieldSuffixes=
 org.eclipse.jdt.core.codeComplete.localPrefixes=
 org.eclipse.jdt.core.codeComplete.localSuffixes=
-org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=_
 org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryFilter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryFilter.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryFilter.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryFilter.java Sat Oct 14 16:30:48 2006
@@ -36,6 +36,7 @@
 import org.apache.tapestry.ioc.RegistryBuilder;
 import org.apache.tapestry.services.ComponentClassResolver;
 import org.apache.tapestry.services.HttpServletRequestHandler;
+import org.apache.tapestry.services.Infrastructure;
 import org.apache.tapestry.services.ServletApplicationInitializer;
 import org.apache.tapestry.services.TapestryModule;
 
@@ -105,6 +106,10 @@
         _registry = builder.build();
 
         long toRegistry = System.currentTimeMillis();
+
+        Infrastructure infra = _registry
+                .getService("tapestry.Infrastructure", Infrastructure.class);
+        infra.setMode("servlet");
 
         // It would be nice to move this logic inside ApplicationInitializer,
         // may have to pass in the FilterConfig, or maybe a wrapper around

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?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- 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 Sat Oct 14 16:30:48 2006
@@ -23,6 +23,7 @@
 import org.apache.tapestry.internal.util.InternalUtils;
 import org.apache.tapestry.ioc.Configuration;
 import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.ModuleBuilderSource;
 import org.apache.tapestry.ioc.OrderedConfiguration;
 import org.apache.tapestry.ioc.ServiceLocator;
 import org.apache.tapestry.ioc.def.ContributionDef;
@@ -53,37 +54,40 @@
         return _serviceId;
     }
 
-    public void contribute(Object moduleBuilder, ServiceLocator locator, Configuration configuration)
+    public void contribute(ModuleBuilderSource moduleBuilderSource, ServiceLocator locator,
+            Configuration configuration)
     {
-        invokeMethod(moduleBuilder, locator, Configuration.class, configuration);
+        invokeMethod(moduleBuilderSource, locator, Configuration.class, configuration);
     }
 
-    public void contribute(Object moduleBuilder, ServiceLocator locator,
+    public void contribute(ModuleBuilderSource moduleBuilderSource, ServiceLocator locator,
             OrderedConfiguration configuration)
     {
-        invokeMethod(moduleBuilder, locator, OrderedConfiguration.class, configuration);
+        invokeMethod(moduleBuilderSource, locator, OrderedConfiguration.class, configuration);
     }
 
-    public void contribute(Object moduleBuilder, ServiceLocator locator,
+    public void contribute(ModuleBuilderSource moduleBuilderSource, ServiceLocator locator,
             MappedConfiguration configuration)
     {
-        invokeMethod(moduleBuilder, locator, MappedConfiguration.class, configuration);
+        invokeMethod(moduleBuilderSource, locator, MappedConfiguration.class, configuration);
     }
 
-    private void invokeMethod(Object moduleBuilder, ServiceLocator locator, Class parameterType,
-            Object parameterValue)
+    private <T> void invokeMethod(ModuleBuilderSource source, ServiceLocator locator,
+            Class<T> parameterType, T parameterValue)
     {
         Map<Class, Object> parameterDefaults = newMap();
 
         // The way it works is: the method will take Configuration, OrderedConfiguration or
-        // MappedConfiguration.
-        // So, if the method is for one type and the service is for a different type,
-        // then we'll see an error putting together the parameter.
+        // MappedConfiguration. So, if the method is for one type and the service is for a different
+        // type, then we'll see an error putting together the parameter.
 
         parameterDefaults.put(parameterType, parameterValue);
         parameterDefaults.put(ServiceLocator.class, locator);
 
         Throwable fail = null;
+
+        Object moduleBuilder = IOCUtilities.isStatic(_contributorMethod) ? null : source
+                .getModuleBuilder();
 
         try
         {

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DecoratorDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DecoratorDefImpl.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DecoratorDefImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DecoratorDefImpl.java Sat Oct 14 16:30:48 2006
@@ -23,6 +23,7 @@
 import org.apache.tapestry.internal.annotations.SuppressNullCheck;
 import org.apache.tapestry.internal.util.InternalUtils;
 import org.apache.tapestry.ioc.IdMatcher;
+import org.apache.tapestry.ioc.ModuleBuilderSource;
 import org.apache.tapestry.ioc.OrIdMatcher;
 import org.apache.tapestry.ioc.ServiceDecorator;
 import org.apache.tapestry.ioc.ServiceResources;
@@ -79,9 +80,9 @@
         return _decoratorId;
     }
 
-    public ServiceDecorator createDecorator(Object moduleBuilder, ServiceResources resources)
+    public ServiceDecorator createDecorator(ModuleBuilderSource moduleBuilderSource, ServiceResources resources)
     {
-        return new ServiceDecoratorImpl(_decoratorMethod, moduleBuilder, resources);
+        return new ServiceDecoratorImpl(_decoratorMethod, moduleBuilderSource, resources);
     }
 
     /**

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java Sat Oct 14 16:30:48 2006
@@ -18,6 +18,7 @@
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Enumeration;
@@ -129,17 +130,17 @@
     }
 
     /** Joins together some number of elements to form a comma separated list. */
-    public static String join(Collection<String> elements)
+    public static String join(List elements)
     {
         StringBuilder buffer = new StringBuilder();
         boolean first = true;
 
-        for (String s : elements)
+        for (Object o : elements)
         {
             if (!first)
                 buffer.append(", ");
 
-            buffer.append(s);
+            buffer.append(String.valueOf(o));
 
             first = false;
         }
@@ -148,9 +149,12 @@
     }
 
     /** Creates a sorted copy of the provided elements, then turns that into a comma separated list. */
-    public static String joinSorted(Collection<String> elements)
+    public static String joinSorted(Collection elements)
     {
-        List<String> list = newList(elements);
+        List<String> list = newList();
+
+        for (Object o : elements)
+            list.add(String.valueOf(o));
 
         Collections.sort(list);
 
@@ -232,20 +236,23 @@
     }
 
     /**
-     * Extracts the string keys from a map and returns them in sorted order.
+     * Extracts the string keys from a map and returns them in sorted order. The keys are converted
+     * to strings.
      * 
-     * @param <V>
      * @param map
      *            the map to extract keys from
      * @return the sorted keys, or the empty set if map is null
      */
     @SuppressNullCheck
-    public static <V> List<String> sortedKeys(Map<String, V> map)
+    public static List<String> sortedKeys(Map map)
     {
         if (map == null)
             return Collections.emptyList();
 
-        List<String> keys = newList(map.keySet());
+        List<String> keys = newList();
+
+        for (Object o : map.keySet())
+            keys.add(String.valueOf(o));
 
         Collections.sort(keys);
 
@@ -269,5 +276,11 @@
             return null;
 
         return map.get(key);
+    }
+
+    /** Returns true if the method provided is a static method. */
+    public static final boolean isStatic(Method method)
+    {
+        return Modifier.isStatic(method.getModifiers());
     }
 }

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?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- 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 Sat Oct 14 16:30:48 2006
@@ -18,6 +18,7 @@
 import java.util.List;
 import java.util.Set;
 
+import org.apache.tapestry.ioc.ModuleBuilderSource;
 import org.apache.tapestry.ioc.ServiceDecorator;
 import org.apache.tapestry.ioc.def.ContributionDef;
 import org.apache.tapestry.ioc.def.DecoratorDef;
@@ -30,7 +31,7 @@
  * 
  * @author Howard M. Lewis Ship
  */
-public interface Module
+public interface Module extends ModuleBuilderSource
 {
     /**
      * Locates a service given a service id and the corresponding service interface type.
@@ -73,11 +74,6 @@
      * @return the ordered list of service decorators
      */
     List<ServiceDecorator> findDecoratorsForService(String serviceId);
-
-    /**
-     * Returns the instantiated module builder instance.
-     */
-    Object getModuleBuilder();
 
     /**
      * Iterates over any decorator definitions defined by the module and returns those that apply to

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?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- 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 Sat Oct 14 16:30:48 2006
@@ -315,7 +315,6 @@
         Log log = getLog(serviceId);
         boolean debug = log.isDebugEnabled();
 
-        Object moduleBuilder = module.getModuleBuilder();
         ServiceLocator locator = new ServiceResourcesImpl(this, module, serviceDef, log);
 
         for (ContributionDef def : contributions)
@@ -326,7 +325,7 @@
             if (debug)
                 log.debug(IOCMessages.invokingMethod(def));
 
-            def.contribute(moduleBuilder, locator, validating);
+            def.contribute(module, locator, validating);
         }
 
     }
@@ -343,7 +342,6 @@
         Log log = getLog(serviceId);
         boolean debug = log.isDebugEnabled();
 
-        Object moduleBuilder = module.getModuleBuilder();
         ServiceLocator locator = new ServiceResourcesImpl(this, module, serviceDef, log);
 
         for (ContributionDef def : contributions)
@@ -354,7 +352,7 @@
             if (debug)
                 log.debug(IOCMessages.invokingMethod(def));
 
-            def.contribute(moduleBuilder, locator, validating);
+            def.contribute(module, locator, validating);
         }
     }
 
@@ -370,7 +368,6 @@
         Log log = getLog(serviceId);
         boolean debug = log.isDebugEnabled();
 
-        Object moduleBuilder = module.getModuleBuilder();
         ServiceLocator locator = new ServiceResourcesImpl(this, module, serviceDef, log);
 
         for (ContributionDef def : contributions)
@@ -381,7 +378,7 @@
             if (debug)
                 log.debug(IOCMessages.invokingMethod(def));
 
-            def.contribute(moduleBuilder, locator, validating);
+            def.contribute(module, locator, validating);
         }
     }
 
@@ -458,9 +455,9 @@
     {
         List<ServiceDecorator> result = newList();
 
-        Object moduleBuilder = null;
         ServiceResources resources = null;
         String moduleId = null;
+        Module module = null;
 
         for (DecoratorDef dd : ordered)
         {
@@ -476,13 +473,12 @@
             {
                 moduleId = decoratorModuleId;
 
-                Module module = _modules.get(moduleId);
-                moduleBuilder = module.getModuleBuilder();
+                module = _modules.get(moduleId);
 
                 resources = new ServiceResourcesImpl(this, module, serviceDef, log);
             }
 
-            ServiceDecorator decorator = dd.createDecorator(moduleBuilder, resources);
+            ServiceDecorator decorator = dd.createDecorator(module, resources);
 
             result.add(decorator);
         }

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?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- 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 Sat Oct 14 16:30:48 2006
@@ -18,6 +18,7 @@
 import static org.apache.tapestry.internal.ioc.ConfigurationType.ORDERED;
 import static org.apache.tapestry.internal.ioc.ConfigurationType.UNORDERED;
 import static org.apache.tapestry.internal.ioc.IOCUtilities.calculateParametersForMethod;
+import static org.apache.tapestry.internal.ioc.IOCUtilities.isStatic;
 import static org.apache.tapestry.util.CollectionFactory.newMap;
 
 import java.lang.reflect.InvocationTargetException;
@@ -232,9 +233,9 @@
     public Object createObject()
     {
         // Defer getting (and possibly instantitating) the module builder until the last possible
-        // moment.
+        // moment. If the method is static, there's no need to even get the builder.
 
-        Object moduleBuilder = _resources.getModuleBuilder();
+        Object moduleBuilder = isStatic(_builderMethod) ? null : _resources.getModuleBuilder();
 
         Object result = null;
         Throwable failure = null;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImpl.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImpl.java Sat Oct 14 16:30:48 2006
@@ -15,6 +15,7 @@
 package org.apache.tapestry.internal.ioc;
 
 import static org.apache.tapestry.internal.ioc.IOCUtilities.calculateParametersForMethod;
+import static org.apache.tapestry.internal.ioc.IOCUtilities.isStatic;
 import static org.apache.tapestry.util.CollectionFactory.newMap;
 
 import java.lang.reflect.InvocationTargetException;
@@ -22,6 +23,7 @@
 import java.util.Map;
 
 import org.apache.commons.logging.Log;
+import org.apache.tapestry.ioc.ModuleBuilderSource;
 import org.apache.tapestry.ioc.ServiceDecorator;
 import org.apache.tapestry.ioc.ServiceResources;
 
@@ -32,7 +34,7 @@
  */
 public class ServiceDecoratorImpl implements ServiceDecorator
 {
-    private final Object _moduleBuilder;
+    private final ModuleBuilderSource _moduleBuilderSource;
 
     private final String _serviceId;
 
@@ -46,11 +48,12 @@
 
     private final Class _serviceInterface;
 
-    public ServiceDecoratorImpl(Method method, Object moduleBuilder, ServiceResources resources)
+    public ServiceDecoratorImpl(Method method, ModuleBuilderSource moduleBuilderSource,
+            ServiceResources resources)
     {
         _serviceId = resources.getServiceId();
         _decoratorMethod = method;
-        _moduleBuilder = moduleBuilder;
+        _moduleBuilderSource = moduleBuilderSource;
         _resources = resources;
         _serviceInterface = resources.getServiceInterface();
         _log = resources.getServiceLog();
@@ -74,6 +77,9 @@
         Object result = null;
         Throwable failure = null;
 
+        Object moduleBuilder = isStatic(_decoratorMethod) ? null : _moduleBuilderSource
+                .getModuleBuilder();
+
         try
         {
             Object[] parameters = calculateParametersForMethod(
@@ -81,7 +87,7 @@
                     _resources,
                     parameterDefaults);
 
-            result = _decoratorMethod.invoke(_moduleBuilder, parameters);
+            result = _decoratorMethod.invoke(moduleBuilder, parameters);
         }
         catch (InvocationTargetException ite)
         {

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImpl.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImpl.java Sat Oct 14 16:30:48 2006
@@ -46,7 +46,7 @@
     }
 
     @Concurrent.Write
-    public void clear()
+    public void clearCache()
     {
         _adapters.clear();
     }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceMessages.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceMessages.java Sat Oct 14 16:30:48 2006
@@ -140,4 +140,14 @@
     {
         return MESSAGES.format("shutdown-listener-error", listener, cause);
     }
+
+    static String noCoercionFound(Class sourceType, Class targetType, String coercions)
+    {
+        return MESSAGES.format(
+                "no-coercion-found",
+                sourceType.getName(),
+                targetType.getName(),
+                coercions);
+    }
+
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/StrategyServiceBuilderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/StrategyServiceBuilderImpl.java?view=auto&rev=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/StrategyServiceBuilderImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/StrategyServiceBuilderImpl.java Sat Oct 14 16:30:48 2006
@@ -0,0 +1,21 @@
+package org.apache.tapestry.internal.ioc.services;
+
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.StrategyServiceBuilder;
+import org.apache.tapestry.util.StrategyRegistry;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class StrategyServiceBuilderImpl implements StrategyServiceBuilder
+{
+    private ClassFactory _classFactory;
+
+    public <S> S build(StrategyRegistry<S> registry)
+    {
+        Class interfaceType = registry.getAdapterType();
+
+        return null;
+    }
+
+}

Copied: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/TypeCoercerImpl.java (from r462686, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TypeCoercerImpl.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/TypeCoercerImpl.java?view=diff&rev=464060&p1=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TypeCoercerImpl.java&r1=462686&p2=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/TypeCoercerImpl.java&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TypeCoercerImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/TypeCoercerImpl.java Sat Oct 14 16:30:48 2006
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.services;
+package org.apache.tapestry.internal.ioc.services;
 
 import static org.apache.tapestry.util.CollectionFactory.newLinkedList;
 import static org.apache.tapestry.util.CollectionFactory.newList;
@@ -26,20 +26,20 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.tapestry.events.InvalidationListener;
 import org.apache.tapestry.internal.annotations.SuppressNullCheck;
 import org.apache.tapestry.internal.ioc.IOCUtilities;
+import org.apache.tapestry.internal.services.CompoundCoercion;
 import org.apache.tapestry.internal.util.InheritanceSearch;
-import org.apache.tapestry.services.Coercion;
-import org.apache.tapestry.services.CoercionTuple;
+import org.apache.tapestry.ioc.services.Coercion;
+import org.apache.tapestry.ioc.services.CoercionTuple;
+import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.services.TransformUtils;
-import org.apache.tapestry.services.TypeCoercer;
 import org.apache.tapestry.util.Defense;
 
 /**
  * @author Howard M. Lewis Ship
  */
-public class TypeCoercerImpl implements TypeCoercer, InvalidationListener
+public class TypeCoercerImpl implements TypeCoercer
 {
     // Read only after constructor
 
@@ -158,7 +158,7 @@
         return result;
     }
 
-    public void objectWasInvalidated()
+    public void clearCache()
     {
         _cache.clear();
     }
@@ -228,7 +228,7 @@
         // Not found anywhere. Identify the source and target type and a (sorted) list of
         // all the known coercions.
 
-        throw new IllegalArgumentException(ServicesMessages.noCoercionFound(
+        throw new IllegalArgumentException(ServiceMessages.noCoercionFound(
                 sourceType,
                 targetType,
                 buildCoercionCatalog()));

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java Sat Oct 14 16:30:48 2006
@@ -3,8 +3,8 @@
 import org.apache.tapestry.ComponentEventHandler;
 import org.apache.tapestry.ComponentResources;
 import org.apache.tapestry.internal.annotations.SuppressNullCheck;
+import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.runtime.ComponentEvent;
-import org.apache.tapestry.services.TypeCoercer;
 
 /**
  * @author Howard M. Lewis Ship

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/CompoundCoercion.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/CompoundCoercion.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/CompoundCoercion.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/CompoundCoercion.java Sat Oct 14 16:30:48 2006
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.internal.services;
 
-import org.apache.tapestry.services.Coercion;
+import org.apache.tapestry.ioc.services.Coercion;
 
 /**
  * Combines two coercions to create a coercsion through an intermediate type.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java Sat Oct 14 16:30:48 2006
@@ -34,6 +34,7 @@
 import org.apache.tapestry.ioc.OrderedConfiguration;
 import org.apache.tapestry.ioc.annotations.Contribute;
 import org.apache.tapestry.ioc.annotations.Id;
+import org.apache.tapestry.ioc.annotations.Inject;
 import org.apache.tapestry.ioc.annotations.InjectService;
 import org.apache.tapestry.ioc.annotations.Lifecycle;
 import org.apache.tapestry.ioc.annotations.Match;
@@ -43,6 +44,7 @@
 import org.apache.tapestry.ioc.services.LoggingDecorator;
 import org.apache.tapestry.ioc.services.PropertyAccess;
 import org.apache.tapestry.ioc.services.ThreadCleanupHub;
+import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.services.ApplicationInitializer;
 import org.apache.tapestry.services.ApplicationInitializerFilter;
 import org.apache.tapestry.services.BindingFactory;
@@ -51,7 +53,6 @@
 import org.apache.tapestry.services.ComponentClassTransformWorker;
 import org.apache.tapestry.services.MarkupWriterFactory;
 import org.apache.tapestry.services.RequestExceptionHandler;
-import org.apache.tapestry.services.TypeCoercer;
 import org.apache.tapestry.services.WebContext;
 import org.apache.tapestry.services.WebRequest;
 import org.apache.tapestry.services.WebRequestFilter;
@@ -88,8 +89,8 @@
             @InjectService("tapestry.ComponentClassResolver")
             ComponentClassResolver componentClassResolver,
             @InjectService("tapestry.ioc.ChainBuilder")
-            ChainBuilder chainBuilder, @InjectService("tapestry.WebRequest")
-            WebRequest request, @InjectService("tapestry.WebResponse")
+            ChainBuilder chainBuilder, @Inject("infrastructure:request")
+            WebRequest request, @Inject("infrastructure:response")
             WebResponse response)
     {
         _componentInstantiatorSource = componentInstantiatorSource;
@@ -139,12 +140,12 @@
     }
 
     @Lifecycle("perthread")
-    public TemplateParser buildTemplateParser(Log log)
+    public static TemplateParser buildTemplateParser(Log log)
     {
         return new TemplateParserImpl(log);
     }
 
-    public PageElementFactory buildPageElementFactory(@InjectService("tapestry.TypeCoercer")
+    public PageElementFactory buildPageElementFactory(@Inject("infrastructure:typeCoercer")
     TypeCoercer typeCoercer, @InjectService("tapestry.BindingSource")
     BindingSource bindingSource)
     {
@@ -190,7 +191,7 @@
      * Such services usually are {@link org.apache.tapestry.internal.event.InvalidationEventHub}s,
      * and fire invalidation events to their listeners.
      */
-    public UpdateListenerHub buildUpdateListenerHub()
+    public static UpdateListenerHub buildUpdateListenerHub()
     {
         return new UpdateListenerHubImpl();
     }
@@ -203,8 +204,8 @@
     @Match(
     { "tapestry.*", "tapestry.*.*" })
     @Order("before:*.*")
-    public <T> T decorateWithLogging(Class<T> serviceInterface, T delegate, String serviceId,
-            Log log, @InjectService("tapestry.ioc.LoggingDecorator")
+    public static <T> T decorateWithLogging(Class<T> serviceInterface, T delegate,
+            String serviceId, Log log, @InjectService("tapestry.ioc.LoggingDecorator")
             LoggingDecorator loggingDecorator)
     {
         return loggingDecorator.build(serviceInterface, delegate, serviceId, log);
@@ -221,7 +222,7 @@
         return service;
     }
 
-    public PageResponseRenderer buildPageResponseRenderer(
+    public static PageResponseRenderer buildPageResponseRenderer(
             @InjectService("tapestry.MarkupWriterFactory")
             MarkupWriterFactory markupWriterFactory,
             @InjectService("tapestry.PageRenderInitializer")
@@ -251,7 +252,8 @@
     public void contributeApplicationInitializerFilters(
             OrderedConfiguration<ApplicationInitializerFilter> configuration,
             @InjectService("tapestry.ioc.PropertyAccess")
-            final PropertyAccess propertyAccess)
+            final PropertyAccess propertyAccess, @Inject("infrastructure:typeCoercer")
+            final TypeCoercer typeCoercer)
     {
         ApplicationInitializerFilter setApplicationPackage = new ApplicationInitializerFilter()
         {
@@ -272,11 +274,12 @@
         {
             public void objectWasInvalidated()
             {
-                propertyAccess.clear();
+                propertyAccess.clearCache();
+                typeCoercer.clearCache();
             }
         };
 
-        ApplicationInitializerFilter clearPropertyAccess = new ApplicationInitializerFilter()
+        ApplicationInitializerFilter clearCaches = new ApplicationInitializerFilter()
         {
             public void initializeApplication(WebContext context, ApplicationInitializer initializer)
             {
@@ -289,7 +292,7 @@
             }
         };
 
-        configuration.add("ClearPropertyAccessCacheOnInvalidation", clearPropertyAccess);
+        configuration.add("ClearCachesOnInvalidation", clearCaches);
     }
 
     /**
@@ -320,7 +323,6 @@
 
     public void contributePropBindingFactory(OrderedConfiguration<BindingFactory> configuration)
     {
-
         BindingFactory keywordFactory = new BindingFactory()
         {
             private final Map<String, Object> _keywords = newMap();

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java Sat Oct 14 16:30:48 2006
@@ -34,11 +34,11 @@
 import org.apache.tapestry.internal.structure.PageElement;
 import org.apache.tapestry.internal.structure.StartElementPageElement;
 import org.apache.tapestry.internal.structure.TextPageElement;
+import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.model.ComponentModel;
 import org.apache.tapestry.runtime.RenderQueue;
 import org.apache.tapestry.services.BindingSource;
 import org.apache.tapestry.services.ComponentClassResolver;
-import org.apache.tapestry.services.TypeCoercer;
 
 /**
  * Null check suppressed as much as to simplify testing (yea! I can pass a null TypeCoercer) as it

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java Sat Oct 14 16:30:48 2006
@@ -178,15 +178,6 @@
         return MESSAGES.format("binding-source-failure", expression, cause);
     }
 
-    static String noCoercionFound(Class sourceType, Class targetType, String coercions)
-    {
-        return MESSAGES.format(
-                "no-coercion-found",
-                sourceType.getName(),
-                targetType.getName(),
-                coercions);
-    }
-
     static String contextIndexOutOfRange(String methodDescription)
     {
         return MESSAGES.format("context-index-out-of-range", methodDescription);

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Sat Oct 14 16:30:48 2006
@@ -31,6 +31,7 @@
 import org.apache.tapestry.internal.ioc.IOCUtilities;
 import org.apache.tapestry.internal.services.ComponentEventImpl;
 import org.apache.tapestry.internal.services.Instantiator;
+import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.model.ComponentModel;
 import org.apache.tapestry.model.ParameterModel;
 import org.apache.tapestry.runtime.ComponentEvent;
@@ -39,7 +40,6 @@
 import org.apache.tapestry.runtime.PageLifecycleListener;
 import org.apache.tapestry.runtime.RenderCommand;
 import org.apache.tapestry.runtime.RenderQueue;
-import org.apache.tapestry.services.TypeCoercer;
 
 /**
  * Implements {@link org.apache.tapestry.internal.structure.PageElement} and

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ExpansionPageElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ExpansionPageElement.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ExpansionPageElement.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ExpansionPageElement.java Sat Oct 14 16:30:48 2006
@@ -16,8 +16,8 @@
 
 import org.apache.tapestry.Binding;
 import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.runtime.RenderQueue;
-import org.apache.tapestry.services.TypeCoercer;
 
 /**
  * @author Howard M. Lewis Ship

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java Sat Oct 14 16:30:48 2006
@@ -42,6 +42,7 @@
 import org.apache.tapestry.runtime.ComponentLifecycle;
 import org.apache.tapestry.runtime.RenderQueue;
 import org.apache.tapestry.services.ComponentClassResolver;
+import org.apache.tapestry.services.Infrastructure;
 import org.apache.tapestry.services.TapestryModule;
 import org.apache.tapestry.services.WebRequest;
 import org.apache.tapestry.test.BaseTestCase;
@@ -67,6 +68,8 @@
         builder.add(TapestryModule.class);
 
         _registry = builder.build();
+
+        _registry.getService(Infrastructure.class).setMode("servlet");
     }
 
     @AfterSuite
@@ -255,7 +258,8 @@
         setReturnValue(contextPath);
     }
 
-    protected final void train_resolvePageClassNameToPageName(ComponentClassResolver resolver, String pageClassName, String pageName)
+    protected final void train_resolvePageClassNameToPageName(ComponentClassResolver resolver,
+            String pageClassName, String pageName)
     {
         resolver.resolvePageClassNameToPageName(pageClassName);
         setReturnValue(pageName);

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/UtilMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/UtilMessages.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/UtilMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/UtilMessages.java Sat Oct 14 16:30:48 2006
@@ -47,4 +47,5 @@
     {
         return MESSAGES.format("constraint-format", constraint, id);
     }
+
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ModuleBuilderSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ModuleBuilderSource.java?view=auto&rev=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ModuleBuilderSource.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ModuleBuilderSource.java Sat Oct 14 16:30:48 2006
@@ -0,0 +1,17 @@
+package org.apache.tapestry.ioc;
+
+/**
+ * The source for the module builder instance needed by most (but not all) service builders, service
+ * contributors and service decorators. Allows the creation of the moduleBuilder instance to be
+ * deferred until actually needed; in practical terms, when the builder/decorator/contributor is a
+ * <em>static</em> method on the module builder class, then a module builder instance is not
+ * needed. This allows Tapestry IOC to work around a tricky chicken-and-the-egg problem, whereby the
+ * constructor of a module builder instance requires contributions that originate in the same
+ * module.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public interface ModuleBuilderSource
+{
+    Object getModuleBuilder();
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceBuilderResources.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceBuilderResources.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceBuilderResources.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceBuilderResources.java Sat Oct 14 16:30:48 2006
@@ -20,17 +20,13 @@
 
 /**
  * Extends {@link org.apache.tapestry.ioc.ServiceResources} with additional methods needed only by
- * the service builder method, related to accessing a service's configuration.
+ * the service builder method, related to accessing a service's configuration. Services may have a
+ * <em>single</em> configuration in one of three flavors: unordered, ordered or mapped.
  * 
  * @author Howard M. Lewis Ship
  */
-public interface ServiceBuilderResources extends ServiceResources
+public interface ServiceBuilderResources extends ServiceResources, ModuleBuilderSource
 {
-    /**
-     * Returns the module builder instance for the module containing the service to be created.
-     */
-    Object getModuleBuilder();
-
     <T> Collection<T> getUnorderedConfiguration(Class<T> valueType);
 
     <T> List<T> getOrderedConfiguration(Class<T> valueType);

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java Sat Oct 14 16:30:48 2006
@@ -16,6 +16,7 @@
 
 import org.apache.tapestry.ioc.Configuration;
 import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.ModuleBuilderSource;
 import org.apache.tapestry.ioc.OrderedConfiguration;
 import org.apache.tapestry.ioc.ServiceLocator;
 
@@ -30,10 +31,11 @@
     String getServiceId();
 
     /**
-     * Performs the work needed to contribute into the configuration.
+     * Performs the work needed to contribute into the standard, unordered configuration.
      * 
-     * @param moduleBuilder
-     *            the module builder instance associated with the contribution
+     * @param moduleBuilderSource
+     *            the source, if needed, of the module builder instance associated with the
+     *            contribution
      * @param locator
      *            allows access to services visible to the module builder instance
      * @param configuration
@@ -41,13 +43,15 @@
      *            encapsulate all related error checks (such as passing of nulls or inappropriate
      *            classes).
      */
-    void contribute(Object moduleBuilder, ServiceLocator locator, Configuration configuration);
+    void contribute(ModuleBuilderSource moduleBuilderSource, ServiceLocator locator,
+            Configuration configuration);
 
     /**
-     * Performs the work needed to contribute into the configuration.
+     * Performs the work needed to contribute into the ordered configuration.
      * 
-     * @param moduleBuilder
-     *            the module builder instance associated with the contribution
+     * @param moduleBuilderSource
+     *            the source, if needed, of the module builder instance associated with the
+     *            contribution
      * @param locator
      *            allows access to services visible to the module builder instance
      * @param configuration
@@ -55,13 +59,15 @@
      *            encapsulate all related error checks (such as passing of nulls or inappropriate
      *            classes).
      */
-    void contribute(Object moduleBuilder, ServiceLocator locator, OrderedConfiguration configuration);
+    void contribute(ModuleBuilderSource moduleBuilderSource, ServiceLocator locator,
+            OrderedConfiguration configuration);
 
     /**
-     * Performs the work needed to contribute into the configuration.
+     * Performs the work needed to contribute into the mapped configuration.
      * 
-     * @param moduleBuilder
-     *            the module builder instance associated with the contribution
+     * @param moduleBuilderSource
+     *            the source, if needed, of the module builder instance associated with the
+     *            contribution
      * @param locator
      *            allows access to services visible to the module builder instance
      * @param configuration
@@ -69,5 +75,6 @@
      *            encapsulate all related error checks (such as passing of null keys or values or
      *            inappropriate classes, or duplicate keys).
      */
-    void contribute(Object moduleBuilder, ServiceLocator locator, MappedConfiguration configuration);
+    void contribute(ModuleBuilderSource moduleBuilderSource, ServiceLocator locator,
+            MappedConfiguration configuration);
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/DecoratorDef.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/DecoratorDef.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/DecoratorDef.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/DecoratorDef.java Sat Oct 14 16:30:48 2006
@@ -14,6 +14,7 @@
 
 package org.apache.tapestry.ioc.def;
 
+import org.apache.tapestry.ioc.ModuleBuilderSource;
 import org.apache.tapestry.ioc.ServiceDecorator;
 import org.apache.tapestry.ioc.ServiceResources;
 
@@ -60,7 +61,7 @@
      * Creates an object that can perform the decoration (in the default case, by invoking the
      * decorator method on the module builder instance.
      * 
-     * @param moduleBuilder
+     * @param moduleBuilderSource
      *            the module builder instance associated with the module containing the decorator
      *            (not necessarily the module containing the service being decorated)
      * @param resources
@@ -69,7 +70,7 @@
      *            serviceInterface, log, etc.) are for the service being decorated.
      * @return
      */
-    ServiceDecorator createDecorator(Object moduleBuilder, ServiceResources resources);
+    ServiceDecorator createDecorator(ModuleBuilderSource moduleBuilderSource, ServiceResources resources);
 
     /**
      * Used to determine which services may be decorated by this decorator. When decorating a

Copied: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/Coercion.java (from r462686, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Coercion.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/Coercion.java?view=diff&rev=464060&p1=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Coercion.java&r1=462686&p2=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/Coercion.java&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Coercion.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/Coercion.java Sat Oct 14 16:30:48 2006
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.services;
+package org.apache.tapestry.ioc.services;
 
 /**
  * Responsible for converting from one type to another. This is used primarily around component

Copied: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/CoercionTuple.java (from r462686, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/CoercionTuple.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/CoercionTuple.java?view=diff&rev=464060&p1=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/CoercionTuple.java&r1=462686&p2=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/CoercionTuple.java&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/CoercionTuple.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/CoercionTuple.java Sat Oct 14 16:30:48 2006
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.services;
+package org.apache.tapestry.ioc.services;
 
 /**
  * An immutable object that represents a mapping from one type to another. This is also the
@@ -44,8 +44,8 @@
     @Override
     public String toString()
     {
-        return String.format("CoercionTuple[%s --> %s via %s]", _sourceType.getName(), _targetType
-                .getName(), _coercion);
+        return String.format("CoercionTuple[%s --> %s]", _sourceType.getName(), _targetType
+                .getName());
     }
 
     public Coercion<S, T> getCoercion()

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/PropertyAccess.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/PropertyAccess.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/PropertyAccess.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/PropertyAccess.java Sat Oct 14 16:30:48 2006
@@ -54,5 +54,5 @@
     ClassPropertyAdapter getAdapter(Class forClass);
 
     /** Discards all stored property access information, discarding all created class adapters. */
-    void clear();
+    void clearCache();
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/StrategyServiceBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/StrategyServiceBuilder.java?view=auto&rev=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/StrategyServiceBuilder.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/StrategyServiceBuilder.java Sat Oct 14 16:30:48 2006
@@ -0,0 +1,32 @@
+package org.apache.tapestry.ioc.services;
+
+import org.apache.tapestry.util.StrategyRegistry;
+
+/**
+ * A service implementation builder that operates around a {@link StrategyRegistry}, implementing a
+ * version of the Gang of Four Strategy pattern.
+ * <p>
+ * The constructed service is configured with a number of adapters (that implement the same service
+ * interface). Method invocations on the service are routed to one of the adapters.
+ * <p>
+ * The first parameter of each method is used to select the appropriate adapter.
+ * <p>
+ * The ideal interface for use with this builder has only one method.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public interface StrategyServiceBuilder
+{
+    /**
+     * Given a number of adapters implementing the service interface, builds a "dispatcher"
+     * implementations that delegates to the one of the adapters. It is an error if any of the
+     * methods takes no parameters.
+     * 
+     * @param <S>
+     *            the service interface type
+     * @param registry
+     *            defines the adapters based on parameter type (of the first parameter)
+     * @return a service implementation
+     */
+    <S> S build(StrategyRegistry<S> registry);
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java Sat Oct 14 16:30:48 2006
@@ -14,8 +14,14 @@
 
 package org.apache.tapestry.ioc.services;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 
+import org.apache.tapestry.internal.annotations.SuppressNullCheck;
 import org.apache.tapestry.internal.ioc.services.ChainBuilderImpl;
 import org.apache.tapestry.internal.ioc.services.DefaultImplementationBuilderImpl;
 import org.apache.tapestry.internal.ioc.services.ExceptionAnalyzerImpl;
@@ -27,6 +33,9 @@
 import org.apache.tapestry.internal.ioc.services.PropertyAccessImpl;
 import org.apache.tapestry.internal.ioc.services.PropertyShadowBuilderImpl;
 import org.apache.tapestry.internal.ioc.services.ServiceObjectProvider;
+import org.apache.tapestry.internal.ioc.services.TypeCoercerImpl;
+import org.apache.tapestry.internal.services.ComponentInstantiatorSource;
+import org.apache.tapestry.ioc.Configuration;
 import org.apache.tapestry.ioc.MappedConfiguration;
 import org.apache.tapestry.ioc.ObjectProvider;
 import org.apache.tapestry.ioc.ServiceLifecycle;
@@ -40,6 +49,7 @@
  * @author Howard M. Lewis Ship
  */
 @Id("tapestry.ioc")
+@SuppressNullCheck
 public final class TapestryIOCModule
 {
     private final ClassFactory _classFactory;
@@ -65,7 +75,7 @@
      * and "primitive") but additional ones are accessed via this service (and its mapped
      * configuration).
      */
-    public ServiceLifecycleSource buildServiceLifecycleSource(
+    public static ServiceLifecycleSource buildServiceLifecycleSource(
             final Map<String, ServiceLifecycle> configuration)
     {
         return new ServiceLifecycleSource()
@@ -100,7 +110,7 @@
      * Services that provides read/write access to JavaBean properties. Encapsulates JavaBean
      * introspection, including serializing access to the non-thread-safe Introspector object.
      */
-    public PropertyAccess buildPropertyAccess()
+    public static PropertyAccess buildPropertyAccess()
     {
         return new PropertyAccessImpl();
     }
@@ -138,7 +148,7 @@
      * @param configuration
      *            map of ObjectProviders, keyed on prefix
      */
-    public ObjectProvider buildMasterObjectProvider(Map<String, ObjectProvider> configuration)
+    public static ObjectProvider buildMasterObjectProvider(Map<String, ObjectProvider> configuration)
     {
         return new MasterObjectProvider(configuration);
     }
@@ -146,7 +156,7 @@
     /**
      * Contributes the "service:" object provider.
      */
-    public void contributeMasterObjectProvider(
+    public static void contributeMasterObjectProvider(
             MappedConfiguration<String, ObjectProvider> configuration)
     {
         configuration.add("service", new ServiceObjectProvider());
@@ -154,14 +164,206 @@
 
     /** Used by the {@link org.apache.tapestry.ioc.services.LoggingDecorator} service. */
     @Lifecycle("perthread")
-    public ExceptionTracker buildExceptionTracker()
+    public static ExceptionTracker buildExceptionTracker()
     {
         return new ExceptionTrackerImpl();
     }
 
-    public ExceptionAnalyzer buildExceptionAnalyzer(@InjectService("PropertyAccess")
+    public static ExceptionAnalyzer buildExceptionAnalyzer(@InjectService("PropertyAccess")
     PropertyAccess access)
     {
         return new ExceptionAnalyzerImpl(access);
+    }
+
+    /**
+     * Returns the service that can coerce between different types.
+     */
+    public static TypeCoercer buildTypeCoercer(Collection<CoercionTuple> configuration)
+    {
+        return new TypeCoercerImpl(configuration);
+    }
+
+    /**
+     * Contributes a set of standard type coercions:
+     * <ul>
+     * <li>Object to String</li>
+     * <li>String to Double</li>
+     * <li>String to BigDecimal</li>
+     * <li>BigDecimal to Double</li>
+     * <li>Double to BigDecimal</li>
+     * <li>String to BigInteger</li>
+     * <li>BigInteger to Long</li>
+     * <li>String to Long</li>
+     * <li>Long to Byte</li>
+     * <li>Long to Short</li>
+     * <li>Long to Integer</li>
+     * <li>Double to Long</li>
+     * <li>Double to Float</li>
+     * <li>Long to Double</li>
+     * <li>String to Boolean ("false" is always false, other non-blank strings are true)</li>
+     * <li>Long to Boolean (true if long value is non zero)</li>
+     * <li>Null to Boolean (always false)</li>
+     * <li>Collection to Boolean (false if empty)</li>
+     * <li>Object to List (by wrapping as a singleton list)</li>
+     * </ul>
+     * 
+     * @see #buildTypeCoercer(Collection, ComponentInstantiatorSource)
+     */
+    @SuppressNullCheck
+    public static void contributeTypeCoercer(Configuration<CoercionTuple> configuration)
+    {
+        add(configuration, Object.class, String.class, new Coercion<Object, String>()
+        {
+            public String coerce(Object input)
+            {
+                return input.toString();
+            }
+        });
+
+        add(configuration, String.class, Double.class, new Coercion<String, Double>()
+        {
+            public Double coerce(String input)
+            {
+                return new Double(input);
+            }
+        });
+
+        // String to BigDecimal is important, as String->Double->BigDecimal would lose
+        // precision.
+
+        add(configuration, String.class, BigDecimal.class, new Coercion<String, BigDecimal>()
+        {
+            public BigDecimal coerce(String input)
+            {
+                return new BigDecimal(input);
+            }
+        });
+
+        add(configuration, BigDecimal.class, Double.class, new Coercion<BigDecimal, Double>()
+        {
+            public Double coerce(BigDecimal input)
+            {
+                return input.doubleValue();
+            }
+        });
+
+        add(configuration, String.class, BigInteger.class, new Coercion<String, BigInteger>()
+        {
+            public BigInteger coerce(String input)
+            {
+                return new BigInteger(input);
+            }
+        });
+
+        add(configuration, String.class, Long.class, new Coercion<String, Long>()
+        {
+            public Long coerce(String input)
+            {
+                return new Long(input);
+            }
+        });
+
+        add(configuration, Long.class, Byte.class, new Coercion<Long, Byte>()
+        {
+            public Byte coerce(Long input)
+            {
+                return input.byteValue();
+            }
+        });
+
+        add(configuration, Long.class, Short.class, new Coercion<Long, Short>()
+        {
+            public Short coerce(Long input)
+            {
+                return input.shortValue();
+            }
+        });
+
+        add(configuration, Long.class, Integer.class, new Coercion<Long, Integer>()
+        {
+            public Integer coerce(Long input)
+            {
+                return input.intValue();
+            }
+        });
+
+        add(configuration, Number.class, Long.class, new Coercion<Number, Long>()
+        {
+            public Long coerce(Number input)
+            {
+                return input.longValue();
+            }
+        });
+
+        add(configuration, Double.class, Float.class, new Coercion<Double, Float>()
+        {
+            public Float coerce(Double input)
+            {
+                return input.floatValue();
+            }
+        });
+
+        add(configuration, Long.class, Double.class, new Coercion<Long, Double>()
+        {
+            public Double coerce(Long input)
+            {
+                return input.doubleValue();
+            }
+        });
+
+        add(configuration, String.class, Boolean.class, new Coercion<String, Boolean>()
+        {
+            public Boolean coerce(String input)
+            {
+                String trimmed = input.trim();
+
+                if (trimmed.equalsIgnoreCase("false") || trimmed.length() == 0)
+                    return false;
+
+                // Any non-blank string but "false"
+
+                return true;
+            }
+        });
+
+        add(configuration, Long.class, Boolean.class, new Coercion<Long, Boolean>()
+        {
+            public Boolean coerce(Long input)
+            {
+                return input.longValue() != 0;
+            }
+        });
+
+        add(configuration, void.class, Boolean.class, new Coercion<Void, Boolean>()
+        {
+            public Boolean coerce(Void input)
+            {
+                return false;
+            }
+        });
+
+        add(configuration, Collection.class, Boolean.class, new Coercion<Collection, Boolean>()
+        {
+            public Boolean coerce(Collection input)
+            {
+                return !input.isEmpty();
+            }
+        });
+
+        add(configuration, Object.class, List.class, new Coercion<Object, List>()
+        {
+            public List coerce(Object input)
+            {
+                return Collections.singletonList(input);
+            }
+        });
+    }
+
+    private static <S, T> void add(Configuration<CoercionTuple> configuration, Class<S> sourceType,
+            Class<T> targetType, Coercion<S, T> coercion)
+    {
+        CoercionTuple<S, T> tuple = new CoercionTuple<S, T>(sourceType, targetType, coercion);
+
+        configuration.add(tuple);
     }
 }

Copied: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TypeCoercer.java (from r462686, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TypeCoercer.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TypeCoercer.java?view=diff&rev=464060&p1=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TypeCoercer.java&r1=462686&p2=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TypeCoercer.java&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TypeCoercer.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TypeCoercer.java Sat Oct 14 16:30:48 2006
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.services;
+package org.apache.tapestry.ioc.services;
 
 /**
  * Makes use of {@link Coercion}s (via {@link CoercionTuple}s) to convert between an input value
@@ -25,7 +25,9 @@
 {
     /**
      * Performs a coercion from an input type to a desired output type. When the target type is a
-     * primitive, the actual conversion will be to the equivalent wrapper type.
+     * primitive, the actual conversion will be to the equivalent wrapper type. In some cases, the
+     * TypeCoercer will need to search for an appropriate coercion, and may even combine existing
+     * coercions to form new ones; in those cases, the results of the search are cached.
      * 
      * @param <S>
      *            source type (input)
@@ -37,4 +39,7 @@
      * @return
      */
     <S, T> T coerce(S input, Class<T> targetType);
+
+    /** Clears cached information stored by the TypeCoercer. */
+    void clearCache();
 }