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 [2/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...

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java Sat Oct 14 16:30:48 2006
@@ -16,10 +16,7 @@
 
 import java.io.IOException;
 import java.lang.annotation.Annotation;
-import java.math.BigDecimal;
-import java.math.BigInteger;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
@@ -49,7 +46,6 @@
 import org.apache.tapestry.internal.services.DefaultInjectionProvider;
 import org.apache.tapestry.internal.services.EnvironmentImpl;
 import org.apache.tapestry.internal.services.EnvironmentalWorker;
-import org.apache.tapestry.internal.services.PageRenderDispatcher;
 import org.apache.tapestry.internal.services.InfrastructureImpl;
 import org.apache.tapestry.internal.services.InfrastructureManagerImpl;
 import org.apache.tapestry.internal.services.InjectWorker;
@@ -57,13 +53,13 @@
 import org.apache.tapestry.internal.services.InternalModule;
 import org.apache.tapestry.internal.services.MarkupWriterImpl;
 import org.apache.tapestry.internal.services.OnEventWorker;
+import org.apache.tapestry.internal.services.PageRenderDispatcher;
 import org.apache.tapestry.internal.services.PageResponseRenderer;
 import org.apache.tapestry.internal.services.ParameterWorker;
 import org.apache.tapestry.internal.services.RequestGlobalsImpl;
 import org.apache.tapestry.internal.services.RequestPageCache;
 import org.apache.tapestry.internal.services.RetainWorker;
 import org.apache.tapestry.internal.services.StaticFilesFilter;
-import org.apache.tapestry.internal.services.TypeCoercerImpl;
 import org.apache.tapestry.internal.services.UnclaimedFieldWorker;
 import org.apache.tapestry.internal.services.WebContextImpl;
 import org.apache.tapestry.internal.services.WebRequestImpl;
@@ -83,6 +79,7 @@
 import org.apache.tapestry.ioc.services.ClassFactory;
 import org.apache.tapestry.ioc.services.PipelineBuilder;
 import org.apache.tapestry.ioc.services.PropertyShadowBuilder;
+import org.apache.tapestry.ioc.services.TypeCoercer;
 
 /**
  * The root module for Tapestry.
@@ -110,7 +107,8 @@
     private final PageResponseRenderer _pageResponseRenderer;
 
     // Yes, you can inject services defined by this module into this module. The service proxy is
-    // created without instantiating the module itself.
+    // created without instantiating the module itself. We're careful about making as many
+    // service builder and contributor methods static as possible to avoid recursive build exceptions.
 
     public TapestryModule(@InjectService("tapestry.ioc.PipelineBuilder")
     PipelineBuilder pipelineBuilder, @InjectService("tapestry.ioc.PropertyShadowBuilder")
@@ -130,7 +128,7 @@
         _pageResponseRenderer = pageResponseRenderer;
     }
 
-    private <T> void add(Configuration<InfrastructureContribution> configuration,
+    private static <T> void add(Configuration<InfrastructureContribution> configuration,
             ServiceLocator locator, Class<T> serviceInterface)
     {
         String className = serviceInterface.getName();
@@ -149,7 +147,7 @@
         configuration.add(contribution);
     }
 
-    public ApplicationGlobals buildApplicationGlobals()
+    public static ApplicationGlobals buildApplicationGlobals()
     {
         return new ApplicationGlobalsImpl();
     }
@@ -237,7 +235,7 @@
                 terminator);
     }
 
-    public Infrastructure buildInfrastructure(Log log,
+    public static Infrastructure buildInfrastructure(Log log,
             Collection<InfrastructureContribution> configuration)
     {
         InfrastructureManager manager = new InfrastructureManagerImpl(log, configuration);
@@ -245,7 +243,7 @@
         return new InfrastructureImpl(manager);
     }
 
-    public MarkupWriterFactory buildMarkupWriterFactory()
+    public static MarkupWriterFactory buildMarkupWriterFactory()
     {
         // Temporary ...
         return new MarkupWriterFactory()
@@ -267,7 +265,7 @@
     }
 
     @Lifecycle("perthread")
-    public RequestGlobals buildRequestGlobals()
+    public static RequestGlobals buildRequestGlobals()
     {
         return new RequestGlobalsImpl();
     }
@@ -317,8 +315,8 @@
      * and terminates the pipeline by returning false. Generally, most filters should be ordered
      * after this filter.
      */
-    public void contributeWebRequestHandler(OrderedConfiguration<WebRequestFilter> configuration,
-            @InjectService("WebContext")
+    public static void contributeWebRequestHandler(
+            OrderedConfiguration<WebRequestFilter> configuration, @InjectService("WebContext")
             WebContext webContext,
             @InjectService("tapestry.internal.DefaultRequestExceptionHandler")
             final RequestExceptionHandler exceptionHandler)
@@ -352,39 +350,20 @@
     }
 
     /**
-     * Contributes a leading (before:*.*) filter into the pipeline that sets the infrastructure mode
-     * to "servlet".
-     */
-
-    public void contributeServletApplicationInitializer(
-            OrderedConfiguration<ServletApplicationInitializerFilter> configuration,
-            @InjectService("Infrastructure")
-            final Infrastructure infrastructure)
-    {
-        ServletApplicationInitializerFilter contribution = new ServletApplicationInitializerFilter()
-        {
-            public void initializeApplication(ServletContext context,
-                    ServletApplicationInitializer initializer)
-            {
-                infrastructure.setMode("servlet");
-
-                initializer.initializeApplication(context);
-            }
-        };
-
-        configuration.add("SetInfrastructureMode", contribution, "before:*.*");
-    }
-
-    /**
      * Contributes properties: componentNameExpander, markupWriterFactory, request
      */
-    public void contributeInfrastructure(Configuration<InfrastructureContribution> configuration,
-            ServiceLocator locator, @InjectService("WebRequest")
-            WebRequest request)
+    public static void contributeInfrastructure(
+            Configuration<InfrastructureContribution> configuration, ServiceLocator locator,
+            @InjectService("WebRequest")
+            WebRequest request, @InjectService("WebResponse")
+            WebResponse response, @InjectService("tapestry.ioc.TypeCoercer")
+            TypeCoercer typeCoercer)
     {
         add(configuration, locator, MarkupWriterFactory.class);
 
         configuration.add(new InfrastructureContribution("request", request));
+        configuration.add(new InfrastructureContribution("response", response));
+        configuration.add(new InfrastructureContribution("typeCoercer", typeCoercer));
     }
 
     /**
@@ -392,7 +371,7 @@
      * mapped to the provider prefix "infrastructure".
      */
     @Contribute("tapestry.ioc.MasterObjectProvider")
-    public void contributeInfrastructureToMasterObjectProvider(
+    public static void contributeInfrastructureToMasterObjectProvider(
             MappedConfiguration<String, ObjectProvider> configuration,
             @InjectService("Infrastructure")
             Infrastructure infrastructure)
@@ -412,7 +391,7 @@
                 _requestPageCache), "after:HTML");
     }
 
-    public ComponentClassResolver buildComponentClassResolver(
+    public static ComponentClassResolver buildComponentClassResolver(
             @InjectService("tapestry.internal.ComponentInstantiatorSource")
             ComponentInstantiatorSource source, Collection<LibraryMapping> configuration)
     {
@@ -425,18 +404,19 @@
         return service;
     }
 
-    public void contributeComponentClassResolver(Configuration<LibraryMapping> configuration)
+    public static void contributeComponentClassResolver(Configuration<LibraryMapping> configuration)
     {
         configuration.add(new LibraryMapping("core", "org.apache.tapestry.corelib"));
     }
 
-    public BindingSource buildBindingSource(Map<String, BindingFactory> configuration)
+    public static BindingSource buildBindingSource(Map<String, BindingFactory> configuration)
     {
         return new BindingSourceImpl(configuration);
     }
 
     /** Contributes the factory for "literal:" bindings. */
-    public void contributeBindingSource(MappedConfiguration<String, BindingFactory> configuration,
+    public static void contributeBindingSource(
+            MappedConfiguration<String, BindingFactory> configuration,
             @InjectService("tapestry.internal.PropBindingFactory")
             BindingFactory propBindingFactory)
     {
@@ -448,7 +428,7 @@
      * Returns a {@link ClassFactory} that can be used to create extra classes around component
      * classes.
      */
-    public ClassFactory buildComponentClassFactory(Log log,
+    public static ClassFactory buildComponentClassFactory(Log log,
             @InjectService("tapestry.internal.ComponentInstantiatorSource")
             ComponentInstantiatorSource source)
     {
@@ -473,7 +453,8 @@
      * <li>Default -- looks for a unique IoC service that matches the field type</li>
      * </ul>
      */
-    public void contributeInjectionProvider(OrderedConfiguration<InjectionProvider> configuration)
+    public static void contributeInjectionProvider(
+            OrderedConfiguration<InjectionProvider> configuration)
     {
         configuration.add("ComponentResources", new ComponentResourcesInjectionProvider());
         configuration.add("Default", new DefaultInjectionProvider(), "after:*.*");
@@ -496,7 +477,7 @@
      * 
      * @param configuration
      */
-    public void contributeComponentClassTransformWorker(
+    public static void contributeComponentClassTransformWorker(
             OrderedConfiguration<ComponentClassTransformWorker> configuration,
             ServiceLocator locator, @InjectService("tapestry.ioc.MasterObjectProvider")
             ObjectProvider objectProvider, @InjectService("InjectionProvider")
@@ -525,7 +506,7 @@
         configuration.add("UnclaimedField", new UnclaimedFieldWorker(), "after:*.*");
     }
 
-    private void add(OrderedConfiguration<ComponentClassTransformWorker> configuration,
+    private static void add(OrderedConfiguration<ComponentClassTransformWorker> configuration,
             MethodSignature signature, Class<? extends Annotation> annotationClass)
     {
         // make the name match the annotation class name.
@@ -535,206 +516,8 @@
         configuration.add(name, new ComponentLifecycleMethodWorker(signature, annotationClass));
     }
 
-    /**
-     * Returns the service that can coerce between different types. The service caches a good bit of
-     * data that may be invalidated when the component class loader is invalidated.
-     */
-    public TypeCoercer buildTypeCoercer(Collection<CoercionTuple> configuration,
-            @InjectService("tapestry.internal.ComponentInstantiatorSource")
-            ComponentInstantiatorSource componentInstantiatorSource)
-    {
-        TypeCoercerImpl service = new TypeCoercerImpl(configuration);
-
-        componentInstantiatorSource.addInvalidationListener(service);
-
-        return service;
-    }
-
-    /**
-     * 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)
-     */
-    public 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 <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);
-    }
-
     @Lifecycle("perthread")
-    public Environment buildEnvironment()
+    public static Environment buildEnvironment()
     {
         return new EnvironmentImpl();
     }
@@ -750,7 +533,7 @@
      * @param environment
      * @return
      */
-    public Runnable buildPageRenderInitializer(final Collection<Runnable> configuration,
+    public static Runnable buildPageRenderInitializer(final Collection<Runnable> configuration,
             @InjectService("Environment")
             final Environment environment)
     {

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?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- 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 Sat Oct 14 16:30:48 2006
@@ -52,6 +52,7 @@
 import org.apache.tapestry.ioc.def.DecoratorDef;
 import org.apache.tapestry.ioc.def.ModuleDef;
 import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.model.ComponentModel;
 import org.apache.tapestry.model.MutableComponentModel;
 import org.apache.tapestry.model.ParameterModel;
@@ -59,7 +60,6 @@
 import org.apache.tapestry.services.ClassTransformation;
 import org.apache.tapestry.services.ComponentClassResolver;
 import org.apache.tapestry.services.MethodSignature;
-import org.apache.tapestry.services.TypeCoercer;
 import org.apache.tapestry.services.WebRequest;
 import org.apache.tapestry.services.WebResponse;
 

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/StrategyRegistry.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/StrategyRegistry.java?view=auto&rev=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/StrategyRegistry.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/StrategyRegistry.java Sat Oct 14 16:30:48 2006
@@ -0,0 +1,126 @@
+package org.apache.tapestry.util;
+
+import static org.apache.tapestry.util.CollectionFactory.newList;
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+import static org.apache.tapestry.util.CollectionFactory.newThreadSafeMap;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tapestry.internal.annotations.SuppressNullCheck;
+import org.apache.tapestry.internal.ioc.IOCUtilities;
+import org.apache.tapestry.internal.util.InheritanceSearch;
+
+/**
+ * A key component in implementing the "Gang of Four" Strategy pattern. A StrategyRegistry will
+ * match up a given input type with a registered strategy for that type.
+ * 
+ * @author Howard M. Lewis Ship
+ * @param <A>
+ *            the type of the strategy adapter
+ */
+public final class StrategyRegistry<A>
+{
+    private final Class<A> _adapterType;
+
+    private final Map<Class, A> _registrations = newMap();
+
+    private final Map<Class, A> _cache = newThreadSafeMap();
+
+    /**
+     * Creates a strategy registry for the given adapter type.
+     * 
+     * @param adapterType
+     *            the type of adapter retrieved from the registry
+     * @param registrations
+     *            map of registrations (the contents of the map are copied)
+     */
+    public StrategyRegistry(final Class<A> adapterType, Map<Class, A> registrations)
+    {
+        _adapterType = adapterType;
+        _registrations.putAll(registrations);
+    }
+
+    public static <A> StrategyRegistry<A> newInstance(Class<A> adapterType,
+            Map<Class, A> registrations)
+    {
+        return new StrategyRegistry<A>(adapterType, registrations);
+    }
+
+    public void clearCache()
+    {
+        _cache.clear();
+    }
+
+    public Class getAdapterType()
+    {
+        return _adapterType;
+    }
+
+    /**
+     * Gets an adapter for an object. Searches based on the value's class, unless the value is null,
+     * in which case, a search on class void is used.
+     * 
+     * @param value
+     *            for which an adapter is needed
+     * @return the adaptoer for the value
+     * @throws IllegalArgumentException
+     *             if no matching adapter may be found
+     */
+    @SuppressNullCheck
+    public A getByInstance(Object value)
+    {
+        return get(value == null ? void.class : value.getClass());
+    }
+
+    /**
+     * Searches for an adapter corresponding to the given input type.
+     * 
+     * @param type
+     *            the type to search
+     * @return the corresponding adapter
+     * @throws IllegalArgumentException
+     *             if no matching adapter may be found
+     */
+    public A get(Class type)
+    {
+        A result = _cache.get(type);
+
+        if (result == null)
+        {
+            result = findMatch(type);
+            _cache.put(type, result);
+        }
+
+        return result;
+    }
+
+    private A findMatch(Class type)
+    {
+        for (Class t : new InheritanceSearch(type))
+        {
+            A result = _registrations.get(t);
+
+            if (result != null)
+                return result;
+        }
+
+        // Report the error. These things really confused the hell out of people in Tap4, so we're
+        // going the extra mile on the exception message.
+
+        List<String> names = newList();
+        for (Class t : _registrations.keySet())
+            names.add(t.getName());
+
+        throw new IllegalArgumentException(UtilMessages.noStrategyAdapter(
+                type,
+                _adapterType,
+                IOCUtilities.joinSorted(names)));
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("StrategyRegistry[%s]", _adapterType.getName());
+    }
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/UtilMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/UtilMessages.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/UtilMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/UtilMessages.java Sat Oct 14 16:30:48 2006
@@ -42,4 +42,13 @@
     {
         return MESSAGES.format("bad-cast", parameterName, parameterValue, type.getName());
     }
+
+    static String noStrategyAdapter(Class inputType, Class adapterType, String catalog)
+    {
+        return MESSAGES.format(
+                "no-strategy-adapter",
+                inputType.getName(),
+                adapterType.getName(),
+                catalog);
+    }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/services/ServiceStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/services/ServiceStrings.properties?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/services/ServiceStrings.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/services/ServiceStrings.properties Sat Oct 14 16:30:48 2006
@@ -32,3 +32,4 @@
 object-reference-format-error=Object reference '%s' does not contain an provider prefix (such as 'service:').
 unknown-object-provider=Object provider '%s' does not exist (in object reference '%s').
 shutdown-listener-error=Error notifying %s of registry shutdown: %s
+no-coercion-found=Could not find a coercion from type %s to type %s.  Available coercions: %s.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties Sat Oct 14 16:30:48 2006
@@ -47,7 +47,6 @@
   or define the component inside class %s using the @Component annotation on a private instance variable.
 embedded-components-not-in-template=Embedded component(s) %s are defined within component class %s, but are not present in the component template.
 binding-source-failure=Could not convert '%s' into a component parameter binding: %s
-no-coercion-found=Could not find a coercion from type %s to type %s.  Available coercions: %s.
 unable-to-resolve-component-type=Unable to resolve component '%s' to a component class name.
 page-does-not-exist=Page '%s' is not defined by this application.
 page-name-unresolved=Unable to resolve class name %s to a logical page name.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/util/UtilStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/util/UtilStrings.properties?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/util/UtilStrings.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/util/UtilStrings.properties Sat Oct 14 16:30:48 2006
@@ -15,4 +15,4 @@
 unable-to-read-last-modified=Unable to read last modified time stamp of resource %s: %s
 dependency-cycle=Unable to add '%s' as a dependency of '%s', as that forms a dependency cycle ('%<s' depends on itself via '%1$s'). The dependency has been ignored.
 duplicate-orderer=Could not add object with duplicate id '%s'.  The duplicate object has been ignored.
-constraint-format=Could not parse ordering constraint '%s' (for '%s'). The constraint has been ignored.
\ No newline at end of file
+constraint-format=Could not parse ordering constraint '%s' (for '%s'). The constraint has been ignored.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/util/UtilStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/util/UtilStrings.properties?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/util/UtilStrings.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/util/UtilStrings.properties Sat Oct 14 16:30:48 2006
@@ -14,4 +14,5 @@
 
 parameter-was-null=Parameter %s was null.
 parameter-was-blank=Parameter %s was null or contained only whitespace.
-bad-cast=Parameter %s (%s) is not assignable to type %s.
\ No newline at end of file
+bad-cast=Parameter %s (%s) is not assignable to type %s.
+no-strategy-adapter=No adapter from type %s to type %s is available (registered types are %s).

Added: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/infrastructure.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/infrastructure.apt?view=auto&rev=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/infrastructure.apt (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/infrastructure.apt Sat Oct 14 16:30:48 2006
@@ -0,0 +1,61 @@
+ ----
+ Infrastructure and Overrides
+ ----
+
+Introduction
+
+  Tapestry includes an object provider, "infrastructure:", which is used to access
+  the key built-in services provided by Tapestry.  This allows you to inject, 
+  into  your components or services, any of the services, using a shorter name, i.e.,
+  "infrastructure:request" vs. "service:tapestry.WebRequest".
+
+  This functionaliy serves a separate, and ultimately more important purpose.
+  
+  In the vast majority of applications developed using Tapestry, the built in set of 
+  services does exactly what you need them to do. However, there are always outliers,
+  very special cases that aren't addressed. The infrastructure mechanism 
+
+infrastructure: object provider
+
+
+  The infrastructure 
+  {{{../ioc/provider.html}object provider}} 
+  is a key element in making Tapestry extensible; it adds a layer of
+  indirection between service implementations and their collaborators. Using the infrastructure
+  provider allows applications to identify and override individual services within Tapestry's
+  network of services. 
+  
+  The <expression> for the infrastructure provider is the name of a property. This property is
+  mapped to a particular service via a <pair> of services. The
+  {{{../apidocs/org/apache/tapestry/services/Infrastructure.html}tapestry.Infrastructure}} service
+  has a mapped configuration of 
+  {{{../apidocs/org/apache/tapestry/services/InfrastructureContribution.html}InfrastructureContribution}}s.
+  Each contribution is keyed on the property it provides.
+  
+  A second service (<<Caution:>> not yet implemented), tapestry.InfrastructureOverride, exists
+  to support a second, identical configuration. Any properties contributed here override the normal
+  Infrastructure properties.
+  
+  In order to override an individual Tapestry service, all that is necessary is to provide
+  a new implementation as a new service, and contribute that service into the configuration for
+  the tapestry.InfrastructureOverride configuration.
+  
+  In many cases, the original service can be injected into the new implementation; this must be done
+  using the original service's fully qualified service id.
+  
+  The following table identifies the properties that are available via the infrastructure provider
+  by default:
+  
+*-----------------------+--------------------------------------------------------------------+------------------------------------+
+| <<Property>>          | <<Service Interfeace>>                                             | <<Default Service>>               |
+*-----------------------+--------------------------------------------------------------------+-----------------------------------+
+| request               | {{{../apidocs/org/apache/tapestry/services/WebRequest.html}WebRequest}}  | tapestry.WebRequest         |        
+*-----------------------+--------------------------------------------------------------------------------------------------------+
+| response | {{{../apidocs/org/apache/tapestry/services/WebResponse.html}WebResponse}}  | tapestry.WebResponse |        
+*-----------------------+--------------------------------------------------------------------------------------------------------+
+Default properties available via the infrastructure object provider
+
+Contributing to Infrastructure
+
+  To Be Documented
+  
\ No newline at end of file

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/command.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/command.apt?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/command.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/command.apt Sat Oct 14 16:30:48 2006
@@ -54,7 +54,7 @@
   We can just let the ChainBuilder service create that object.
   
 +----+
-  public MyChainService buildMyChainService(List<MyChainService> commands,
+  public static MyChainService buildMyChainService(List<MyChainService> commands,
     @InjectService("tapestry.ioc.ChainBuilder")
     ChainBuilder chainBuilder)
   {

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/configuration.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/configuration.apt?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/configuration.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/configuration.apt Sat Oct 14 16:30:48 2006
@@ -4,8 +4,9 @@
  
 Tapestry IoC Configurations
 
-  One of the key concepts on Tapestry IoC is <distributed configuration>. This is an idea adapted
-  from the Eclipse Plugin API and evidenced in HiveMind prior to Tapestry 5 IoC.
+  One of the key concepts on Tapestry IoC is <distributed configuration>. This is a
+  concept borrowed from the Eclipse Plugin API and evidenced in 
+  HiveMind prior to Tapestry 5 IoC.
   
   So ... nice term, what does it mean?
   
@@ -24,7 +25,7 @@
   A central service uses this configuration to select a particular FileService interface:
   
 +------+
-  public FileServicer buildFileServicerDispatcher(Map<String,FileServicer> contributions)
+  public static FileServicer buildFileServicerDispatcher(Map<String,FileServicer> contributions)
   {
     return new FileServiceDispatcherImpl(contributions);
   } 
@@ -40,7 +41,7 @@
   
 +------+
   @Contribute("FileServicerDispatcher")
-  public void contributeFileServicers(MappedConfiguration<String,FileServicer> configuration)
+  public static void contributeFileServicers(MappedConfiguration<String,FileServicer> configuration)
   {
     configuration.add("txt", new TextFileServicer());
     configuration.add("pdf", new PDFFileServicer());
@@ -51,7 +52,7 @@
   
 +------+
   @Contribute("FileServicerDispatcher")
-  public void contributeFileServicers(MappedConfiguration<String,FileServicer> configuration,
+  public static void contributeFileServicers(MappedConfiguration<String,FileServicer> configuration,
     @InjectService("TextFileServicer") FileServicer textFileServicer,
     @InjectService("PDFFileServicer") FileServicer pdfFileServicer,
   {
@@ -66,7 +67,7 @@
   
 +------+
   @Contribute("some.module.FileServicerDispatcher")
-  public void contributeOfficeFileServicers(MappedConfiguration<String,FileServicer> configuration)
+  public static void contributeOfficeFileServicers(MappedConfiguration<String,FileServicer> configuration)
   {
     configuration.add("doc", new WordFileServicer());
     configuration.add("ppt", new PowerPointFileServicer());
@@ -111,7 +112,7 @@
   objects.  It doesn't care what order the Runnable objects are executed in.
   
 +------+
-  public Runnable buildStartup(final Collection<Runnable> configuration)
+  public static Runnable buildStartup(final Collection<Runnable> configuration)
   {
     return new Runnable()
     {
@@ -134,7 +135,7 @@
   
 +------+
   @Contribute("some.module.Startup")
-  public void contributeStartups(Configuration<Runnable> configuration)
+  public static void contributeStartups(Configuration<Runnable> configuration)
   {
     configuration.add(new JMSStartup());
     configuration.add(new FileSystemStartup());
@@ -171,7 +172,7 @@
   So, if we changed our Startup service to require a specific order for startup:
   
 +------+
-  public Runnable buildStartup(final List<Runnable> configuration)
+  public static Runnable buildStartup(final List<Runnable> configuration)
   {
     return new Runnable()
     {
@@ -194,7 +195,7 @@
  
 +------+
   @Contribute("some.module.Startup")
-  public void contributeStartups(OrderedConfiguration<Runnable> configuration)
+  public static void contributeStartups(OrderedConfiguration<Runnable> configuration)
   {
     configuration.add("JMS", new JMSStartup());
     configuration.add("FileSystem", new FileSystemStartup(), "after:*.CacheSetup");

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/decorator.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/decorator.apt?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/decorator.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/decorator.apt Sat Oct 14 16:30:48 2006
@@ -63,12 +63,12 @@
 @Id("myapp")
 public class MyAppModule
 {
-  public Indexer buildIndexer()
+  public static Indexer buildIndexer()
   {
     return new IndexerImpl();
   }
   
-  public <T> T decorateIndexer(Class<T> serviceInterface, T delegate, 
+  public static <T> T decorateIndexer(Class<T> serviceInterface, T delegate, 
     String serviceId, Log serviceLog,
     @InjectService("tapestry.ioc.LoggingDecorator")
     LoggingDecorator decorator)
@@ -118,7 +118,7 @@
 @Id("myapp")
 public class MyAppModule
 {
-  public Indexer buildIndexer(Class serviceInterface, Log serviceLog,
+  public static Indexer buildIndexer(Class serviceInterface, Log serviceLog,
     @InjectService("tapestry.ioc.LoggingDecorator")
     LoggingInterceptorFactory decorator)
   {
@@ -144,7 +144,7 @@
   
 +---------------------+    
   @Match("*")
-  public <T> T decorateLogging(Class<T> serviceInterface, T delegate, 
+  public static <T> T decorateLogging(Class<T> serviceInterface, T delegate, 
     String serviceId, Log serviceLog,
     @InjectService("tapestry.ioc.LoggingDecorator")
     LoggingDecorator decorator)
@@ -186,7 +186,7 @@
 +---------------------+    
   @Match("*")
   @Order("before:*.*")
-  public <T> T decorateLogging(Class<T> serviceInterface, T delegate, 
+  public static <T> T decorateLogging(Class<T> serviceInterface, T delegate, 
     String serviceId, Log serviceLog,
     @InjectService("tapestry.ioc.LoggingDecorator")
     LoggingDecorator decorator)

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/index.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/index.apt?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/index.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/index.apt Sat Oct 14 16:30:48 2006
@@ -90,18 +90,19 @@
   module builder class, but you can't realistically unit test an XML descriptor.
   
   Tapestry IOC modules are easily packaged into JAR files, supporting 
-  zero-configuration usage: ust drop the JAR onto the classpath.
+  zero-configuration usage: just drop the JAR onto the classpath.
   
   Another goal is "developer friendliness". This is a true cross-cutting concern, and one not likely to be packaged
   into an aspect any time soon. The Tapestry IoC framework is designed to be easy to use and easy to understand.
-  Further, when things go wrong, it actively attempts to help you by careful checks and careful error messages. Further,
+  Further, when things go wrong, it actively attempts to help you by 
+	comprehensive checks and carefully composed error messages. Further,
   all user-visible objects implement
   {{{http://howardlewisship.com/blog/2003/08/importance-of-tostring.html}a reasonable toString() method}},
   to help you understand what's going when you inevitably try to figure things out in the debugger. 
   
   In terms of building services using Tapestry IoC ... the objective here is "lightness", a term borrowed from the board
   game {{{http://boardgamegeek.com/game/188}Go}}. In Go, two players place stones on an initially empty board, 
-  creating walls to enclose territory or eliminate the encroaching stones player by the opponent. The winner at the
+  creating walls to enclose territory or eliminate the encroaching stones played by the opponent. The winner at the
   end of the game controls the most territory, and it is the constant tension between taking territory and defending
   existing territory that drives the game.   In Go, groups of playing stones are "light" (or have "good shape")
   when the minimum number of them control the maximum area on the board.  Playing "heavy" just gives your opponent a free
@@ -157,7 +158,7 @@
   * A module defines a <<module id>> that is used as a prefix when naming services within the module. This is very much equivalent
     to a Java package name.  Module ids must be unique within the registry of modules.
     
-  * A module is defined by a <<module builder>>, a specific class that is instantiated.
+  * A module is defined by a <<module builder>>, a specific class containing static or instance methods.
   
   * Methods of the module builder class define the services provided by the module, 
     and the same methods are responsible
@@ -177,8 +178,10 @@
   service interface as the service.
   Control is given over the order in which decorators are applied to a service.
   
-  A service may have a <<configuration>>. The configuration is either a map, a collection, or an ordered list. The configuration is contructed
-  from <<contributions>> provided by one or more modules. 
+  A service may have a <<configuration>>. The configuration is either a map, a collection, or an ordered list. The service defines the type
+  of object allowed to be contributed into the configuration. The configuration is contructed
+  from <<contributions>> provided by one or more modules.   <<Service contributor methods>> are invoked to contribute objects into
+  configurations.
   
   <Note: In HiveMind, services and configurations were separate, which often lead
   to linked pairs of similarily named services and configurations. For Tapestry IoC, each service is allowed to have a single configuration,

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/module.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/module.apt?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/module.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/module.apt Sat Oct 14 16:30:48 2006
@@ -11,14 +11,14 @@
 
   A module bulider defines builder methods, one for each service provided by the module.
 
-  Service builder methods are public methods. Here's a trivial example:
+  Service builder methods are public methods. They are often static. Here's a trivial example:
 
 +-----------------------------------------------------------------------------------+
 package org.example.myapp.services;
 
 public class MyAppModule
 {
-  public Indexer buildIndexer()
+  public static Indexer buildIndexer()
   {
     return new IndexerImpl();
   }
@@ -28,13 +28,13 @@
   By default, a module's id is the same as its package name (we'll see how to override
   that shortly).  Here the module id will be org.example.myapp.services.
 
-  Any public method whose name starts with "build" is a service builder method, implicitly
+  Any public method (static or instance) whose name starts with "build" is a service builder method, implicitly
   defining a service within the module.  Here we're defining a service around
   the Indexer service interface (presumably also in the org.example.myapp.services
   package).
 
   The service's unqualified id (the part after the module id) is derived from the method name.
-  Here "build" was stripped of "buildIndexer", leaving "Indexer".  That's the unqualified id.
+  Here "build" was stripped off of "buildIndexer", leaving "Indexer".  That's the unqualified id.
   Prefixing with the module id results in the fully qualfied id 
   org.example.myapp.services.Indexer.
 
@@ -55,7 +55,7 @@
 @Id("myapp")
 public class MyAppModule
 {
-  public Indexer buildIndexer()
+  public static Indexer buildIndexer()
   {
     return new IndexerImpl();
   }
@@ -108,6 +108,11 @@
 }
 +-----------------------------------------------------------------------------------+
 
+  Notice that we've switched from <static> methods to <instance> methods.  Since the builder
+  methods are not static, the MyModule class will be instantiated so that the methods may be
+  invoked. The constructor receives two common dependencies, which are stored into instance
+  fields that may later be used inside service builder methods such as buildIndexer().
+
   In addition to injecting dependencies with the @InjectService and @Inject annotations,
   you may also inject a number of <module> resources:
   
@@ -123,7 +128,7 @@
   the module constructor is dependent on itself. For example, if you invoke a method on any injected services
   defined within the same module from the module builder's constructor,
   then the service implementation will be needed. Creating service implementations
-  requires the module builder instance ... that's a recursive reference.
+  requires the module builder instance ... that's a recursive reference. 
   
   Another common example would be using @Inject("infrastructure:<property>") when the module being constructed
   contributes into the tapestry.Infrastructure service's configuration. Here, to resolve the contribution, Tapestry
@@ -216,4 +221,8 @@
   even those inherited from base classes.  Tapestry <only> sees public methods.  
   
   By convention, module builder class names end in Module and are final classes.
-  
\ No newline at end of file
+  
+  You don't <have> to define your methods as static. The use of static methods is only absolutely
+  necessary in a few cases, where the constructor for a module is dependent on contributions
+  from the same module (this creates a chicken-and-the-egg situation that is resolved through
+  static methods).
\ No newline at end of file

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/pipeline.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/pipeline.apt?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/pipeline.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/pipeline.apt Sat Oct 14 16:30:48 2006
@@ -72,7 +72,7 @@
   must be provided.  The bridges and the terminator implement the service interface.
   
 +-----+
-  public StringTransformService buildStringTransform(
+  public static StringTransformService buildStringTransform(
     @InjectService("tapestry.ioc.PipelineBuilder")
     PipelineBuilder builder,
     List<StringTransformFilter> configuration,

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/provider.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/provider.apt?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/provider.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/provider.apt Sat Oct 14 16:30:48 2006
@@ -28,39 +28,9 @@
   
 * infrastructure provider
 
-  The infrastructure provider is a key element in making Tapestry extensible; it adds a layer of
-  indirection between service implementations and their collaborators. Using the infrastructure
-  provider allows applications to identify and override individual services within Tapestry's
-  network of services. 
-  
-  The <expression> for the infrastructure provider is the name of a property. This property is
-  mapped to a particular service via a <pair> of services. The
-  {{{../apidocs/org/apache/tapestry/services/Infrastructure.html}tapestry.Infrastructure}} service
-  has a mapped configuration of 
-  {{{../apidocs/org/apache/tapestry/services/InfrastructureContribution.html}InfrastructureContribution}}s.
-  Each contribution is keyed on the property it provides.
-  
-  A second service (<<Caution:>> not yet implemented), tapestry.InfrastructureOverride, exists
-  to support a second, identical configuration. Any properties contributed here override the normal
-  Infrastructure properties.
-  
-  In order to override an individual Tapestry service, all that is necessary is to provide
-  a new implementation as a new service, and contribute that service into the configuration for
-  the tapestry.InfrastructureOverride configuration.
-  
-  In many cases, the original service can be injected into the new implementation; this must be done
-  using the original service's fully qualified service id.
-  
-  The following table identifies the properties that are available via the infrastructure provider
-  by default:
-  
-*-----------------------+--------------------------------------------------------------------------------------------------------+
-| <<Property>>          | <<Default Service or Implementation>>                                                                  |
-*-----------------------+--------------------------------------------------------------------------------------------------------+
-| request               | {{{../apidocs/org/apache/tapestry/services/WebRequest.html}tapestry.WebRequest}}                |
-*-----------------------+--------------------------------------------------------------------------------------------------------+
-Default properties available via the infrastructure object provider
-  
+  The tapestry module provides the
+  {{{../guide/infrastructure.html}infrastructure}} object provider, which exists
+  to provide shorter names for injecting services and to support overrides.  
   
 Defining New Providers
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt Sat Oct 14 16:30:48 2006
@@ -23,7 +23,7 @@
 @Id("myapp")
 public class MyAppModule
 {
-  public Indexer buildIndexer()
+  public static Indexer buildIndexer()
   {
     return new IndexerImpl();
   }
@@ -42,7 +42,7 @@
   when it executes, and a FileSystem to access files and store indexes.
   
 +-----------------------------------------------------------------------------------+
-  public Indexer buildIndexer(@InjectService("JobScheduler")
+  public static Indexer buildIndexer(@InjectService("JobScheduler")
     JobScheduler scheduler, @InjectService("FileSystem")
     FileSystem fileSystem)
   {
@@ -85,7 +85,7 @@
   as:
     
 +-----------------------------------------------------------------------------------+
-  public Indexer buildIndexer(@Inject("service:JobScheduler")
+  public static Indexer buildIndexer(@Inject("service:JobScheduler")
     JobScheduler scheduler, @Inject("service:FileSystem")
     FileSystem fileSystem)
   {
@@ -207,7 +207,7 @@
   Example:
   
 +-----------------------------------------------------------------------------------+
-  public Indexer buildIndexer(String serviceId, Log serviceLog, @InjectService("JobScheduler")
+  public static Indexer buildIndexer(String serviceId, Log serviceLog, @InjectService("JobScheduler")
     JobScheduler scheduler, @InjectService("FileSystem")
     FileSystem fileSystem)
   {
@@ -248,7 +248,7 @@
   Example:
   
 +-----------------------------------------------------------------------------------+
-  public Indexer buildIndexer(JobScheduler scheduler, FileSystem fileSystem)
+  public static Indexer buildIndexer(JobScheduler scheduler, FileSystem fileSystem)
   {
     IndexerImpl indexer = new IndexerImpl(fileSystem);
       
@@ -292,7 +292,7 @@
   With Tapestry IoC, this is not even considered a special case:
   
 +-----------------------------------------------------------------------------------+
-  public Indexer buildIndexer(JobScheduler scheduler, FileSystem fileSystem)
+  public static Indexer buildIndexer(JobScheduler scheduler, FileSystem fileSystem)
   {
     IndexerImpl indexer = new IndexerImpl(fileSystem);
   
@@ -301,7 +301,7 @@
     return indexer;
   }
     
-  public buildFileSystem(Indexer indexer)
+  public static buildFileSystem(Indexer indexer)
   {
     return new FileSystemImpl(indexer);
   }  

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/shadow.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/shadow.apt?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/shadow.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/shadow.apt Sat Oct 14 16:30:48 2006
@@ -10,7 +10,7 @@
   
   Effectively, it is used to allow a property of another service to be exposed as its own service.
   
-  For example, the tapestry.request module provides a WebRequest property as a shadow of the RequestGlobals
+  For example, the tapestry module provides a WebRequest property as a shadow of the RequestGlobals
   service's request property:
   
 +----+

Added: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/struts.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/struts.apt?view=auto&rev=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/struts.apt (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/struts.apt Sat Oct 14 16:30:48 2006
@@ -0,0 +1,119 @@
+ ----
+ Tapestry for Struts Programmers
+ ----
+ 
+Introduction
+	
+  There's no getting around it ... Struts is the 800lb gorilla of Java web application frameworks.
+  It was on the scene early, it got wide coverage and wide adoptions, and vast numbers of
+  applications have been written in it.
+  
+  Struts is an <action based> framework, and exists as a kind of thin wrapper on top of the
+  base Servlet API.  This is good as far as it goes, but Tapestry has always existed
+  as an example of why that view of the world is limited.
+    
+  Tapestry, especially Tapestry 5, represents a somewhat radical approach compared to
+  Struts. You will find it to be quite compelling ... but it also requires adjusting your
+  mindset to a completely different way of looking at building web applications.
+  
+Struts: Actions and Views
+
+  Tapestry and Struts approach the division of concerns represented by the Model-View-Controller
+  design pattern from very different angles.
+  
+  Struts maps incoming URLs to <actions>; these actions are objects that extends from the 
+  Action base class.
+  
+  What does an action do?  It reads query parameters in the request either directly,
+  or via an associated ActionForm object. It probably talks to your backend to read information
+  from a database, or write information out to it. It probably stores some information
+  in the request, information that will be needed by the <view> when it renders.
+  Finally, it returns the name of the view.
+  
+  The framework picks it up from there; it uses that view name to select
+  a template, usually a JavaServer page, 
+  and gets the template to render a response to the user.
+  
+  How does Struts find all this?  Lots of XML configuration; endless details for each
+  and every "page" to define the controller class, the map view names to JSPs, to link
+  views and actions to ActionForm classes.
+
+The Problem of Statelessness
+
+  Where does Struts (and similar frameworks) get things wrong?  The first issue is with
+  the management of <state>.
+  
+  Remember "Begining Object Oriented Programming 101"?  Objects are generally defines
+  as a software construct that encapsulates behavior <and state>.
+  
+  Struts actions do not have internal state.  They can't -- they're singletons, one instance
+  shared by however many threads are operating within the servlet container.  Any internal state,
+  which is to say, any <instance variables>, would be immediately overwritten by some
+  other thread servicing a request for some other user.
+  
+  Struts approaches this problem by externalizing state: into the HttpServletRequest (for
+  state needed just by the view), or into
+  the HttpSession (for state that must persist from one request to the next). 
+  
+  Basically, what we have here is a crippled form of object oriented programming:
+  objects that have a single behavior, and have no internal state.
+  
+  As we'll see, Tapestry addresses both of these issues: in Tapestry, components
+  can have internal state, and they may have not just one, but many different behaviors.
+  
+Views: An Artifical Barrier
+
+  Action frameworks create a separation between the behavior logic, the code inside 
+  a Struts Action, and the view logic, which it typically a JavaServer Page.
+  
+  The <artificial barrier> is the lack of linkage between the template and the controller
+  (the Struts Action).  The only line of communication is the data in the HttpServletRequest
+  and HttpSession.
+  
+  There's a purpose to this design: it's all about the choice for the view. Because the
+  action may select one of several views, it's necessary to loosely couple the action
+  and the view.  The HttpServletRequest, and the named attributes stored in the request,
+  is the form of this loose coupling.
+  
+  This puts an onus on the action to stuff into the HttpServletRequest any and all data
+  that might be needed by the view as it renders a response. After all, there's no other
+  alternative, is there?
+  
+  Additionally, there's the issue of getting the action and the view, or views, to agree
+  on the name and type of every bit of state stored inside the HttpServletRequest or
+  HttpSession. Small changes to the controller, such as storing a different piece of data,
+  or using a different name, can have a ripple effect inside the view.
+  
+  This makes sense, doesn't it? After all, the result of an action (such as clicking a link
+  or submitting a form) may be some kind of success, or some kind of error. Or perhaps
+  you decide on the flavor of output based on the kind of client: HTML for the desktop or WML
+  for a phone.
+  
+Components: Its Not Just About Output
+
+  What happens when you have common <fixtures> to your application?  By fixtures,
+  we mean, bits of the view that are used in many places throughout the application.
+  This includes large chunks of functionality, such as a menu system used on every page,
+  down to tiny bits of functionality, like some kind of "widget" to format a date for output.
+  
+  JSPs provide two approaches for this kind of behavior: you can use JSP includes, to reuse
+  JSPs snippets across many larger JSPs.  Alternately, you can define and use JSP tags, which provide
+  a way to generate output using code, and provides mechanism for passing information from the 
+  HttpServletRequest into the JSP tag implementation.
+  Alas, in the real world, the vast majority of actions do have just a <single> view, named
+  "success" by convention. After all, even when an error occurs, you don't want to lose
+  all context ... if a user enters incorrect information into a form, then you want
+  to redisplay the form with the error messages. The view has to <adapt> to the state
+  determined by the request.
+  
+  But what happens when the "fixture" has behavior? For example, maybe a fixture is a login form
+  that's displayed on every page until the user logs in.  The form may have a URL that
+  points to a login Action ... but how do you return to the same view after logging in?
+  A similar case may be a component that displays tabular data and supports paging. Such
+  a component will have links for navigation and sorting. How do the actions for those links
+  return the user to the same view after changing the set of displayed items?  
+  What if there's more than one such component in a single view?
+  
+  It ends up being more and more configuration. You must define more and more JSP attributes
+  or other tricks in order to tell the appropriate action how to get the correct view
+  
\ No newline at end of file

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml Sat Oct 14 16:30:48 2006
@@ -48,9 +48,8 @@
         <menu name="Tapestry Core">
             <item name="Introduction" href="/index.html"/>
             <item name="Upgrade from Tapestry 4" href="/upgrade.html"/>
+            <item name="Tapestry for Struts Developers" href="struts.html"/>
         </menu> 
-        
-
 
         <menu name="User Guide">
             <item name="Component Classes" href="guide/component-classes.html"/>
@@ -59,6 +58,7 @@
             <item name="Component Rendering" href="guide/rendering.html"/>
             <item name="Component Templates" href="guide/templates.html"/>
             <item name="Injection" href="guide/inject.html"/>
+            <item name="Infrastructure" href="guide/infrastructure.html"/>
             <item name="Configuration" href="guide/conf.html"/>
             <item name="Request Processing" href="guide/request.html"/>
             <item name="DOM" href="guide/dom.html"/>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml Sat Oct 14 16:30:48 2006
@@ -15,7 +15,7 @@
    limitations under the License.
 -->
 
-<suite name="Tapestry" parallel="true" thread-count="10" annotations="1.5" verbose="2">
+<suite name="Tapestry" parallel="false" thread-count="10" annotations="1.5" verbose="2">
   <test name="Tapestry Core">
     <packages>
       <!-- Logically we'd like to do the General (unit) testing first, but practically,

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ContributionDefImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ContributionDefImplTest.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ContributionDefImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ContributionDefImplTest.java Sat Oct 14 16:30:48 2006
@@ -19,6 +19,7 @@
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
 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.annotations.InjectService;
@@ -28,9 +29,14 @@
 /**
  * @author Howard M. Lewis Ship
  */
-public class ContributionDefImplTest extends InternalBaseTestCase
+public class ContributionDefImplTest extends InternalBaseTestCase implements ModuleBuilderSource
 {
     private Object _toContribute;
+
+    public Object getModuleBuilder()
+    {
+        return this;
+    }
 
     @SuppressWarnings("unchecked")
     @Test

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImplTest.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImplTest.java Sat Oct 14 16:30:48 2006
@@ -18,6 +18,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.ModuleBuilderSource;
 import org.apache.tapestry.ioc.ServiceResources;
 import org.testng.annotations.Test;
 
@@ -28,6 +29,17 @@
 {
     private static final String SERVICE_ID = "ioc.Fie";
 
+    private ModuleBuilderSource newSource(final Object builder)
+    {
+        return new ModuleBuilderSource()
+        {
+            public Object getModuleBuilder()
+            {
+                return builder;
+            }
+        };
+    }
+
     /**
      * Also, test logging of decorator method invocation.
      * 
@@ -43,6 +55,7 @@
         Log log = newLog();
         fixture._expectedDelegate = newFieService();
         fixture._interceptorToReturn = newFieService();
+        ModuleBuilderSource source = newSource(fixture);
 
         trainForConstructor(resources, log);
 
@@ -55,7 +68,7 @@
         // Check that the delegate gets passed in; check that the return value of the
         // decorator method is the return value of the ServiceDecorator.
 
-        ServiceDecoratorImpl decorator = new ServiceDecoratorImpl(m, fixture, resources);
+        ServiceDecoratorImpl decorator = new ServiceDecoratorImpl(m, source, resources);
 
         Object interceptor = decorator.createInterceptor(fixture._expectedDelegate);
 
@@ -68,6 +81,7 @@
     public void decorator_returns_null_interceptor() throws Exception
     {
         ServiceDecoratorFixture fixture = new ServiceDecoratorFixture();
+        ModuleBuilderSource source = newSource(fixture);
         ServiceResources resources = newServiceResources();
         Log log = newLog();
         Object delegate = newFieService();
@@ -80,7 +94,7 @@
 
         Method m = findMethod(fixture, "decorateReturnNull");
 
-        ServiceDecoratorImpl decorator = new ServiceDecoratorImpl(m, fixture, resources);
+        ServiceDecoratorImpl decorator = new ServiceDecoratorImpl(m, source, resources);
 
         Object interceptor = decorator.createInterceptor(delegate);
 
@@ -93,6 +107,7 @@
     public void decorator_returns_incorrect_type() throws Exception
     {
         ServiceDecoratorFixture fixture = new ServiceDecoratorFixture();
+        ModuleBuilderSource source = newSource(fixture);
         ServiceResources resources = newServiceResources();
         Log log = newLog();
         fixture._expectedDelegate = newFieService();
@@ -112,7 +127,7 @@
 
         replay();
 
-        ServiceDecoratorImpl decorator = new ServiceDecoratorImpl(m, fixture, resources);
+        ServiceDecoratorImpl decorator = new ServiceDecoratorImpl(m, source, resources);
 
         Object interceptor = decorator.createInterceptor(fixture._expectedDelegate);
 
@@ -125,6 +140,7 @@
     public void decorator_method_throws_exception() throws Exception
     {
         ServiceDecoratorFixture fixture = new ServiceDecoratorFixture();
+        ModuleBuilderSource source = newSource(fixture);
         ServiceResources resources = newServiceResources();
         Log log = newLog();
         Object delegate = newFieService();
@@ -138,7 +154,7 @@
 
         Method m = findMethod(fixture, "decoratorThrowsException");
 
-        ServiceDecoratorImpl decorator = new ServiceDecoratorImpl(m, fixture, resources);
+        ServiceDecoratorImpl decorator = new ServiceDecoratorImpl(m, source, resources);
 
         try
         {

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImplTest.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImplTest.java Sat Oct 14 16:30:48 2006
@@ -293,7 +293,7 @@
 
         assertSame(cpa2, cpa1);
 
-        _access.clear();
+        _access.clearCache();
 
         ClassPropertyAdapter cpa3 = _access.getAdapter(Bean.class);
 

Copied: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/TypeCoercerImplTest.java (from r463734, tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TypeCoercerImplTest.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/TypeCoercerImplTest.java?view=diff&rev=464060&p1=tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TypeCoercerImplTest.java&r1=463734&p2=tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/TypeCoercerImplTest.java&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TypeCoercerImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/TypeCoercerImplTest.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 java.math.BigDecimal;
 import java.math.BigInteger;
@@ -22,7 +22,7 @@
 
 import org.apache.tapestry.internal.annotations.SuppressNullCheck;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
-import org.apache.tapestry.services.TypeCoercer;
+import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
@@ -39,7 +39,7 @@
     @BeforeClass
     public void setup_coercer()
     {
-        _coercer = getService(TypeCoercer.class);
+        _coercer = getObject("infrastructure:typeCoercer", TypeCoercer.class);
     }
 
     @AfterClass
@@ -98,10 +98,8 @@
         }
         catch (IllegalArgumentException ex)
         {
-            assertTrue(ex
-                    .getMessage()
-                    .contains(
-                            "Could not find a coercion from type java.lang.String to type java.util.Map"));
+            assertTrue(ex.getMessage().contains(
+                    "Could not find a coercion from type java.lang.String to type java.util.Map"));
         }
     }
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentEventImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentEventImplTest.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentEventImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentEventImplTest.java Sat Oct 14 16:30:48 2006
@@ -2,8 +2,8 @@
 
 import org.apache.tapestry.ComponentEventHandler;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.runtime.ComponentEvent;
-import org.apache.tapestry.services.TypeCoercer;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
@@ -18,7 +18,7 @@
     @BeforeClass
     public void setup_coercer()
     {
-        _coercer = getService("tapestry.TypeCoercer", TypeCoercer.class);
+        _coercer = getObject("infrastructure:typeCoercer", TypeCoercer.class);
     }
 
     @AfterClass

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImplTest.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImplTest.java Sat Oct 14 16:30:48 2006
@@ -37,6 +37,7 @@
 import org.apache.tapestry.ioc.RegistryBuilder;
 import org.apache.tapestry.ioc.services.PropertyAccess;
 import org.apache.tapestry.runtime.ComponentLifecycle;
+import org.apache.tapestry.services.Infrastructure;
 import org.apache.tapestry.services.TapestryModule;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -261,6 +262,8 @@
         builder.add(TapestryModule.class);
 
         _registry = builder.build();
+
+        _registry.getService("tapestry.Infrastructure", Infrastructure.class).setMode("servlet");
 
         _source = _registry.getService(ComponentInstantiatorSource.class);
         _access = _registry.getService(PropertyAccess.class);

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java Sat Oct 14 16:30:48 2006
@@ -20,10 +20,10 @@
 import org.apache.tapestry.internal.TapestryException;
 import org.apache.tapestry.internal.services.Instantiator;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.model.ComponentModel;
 import org.apache.tapestry.model.ParameterModel;
 import org.apache.tapestry.runtime.ComponentLifecycle;
-import org.apache.tapestry.services.TypeCoercer;
 import org.easymock.EasyMock;
 import org.testng.annotations.Test;
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ExpansionPageElementImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ExpansionPageElementImplTest.java?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ExpansionPageElementImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ExpansionPageElementImplTest.java Sat Oct 14 16:30:48 2006
@@ -17,8 +17,8 @@
 import org.apache.tapestry.Binding;
 import org.apache.tapestry.MarkupWriter;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.runtime.RenderQueue;
-import org.apache.tapestry.services.TypeCoercer;
 import org.testng.annotations.Test;
 
 /**

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?view=diff&rev=464060&r1=464059&r2=464060
==============================================================================
--- 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 Sat Oct 14 16:30:48 2006
@@ -38,6 +38,54 @@
     }
 
     @Test
+    public void static_builder_method_does_not_instantiate_builder()
+    {
+        StaticModule.setInstantiated(false);
+        StaticModule.setFredRan(false);
+
+        Registry r = buildRegistry(StaticModule.class);
+
+        Runnable fred = r.getService("static.Fred", Runnable.class);
+
+        fred.run();
+
+        assertFalse(StaticModule.isInstantiated());
+        assertTrue(StaticModule.getFredRan());
+    }
+
+    @Test
+    public void static_decorator_method_does_not_instantiate_builder()
+    {
+        StaticModule.setInstantiated(false);
+        StaticModule.setDecoratorRan(false);
+
+        Registry r = buildRegistry(StaticModule.class);
+
+        Runnable fred = r.getService("static.Barney", Runnable.class);
+
+        fred.run();
+
+        assertFalse(StaticModule.isInstantiated());
+        assertTrue(StaticModule.getDecoratorRan());
+    }
+
+    @Test
+    public void static_contributor_method_does_not_instantiate_builder()
+    {
+        StaticModule.setInstantiated(false);
+
+        Registry r = buildRegistry(StaticModule.class);
+
+        NameListHolder holder = r.getService("static.Names", NameListHolder.class);
+
+        List<String> names = holder.getNames();
+
+        assertEquals(names, Arrays.asList("Fred"));
+
+        assertFalse(StaticModule.isInstantiated());
+    }
+
+    @Test
     public void shutdown_deactivates_proxies()
     {
         Registry r = buildRegistry();

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StaticModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StaticModule.java?view=auto&rev=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StaticModule.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StaticModule.java Sat Oct 14 16:30:48 2006
@@ -0,0 +1,111 @@
+package org.apache.tapestry.ioc;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.tapestry.ioc.annotations.Id;
+import org.apache.tapestry.util.CollectionFactory;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+@Id("static")
+public class StaticModule
+{
+    private static boolean _instantiated;
+
+    private static boolean _fredRan;
+
+    private static boolean _decoratorRan;
+
+    public StaticModule()
+    {
+        setInstantiated(true);
+    }
+
+    public static Runnable buildFred()
+    {
+        return new Runnable()
+        {
+            public void run()
+            {
+                setFredRan(true);
+            }
+        };
+    }
+
+    public static Runnable buildBarney()
+    {
+        return new Runnable()
+        {
+            public void run()
+            {
+            }
+        };
+    }
+
+    public static Runnable decorateBarney(final Object delegate)
+    {
+        return new Runnable()
+        {
+            public void run()
+            {
+                setDecoratorRan(true);
+
+                ((Runnable) delegate).run();
+            }
+        };
+    }
+
+    public static synchronized void setFredRan(boolean fredRan)
+    {
+        _fredRan = fredRan;
+    }
+
+    public static synchronized boolean getFredRan()
+    {
+        return _fredRan;
+    }
+
+    public static synchronized void setInstantiated(boolean instantiated)
+    {
+        _instantiated = instantiated;
+    }
+
+    public static synchronized boolean isInstantiated()
+    {
+        return _instantiated;
+    }
+
+    public static synchronized void setDecoratorRan(boolean decoratorRan)
+    {
+        _decoratorRan = decoratorRan;
+    }
+
+    public static synchronized boolean getDecoratorRan()
+    {
+        return _decoratorRan;
+    }
+
+    public static NameListHolder buildNames(final Collection<String> configuration)
+    {
+        return new NameListHolder()
+        {
+            public List<String> getNames()
+            {
+                List result = CollectionFactory.newList(configuration);
+
+                Collections.sort(result);
+
+                return result;
+            }
+        };
+    }
+
+    public static void contributeNames(Configuration<String> configuration)
+    {
+        configuration.add("Fred");
+    }
+
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/StrategyRegistryTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/StrategyRegistryTest.java?view=auto&rev=464060
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/StrategyRegistryTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/StrategyRegistryTest.java Sat Oct 14 16:30:48 2006
@@ -0,0 +1,145 @@
+package org.apache.tapestry.util;
+
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.util.StrategyRegistry;
+import org.testng.annotations.Test;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class StrategyRegistryTest extends InternalBaseTestCase
+{
+    @Test
+    public void adapter_not_found()
+    {
+        Runnable r1 = newRunnable();
+        Runnable r2 = newRunnable();
+
+        replay();
+
+        Map<Class, Runnable> registrations = newMap();
+
+        registrations.put(List.class, r1);
+        registrations.put(Map.class, r2);
+
+        StrategyRegistry<Runnable> r = StrategyRegistry.newInstance(Runnable.class, registrations);
+
+        try
+        {
+            r.get(Set.class);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "No adapter from type java.util.Set to type java.lang.Runnable is available (registered types are java.util.List, java.util.Map).");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void adapter_found()
+    {
+        Runnable r1 = newRunnable();
+        Runnable r2 = newRunnable();
+
+        replay();
+
+        Map<Class, Runnable> registrations = newMap();
+
+        registrations.put(List.class, r1);
+        registrations.put(Map.class, r2);
+
+        StrategyRegistry<Runnable> r = StrategyRegistry.newInstance(Runnable.class, registrations);
+
+        Runnable actual = r.get(ArrayList.class);
+
+        assertSame(actual, r1);
+
+        // The cache is almost impossible to "test", but we can at least collect some
+        // code coverage over those lines.
+
+        Runnable actual2 = r.get(ArrayList.class);
+        assertSame(actual2, r1);
+
+        r.clearCache();
+
+        Runnable actual3 = r.get(ArrayList.class);
+        assertSame(actual3, r1);
+
+        verify();
+    }
+
+    @Test
+    public void registration_map_is_copied_by_constructor()
+    {
+        Runnable r1 = newRunnable();
+        Runnable r2 = newRunnable();
+
+        replay();
+
+        Map<Class, Runnable> registrations = newMap();
+
+        registrations.put(List.class, r1);
+        registrations.put(Map.class, r2);
+
+        StrategyRegistry<Runnable> r = StrategyRegistry.newInstance(Runnable.class, registrations);
+
+        registrations.clear();
+
+        Runnable actual = r.get(ArrayList.class);
+
+        assertSame(actual, r1);
+    }
+
+    @Test
+    public void adapter_found_by_instance()
+    {
+        Runnable r1 = newRunnable();
+        Runnable r2 = newRunnable();
+
+        replay();
+
+        Map<Class, Runnable> registrations = newMap();
+
+        registrations.put(List.class, r1);
+        registrations.put(Map.class, r2);
+
+        StrategyRegistry<Runnable> r = StrategyRegistry.newInstance(Runnable.class, registrations);
+
+        assertSame(r.getByInstance(registrations), r2);
+
+        verify();
+    }
+
+    @Test
+    public void null_instance_matches_class_void()
+    {
+        Runnable r1 = newRunnable();
+        Runnable r2 = newRunnable();
+        Runnable r3 = newRunnable();
+
+        replay();
+
+        Map<Class, Runnable> registrations = newMap();
+
+        registrations.put(List.class, r1);
+        registrations.put(Map.class, r2);
+        registrations.put(void.class, r3);
+
+        StrategyRegistry<Runnable> r = StrategyRegistry.newInstance(Runnable.class, registrations);
+
+        assertSame(r.getByInstance(null), r3);
+
+        verify();
+    }
+}