Author: hlship
Date: Tue Nov 11 20:39:46 2008
New Revision: 713263

URL: http://svn.apache.org/viewvc?rev=713263&view=rev
Log:
TAP5-292: Field injection does not support injecting configurations or other 
service resources, only dependencies

Added:
    
tapestry/tapestry5/trunk/tapestry-annotations/src/main/java/org/apache/tapestry5/ioc/annotations/InjectResource.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/DelegatingInjectionResources.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InjectionResources.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/MapInjectionResources.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FailedFieldInjectionStringTransformer.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceInjectionModule.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceService.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceServiceImpl.java
Modified:
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractServiceCreator.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ConstructorServiceCreator.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodInvoker.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDecoratorImpl.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/UtilMessages.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/util/UtilStrings.properties
    tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/injection.apt
    
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/InternalUtilsTest.java

Added: 
tapestry/tapestry5/trunk/tapestry-annotations/src/main/java/org/apache/tapestry5/ioc/annotations/InjectResource.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-annotations/src/main/java/org/apache/tapestry5/ioc/annotations/InjectResource.java?rev=713263&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-annotations/src/main/java/org/apache/tapestry5/ioc/annotations/InjectResource.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-annotations/src/main/java/org/apache/tapestry5/ioc/annotations/InjectResource.java
 Tue Nov 11 20:39:46 2008
@@ -0,0 +1,29 @@
+//  Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc.annotations;
+
+import java.lang.annotation.*;
+
+
+/**
+ * Annotation used with field injection when the desired injection value is a 
resource (such as a service id, service
+ * configuration, or logger) and not an object obtained from the [EMAIL 
PROTECTED] org.apache.tapestry5.ioc.services.MasterObjectProvider}.
+ */
[EMAIL PROTECTED](ElementType.FIELD)
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED]
+public @interface InjectResource
+{
+}

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractServiceCreator.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractServiceCreator.java?rev=713263&r1=713262&r2=713263&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractServiceCreator.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractServiceCreator.java
 Tue Nov 11 20:39:46 2008
@@ -20,6 +20,9 @@
 import org.apache.tapestry5.ioc.ServiceResources;
 import static org.apache.tapestry5.ioc.internal.ConfigurationType.*;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.internal.util.DelegatingInjectionResources;
+import org.apache.tapestry5.ioc.internal.util.InjectionResources;
+import org.apache.tapestry5.ioc.internal.util.MapInjectionResources;
 import org.slf4j.Logger;
 
 import java.lang.reflect.ParameterizedType;
@@ -36,7 +39,7 @@
 {
     protected final String serviceId;
 
-    private final Map<Class, Object> parameterDefaults = 
CollectionFactory.newMap();
+    private final Map<Class, Object> injectionResources = 
CollectionFactory.newMap();
 
     protected final ServiceBuilderResources resources;
 
@@ -60,90 +63,77 @@
         this.creatorDescription = creatorDescription;
         logger = resources.getLogger();
 
-        parameterDefaults.put(String.class, serviceId);
-        parameterDefaults.put(ObjectLocator.class, resources);
-        parameterDefaults.put(ServiceResources.class, resources);
-        parameterDefaults.put(Logger.class, logger);
-        parameterDefaults.put(Class.class, resources.getServiceInterface());
+        injectionResources.put(String.class, serviceId);
+        injectionResources.put(ObjectLocator.class, resources);
+        injectionResources.put(ServiceResources.class, resources);
+        injectionResources.put(Logger.class, logger);
+        injectionResources.put(Class.class, resources.getServiceInterface());
     }
 
     /**
-     * Returns a map (based on _parameterDefaults) that includes (possibly) an 
additional mapping containing the
+     * Returns a map (based on parameterDefaults) that includes (possibly) an 
additional mapping containing the
      * collected configuration data. This involves scanning the parameters and 
generic types.
      */
-    protected final Map<Class, Object> 
getParameterDefaultsWithConfiguration(Class[] parameterTypes,
-                                                                             
Type[] genericParameterTypes)
+    protected final InjectionResources createInjectionResources()
     {
-        Map<Class, Object> result = 
CollectionFactory.newMap(parameterDefaults);
-        ConfigurationType type = null;
+        InjectionResources core = new 
MapInjectionResources(injectionResources);
 
-        for (int i = 0; i < parameterTypes.length; i++)
+        InjectionResources configurations = new InjectionResources()
         {
-            Class parameterType = parameterTypes[i];
+            private boolean seenOne;
 
-            ConfigurationType thisType = 
PARAMETER_TYPE_TO_CONFIGURATION_TYPE.get(parameterType);
-
-            if (thisType == null) continue;
-
-            if (type != null)
+            public <T> T findResource(Class<T> resourceType, Type genericType)
             {
-                
logger.warn(IOCMessages.tooManyConfigurationParameters(creatorDescription));
-                break;
-            }
+                ConfigurationType thisType = 
PARAMETER_TYPE_TO_CONFIGURATION_TYPE.get(resourceType);
 
-            // Remember that we've seen a configuration parameter, in case 
there
-            // is another.
+                if (thisType == null) return null;
 
-            type = thisType;
-
-            Type genericType = genericParameterTypes[i];
-
-            switch (type)
-            {
+                if (seenOne)
+                    throw new 
RuntimeException(IOCMessages.tooManyConfigurationParameters(creatorDescription));
 
-                case UNORDERED:
 
-                    addUnorderedConfigurationParameter(result, genericType);
+                seenOne = true;
 
-                    break;
+                switch (thisType)
+                {
+                    case UNORDERED:
 
-                case ORDERED:
+                        return 
resourceType.cast(getUnorderedConfiguration(genericType));
 
-                    addOrderedConfigurationParameter(result, genericType);
+                    case ORDERED:
 
-                    break;
+                        return 
resourceType.cast(getOrderedConfiguration(genericType));
 
-                case MAPPED:
+                    case MAPPED:
 
-                    addMappedConfigurationParameter(result, genericType);
+                        return 
resourceType.cast(getMappedConfiguration(genericType));
+                }
 
-                    break;
+                return null;
             }
-        }
+        };
 
-        return result;
+
+        return new DelegatingInjectionResources(core, configurations);
     }
 
-    @SuppressWarnings("unchecked")
-    private void addOrderedConfigurationParameter(Map<Class, Object> 
parameterDefaults, Type genericType)
+    private List getOrderedConfiguration(Type genericType)
     {
         Class valueType = findParameterizedTypeFromGenericType(genericType);
-        List configuration = resources.getOrderedConfiguration(valueType);
-
-        parameterDefaults.put(List.class, configuration);
+        return resources.getOrderedConfiguration(valueType);
     }
 
+
     @SuppressWarnings("unchecked")
-    private void addUnorderedConfigurationParameter(Map<Class, Object> 
parameterDefaults, Type genericType)
+    private Collection getUnorderedConfiguration(Type genericType)
     {
         Class valueType = findParameterizedTypeFromGenericType(genericType);
-        Collection configuration = 
resources.getUnorderedConfiguration(valueType);
 
-        parameterDefaults.put(Collection.class, configuration);
+        return resources.getUnorderedConfiguration(valueType);
     }
 
     @SuppressWarnings("unchecked")
-    private void addMappedConfigurationParameter(Map<Class, Object> 
parameterDefaults, Type genericType)
+    private Map getMappedConfiguration(Type genericType)
     {
         Class keyType = findParameterizedTypeFromGenericType(genericType, 0);
         Class valueType = findParameterizedTypeFromGenericType(genericType, 1);
@@ -151,9 +141,7 @@
         if (keyType == null || valueType == null)
             throw new 
IllegalArgumentException(IOCMessages.genericTypeNotSupported(genericType));
 
-        Map configuration = resources.getMappedConfiguration(keyType, 
valueType);
-
-        parameterDefaults.put(Map.class, configuration);
+        return resources.getMappedConfiguration(keyType, valueType);
     }
 
     /**

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ConstructorServiceCreator.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ConstructorServiceCreator.java?rev=713263&r1=713262&r2=713263&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ConstructorServiceCreator.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ConstructorServiceCreator.java
 Tue Nov 11 20:39:46 2008
@@ -15,11 +15,11 @@
 package org.apache.tapestry5.ioc.internal;
 
 import org.apache.tapestry5.ioc.ServiceBuilderResources;
+import org.apache.tapestry5.ioc.internal.util.InjectionResources;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.util.Map;
 
 /**
  * A service creator based on an implementation class' constructor, rather 
than a service builder method.
@@ -50,15 +50,17 @@
         {
             InternalUtils.validateConstructorForAutobuild(constructor);
 
+            InjectionResources injectionResources = createInjectionResources();
+
             Object[] parameters = 
InternalUtils.calculateParametersForConstructor(constructor, resources,
-                                                                               
   getParameterDefaultsWithConfigurations(),
+                                                                               
   injectionResources,
                                                                                
   resources.getTracker());
 
             if (logger.isDebugEnabled()) 
logger.debug(IOCMessages.invokingConstructor(creatorDescription));
 
             Object result = constructor.newInstance(parameters);
 
-            InternalUtils.injectIntoFields(result, resources, 
resources.getTracker());
+            InternalUtils.injectIntoFields(result, resources, 
injectionResources, resources.getTracker());
 
             return result;
         }
@@ -73,14 +75,4 @@
 
         throw new 
RuntimeException(IOCMessages.constructorError(creatorDescription, serviceId, 
failure), failure);
     }
-
-    /**
-     * Returns a map that includes (possibly) an additional mapping containing 
the collected configuration data. This
-     * involves scanning the constructor's parameters.
-     */
-    private Map<Class, Object> getParameterDefaultsWithConfigurations()
-    {
-        return 
getParameterDefaultsWithConfiguration(constructor.getParameterTypes(), 
constructor
-                .getGenericParameterTypes());
-    }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java?rev=713263&r1=713262&r2=713263&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java
 Tue Nov 11 20:39:46 2008
@@ -17,7 +17,9 @@
 import org.apache.tapestry5.ioc.*;
 import org.apache.tapestry5.ioc.def.ContributionDef;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.internal.util.InjectionResources;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.internal.util.MapInjectionResources;
 import org.apache.tapestry5.ioc.services.ClassFactory;
 
 import java.lang.reflect.InvocationTargetException;
@@ -71,14 +73,16 @@
     private <T> void invokeMethod(ModuleBuilderSource source, ServiceResources 
resources,
                                   Class<T> parameterType, T parameterValue)
     {
-        Map<Class, Object> parameterDefaults = CollectionFactory.newMap();
+        Map<Class, Object> resourceMap = CollectionFactory.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.
 
-        parameterDefaults.put(parameterType, parameterValue);
-        parameterDefaults.put(ObjectLocator.class, resources);
+        resourceMap.put(parameterType, parameterValue);
+        resourceMap.put(ObjectLocator.class, resources);
+
+        InjectionResources injectionResources = new 
MapInjectionResources(resourceMap);
 
         Throwable fail = null;
 
@@ -90,7 +94,7 @@
             Object[] parameters = InternalUtils.calculateParametersForMethod(
                     contributorMethod,
                     resources,
-                    parameterDefaults, resources.getTracker());
+                    injectionResources, resources.getTracker());
 
             contributorMethod.invoke(moduleBuilder, parameters);
         }

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java?rev=713263&r1=713262&r2=713263&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
 Tue Nov 11 20:39:46 2008
@@ -364,10 +364,12 @@
             throw new 
RuntimeException(IOCMessages.recursiveModuleConstructor(builderClass, 
constructor));
 
         ObjectLocator locator = new ObjectLocatorImpl(registry, this);
-        Map<Class, Object> parameterDefaults = CollectionFactory.newMap();
+        Map<Class, Object> resourcesMap = CollectionFactory.newMap();
 
-        parameterDefaults.put(Logger.class, logger);
-        parameterDefaults.put(ObjectLocator.class, locator);
+        resourcesMap.put(Logger.class, logger);
+        resourcesMap.put(ObjectLocator.class, locator);
+
+        InjectionResources resources = new MapInjectionResources(resourcesMap);
 
         Throwable fail = null;
 
@@ -375,14 +377,15 @@
         {
             insideConstructor = true;
 
-            Object[] parameterValues = 
InternalUtils.calculateParameters(locator, parameterDefaults,
+            Object[] parameterValues = 
InternalUtils.calculateParameters(locator, resources,
                                                                          
constructor.getParameterTypes(),
+                                                                         
constructor.getGenericParameterTypes(),
                                                                          
constructor.getParameterAnnotations(),
                                                                          
registry);
 
             Object result = constructor.newInstance(parameterValues);
 
-            InternalUtils.injectIntoFields(result, locator, registry);
+            InternalUtils.injectIntoFields(result, locator, resources, 
registry);
 
             return result;
         }

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java?rev=713263&r1=713262&r2=713263&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
 Tue Nov 11 20:39:46 2008
@@ -776,6 +776,7 @@
                 // service, we don't have defaults for Log, service id, etc.
 
                 Map<Class, Object> empty = Collections.emptyMap();
+                InjectionResources resources = new 
MapInjectionResources(empty);
 
                 try
                 {
@@ -783,12 +784,12 @@
 
                     Object[] parameters = 
InternalUtils.calculateParametersForConstructor(constructor,
                                                                                
           locator,
-                                                                               
           empty,
+                                                                               
           resources,
                                                                                
           tracker);
 
                     Object result = constructor.newInstance(parameters);
 
-                    InternalUtils.injectIntoFields(result, locator, tracker);
+                    InternalUtils.injectIntoFields(result, locator, resources, 
tracker);
 
                     return clazz.cast(result);
                 }

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodInvoker.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodInvoker.java?rev=713263&r1=713262&r2=713263&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodInvoker.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodInvoker.java
 Tue Nov 11 20:39:46 2008
@@ -19,7 +19,6 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.util.Map;
 
 /**
  * Basic implementation of [EMAIL PROTECTED] 
org.apache.tapestry5.ioc.ObjectCreator} that handles invoking a method on the 
module
@@ -38,17 +37,6 @@
     }
 
     /**
-     * Returns a map that includes (possibly) an additional mapping containing 
the collected configuration data. This
-     * involves scanning the builder method's parameters.
-     */
-    private Map<Class, Object> getParameterDefaultsWithConfigurations()
-    {
-        return getParameterDefaultsWithConfiguration(
-                builderMethod.getParameterTypes(),
-                builderMethod.getGenericParameterTypes());
-    }
-
-    /**
      * Invoked from the proxy to create the actual service implementation.
      */
     public Object createObject()
@@ -67,7 +55,7 @@
             Object[] parameters = InternalUtils.calculateParametersForMethod(
                     builderMethod,
                     resources,
-                    getParameterDefaultsWithConfigurations(), 
resources.getTracker());
+                    createInjectionResources(), resources.getTracker());
 
             if (logger.isDebugEnabled())
                 logger.debug(IOCMessages.invokingMethod(creatorDescription));

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDecoratorImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDecoratorImpl.java?rev=713263&r1=713262&r2=713263&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDecoratorImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDecoratorImpl.java
 Tue Nov 11 20:39:46 2008
@@ -19,7 +19,9 @@
 import org.apache.tapestry5.ioc.ServiceDecorator;
 import org.apache.tapestry5.ioc.ServiceResources;
 import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry5.ioc.internal.util.InjectionResources;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.internal.util.MapInjectionResources;
 import org.apache.tapestry5.ioc.services.ClassFactory;
 import org.slf4j.Logger;
 
@@ -85,6 +87,8 @@
         parameterDefaults.put(Object.class, delegate);
         parameterDefaults.put(serviceInterface, delegate);
 
+        InjectionResources injectionResources = new 
MapInjectionResources(parameterDefaults);
+
         if (logger.isDebugEnabled()) 
logger.debug(IOCMessages.invokingMethod(methodId()));
 
         Object result = null;
@@ -97,8 +101,8 @@
         {
             Object[] parameters = InternalUtils.calculateParametersForMethod(
                     decoratorMethod,
-                    resources,
-                    parameterDefaults, resources.getTracker());
+                    this.resources,
+                    injectionResources, resources.getTracker());
 
             result = decoratorMethod.invoke(moduleBuilder, parameters);
         }

Added: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/DelegatingInjectionResources.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/DelegatingInjectionResources.java?rev=713263&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/DelegatingInjectionResources.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/DelegatingInjectionResources.java
 Tue Nov 11 20:39:46 2008
@@ -0,0 +1,40 @@
+//  Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc.internal.util;
+
+import java.lang.reflect.Type;
+
+/**
+ * Chain of command for InjectionDefaultProvider.
+ */
+public class DelegatingInjectionResources implements InjectionResources
+{
+    private final InjectionResources first;
+    private final InjectionResources next;
+
+    public DelegatingInjectionResources(InjectionResources first,
+                                        InjectionResources next)
+    {
+        this.first = first;
+        this.next = next;
+    }
+
+    public <T> T findResource(Class<T> type, Type genericType)
+    {
+        T result = first.findResource(type, null);
+
+        return result != null ? result : next.findResource(type, genericType);
+    }
+}

Added: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InjectionResources.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InjectionResources.java?rev=713263&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InjectionResources.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InjectionResources.java
 Tue Nov 11 20:39:46 2008
@@ -0,0 +1,34 @@
+//  Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc.internal.util;
+
+import java.lang.reflect.Type;
+
+/**
+ * Provides for the injection of specific types of values as 
<em>resources</em> as opposed to services or objects
+ * obtained from [EMAIL PROTECTED] 
org.apache.tapestry5.ioc.services.MasterObjectProvider}. This includes values 
such as a
+ * service's id, logger or service interface class.
+ */
+public interface InjectionResources
+{
+    /**
+     * Given the field type, provide the matching resource value, or null.
+     *
+     * @param type        type of field or parameter
+     * @param genericType generic type information associated with field or 
parameter
+     * @return the  corresponding value, or null
+     */
+    <T> T findResource(Class<T> type, Type genericType);
+}

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java?rev=713263&r1=713262&r2=713263&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java
 Tue Nov 11 20:39:46 2008
@@ -16,6 +16,7 @@
 
 import org.apache.tapestry5.ioc.*;
 import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.ioc.annotations.InjectResource;
 import org.apache.tapestry5.ioc.annotations.InjectService;
 import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newList;
 import static org.apache.tapestry5.ioc.internal.util.Defense.notBlank;
@@ -27,10 +28,7 @@
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
+import java.lang.reflect.*;
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -39,6 +37,7 @@
  * Utilities used within various internal implemenations of Tapestry IOC and 
the rest of the tapestry-core framework.
  */
 
[EMAIL PROTECTED]({"JavaDoc", "unchecked"})
 public class InternalUtils
 {
     /**
@@ -164,9 +163,8 @@
         return null;
     }
 
-    @SuppressWarnings("unchecked")
-    private static Object calculateInjection(Class injectionType, final 
Annotation[] annotations,
-                                             ObjectLocator locator, Map<Class, 
Object> defaults)
+    private static Object calculateInjection(Class injectionType, Type 
genericType, final Annotation[] annotations,
+                                             ObjectLocator locator, 
InjectionResources resources)
     {
         AnnotationProvider provider = new AnnotationProvider()
         {
@@ -193,7 +191,7 @@
 
         if (provider.getAnnotation(Inject.class) == null)
         {
-            Object result = defaults.get(injectionType);
+            Object result = resources.findResource(injectionType, genericType);
 
             if (result != null) return result;
         }
@@ -205,26 +203,30 @@
     }
 
     public static Object[] calculateParametersForMethod(Method method, 
ObjectLocator locator,
-                                                        Map<Class, Object> 
parameterDefaults, OperationTracker tracker)
+                                                        InjectionResources 
resources,
+                                                        OperationTracker 
tracker)
     {
-        Class[] parameterTypes = method.getParameterTypes();
-        Annotation[][] annotations = method.getParameterAnnotations();
 
-        return calculateParameters(locator, parameterDefaults, parameterTypes, 
annotations, tracker);
+        return calculateParameters(locator, resources, 
method.getParameterTypes(), method.getGenericParameterTypes(),
+                                   method.getParameterAnnotations(),
+                                   tracker);
     }
 
     public static Object[] calculateParametersForConstructor(Constructor 
constructor, ObjectLocator locator,
-                                                             Map<Class, 
Object> parameterDefaults,
+                                                             
InjectionResources resources,
                                                              OperationTracker 
tracker)
     {
-        Class[] parameterTypes = constructor.getParameterTypes();
-        Annotation[][] annotations = constructor.getParameterAnnotations();
 
-        return calculateParameters(locator, parameterDefaults, parameterTypes, 
annotations, tracker);
+        return calculateParameters(locator, resources, 
constructor.getParameterTypes(),
+                                   constructor.getGenericParameterTypes(),
+                                   constructor.getParameterAnnotations(), 
tracker);
     }
 
-    public static Object[] calculateParameters(final ObjectLocator locator, 
final Map<Class, Object> defaults,
-                                               Class[] parameterTypes, 
Annotation[][] parameterAnnotations,
+    public static Object[] calculateParameters(final ObjectLocator locator,
+                                               final InjectionResources 
resources,
+                                               Class[] parameterTypes,
+                                               final Type[] genericTypes,
+                                               Annotation[][] 
parameterAnnotations,
                                                OperationTracker tracker)
     {
         int parameterCount = parameterTypes.length;
@@ -234,6 +236,7 @@
         for (int i = 0; i < parameterCount; i++)
         {
             final Class type = parameterTypes[i];
+            final Type genericType = genericTypes[i];
             final Annotation[] annotations = parameterAnnotations[i];
 
             String description = String.format("Determining injection value 
for parameter #%d (%s)", i + 1,
@@ -243,7 +246,7 @@
             {
                 public Object invoke()
                 {
-                    return calculateInjection(type, annotations, locator, 
defaults);
+                    return calculateInjection(type, genericType, annotations, 
locator, resources);
                 }
             };
 
@@ -257,17 +260,19 @@
      * Injects into the fields (of all visibilities)  when the [EMAIL 
PROTECTED] org.apache.tapestry5.ioc.annotations.Inject} or
      * [EMAIL PROTECTED] org.apache.tapestry5.ioc.annotations.InjectService} 
annotations are present.
      *
-     * @param object  to be initialized
-     * @param locator used to resolve external dependencies
-     * @param tracker track operations
-     */
-    public static void injectIntoFields(final Object object, final 
ObjectLocator locator, OperationTracker tracker)
+     * @param object    to be initialized
+     * @param locator   used to resolve external dependencies
+     * @param resources provides injection resources for fields
+     * @param tracker   track operations
+     */
+    public static void injectIntoFields(final Object object, final 
ObjectLocator locator,
+                                        final InjectionResources resources,
+                                        OperationTracker tracker)
     {
         Class clazz = object.getClass();
 
         while (clazz != Object.class)
         {
-
             Field[] fields = clazz.getDeclaredFields();
 
             for (final Field f : fields)
@@ -293,22 +298,35 @@
                 {
                     public void run()
                     {
-                        InjectService is = 
ap.getAnnotation(InjectService.class);
+                        final Class<?> fieldType = f.getType();
 
+                        InjectService is = 
ap.getAnnotation(InjectService.class);
                         if (is != null)
                         {
-                            inject(object, f, locator.getService(is.value(), 
f.getType()));
+                            inject(object, f, locator.getService(is.value(), 
fieldType));
                             return;
                         }
 
                         if (ap.getAnnotation(Inject.class) != null)
                         {
-                            inject(object, f, locator.getObject(f.getType(), 
ap));
+                            inject(object, f, locator.getObject(fieldType, 
ap));
+                            return;
+                        }
+
+
+                        if (ap.getAnnotation(InjectResource.class) != null)
+                        {
+                            Object value = resources.findResource(fieldType, 
f.getGenericType());
+
+                            if (value == null)
+                                throw new 
RuntimeException(UtilMessages.injectResourceFailure(f.getName(), fieldType));
+
+                            inject(object, f, value);
+
                             return;
                         }
 
-                        // Ignore fields that do not have the necessary 
annotation.  Should we ignore static
-                        // fields?
+                        // Ignore fields that do not have the necessary 
annotation.
 
                     }
                 });

Added: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/MapInjectionResources.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/MapInjectionResources.java?rev=713263&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/MapInjectionResources.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/MapInjectionResources.java
 Tue Nov 11 20:39:46 2008
@@ -0,0 +1,34 @@
+//  Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc.internal.util;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+
+/**
+ * InjectionDefaultProvider that operates using a Map from type to value.
+ */
+public class MapInjectionResources implements InjectionResources
+{
+    private final Map<Class, Object> map;
+
+    public MapInjectionResources(Map<Class, Object> map) {this.map = map;}
+
+    @SuppressWarnings({"unchecked"})
+    public <T> T findResource(Class<T> type, Type genericType)
+    {
+        return (T) map.get(type);
+    }
+}

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/UtilMessages.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/UtilMessages.java?rev=713263&r1=713262&r2=713263&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/UtilMessages.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/UtilMessages.java
 Tue Nov 11 20:39:46 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2008 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
 package org.apache.tapestry5.ioc.internal.util;
 
 import org.apache.tapestry5.ioc.Messages;
+import org.apache.tapestry5.ioc.services.ClassFabUtils;
 
 class UtilMessages
 {
@@ -63,4 +64,9 @@
     {
         return MESSAGES.format("bad-marker-annotation", 
annotationClass.getName());
     }
+
+    static String injectResourceFailure(String fieldName, Class fieldType)
+    {
+        return MESSAGES.format("inject-resource-failure", fieldName, 
ClassFabUtils.toJavaClassName(fieldType));
+    }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/util/UtilStrings.properties
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/util/UtilStrings.properties?rev=713263&r1=713262&r2=713263&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/util/UtilStrings.properties
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/util/UtilStrings.properties
 Tue Nov 11 20:39:46 2008
@@ -1,17 +1,17 @@
-# Copyright 2006 The Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
+# Copyright 2006, 2008 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 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.
@@ -20,3 +20,4 @@
 parameter-was-blank=Parameter %s was null or contained only whitespace.
 bad-cast=Parameter %s (%s) is not assignable to type %s.
 bad-marker-annotation=Marker annotation class %s is not valid because it is 
not visible at runtime. Add a @RetentionPolicy(RUNTIME) to the class.
+inject-resource-failure=Unable to determine resource value to inject into 
field '%s' (of type %s).

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/injection.apt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/injection.apt?rev=713263&r1=713262&r2=713263&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/injection.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/injection.apt Tue Nov 11 
20:39:46 2008
@@ -73,9 +73,6 @@
 
    This step applies only to IoC layer injection (not to injection into 
components).
 
-   <Currently: this step only applies to parameter, not to field; an 
outstanding issue is to support resource
-   injection into fields.>
-
    When the Inject annotation is <not present> at the point of injection, 
Tapestry checks to see
    if a resource can be injected.  When the Inject annotation is present, this 
step is skipped (this is necessary
    when the object to be injected has a type that conflicts with a resource 
type, such as String).
@@ -113,6 +110,13 @@
    If field type does not match any of the available resource types, or the 
Inject annotation is present,
    logic continues to the next step.
 
+   Injection of resources into fields is triggered by the presence of the
+   
{{{../apidocs/org/apache/tapestry5/ioc/annotations/InjectResource.html}InjectResource}}
+   annotation, whereas injection of resources into parameters occurs when the 
Inject or InjectService
+   annotation is <not> present.  These rules are slightly tricky, which 
reflects a desire to avoid
+   any annotations except when needed, and the fact that field injection came 
much later than
+   parameter injection.
+
 * Service Lookup by Type and Annotations
 
   Tapestry attempts to find a matching <service>.
@@ -174,8 +178,9 @@
 ** Autobuild ObjectProvider
 
    Checks to see if the
-   
{{{../apidocs/org/apache/tapestry5/ioc/annotation/Autobuild.html}Autobuild}} is 
present and,
-   if so, autobuilds the value for the parameter. 
+   
{{{../apidocs/org/apache/tapestry5/ioc/annotation/Autobuild.html}Autobuild}} 
annotation is present and,
+   if so, autobuilds the value for the parameter. Of course, the object being 
built will itself
+   be configured via injection.
 
 ** Alias ObjectProvider  (tapestry-core)
 

Added: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FailedFieldInjectionStringTransformer.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FailedFieldInjectionStringTransformer.java?rev=713263&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FailedFieldInjectionStringTransformer.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FailedFieldInjectionStringTransformer.java
 Tue Nov 11 20:39:46 2008
@@ -0,0 +1,28 @@
+//  Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc;
+
+import org.apache.tapestry5.ioc.annotations.InjectResource;
+
+public class FailedFieldInjectionStringTransformer implements StringTransformer
+{
+    @InjectResource
+    private Runnable unknownRunnable;
+
+    public String transform(String input)
+    {
+        return null;
+    }
+}

Added: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceInjectionModule.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceInjectionModule.java?rev=713263&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceInjectionModule.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceInjectionModule.java
 Tue Nov 11 20:39:46 2008
@@ -0,0 +1,32 @@
+//  Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc;
+
+public class FieldResourceInjectionModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(FieldResourceService.class);
+        binder.bind(StringTransformer.class, 
FailedFieldInjectionStringTransformer.class);
+    }
+
+    public static void contributeFieldResourceService(Configuration<String> 
configuration)
+    {
+        configuration.add("Fred");
+        configuration.add("Barney");
+        configuration.add("Wilma");
+        configuration.add("Betty");
+    }
+}

Added: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceService.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceService.java?rev=713263&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceService.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceService.java
 Tue Nov 11 20:39:46 2008
@@ -0,0 +1,24 @@
+//  Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc;
+
+import java.util.List;
+
+public interface FieldResourceService
+{
+    String getServiceId();
+
+    List<String> getLabels();
+}

Added: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceServiceImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceServiceImpl.java?rev=713263&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceServiceImpl.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/FieldResourceServiceImpl.java
 Tue Nov 11 20:39:46 2008
@@ -0,0 +1,46 @@
+//  Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc;
+
+import org.apache.tapestry5.ioc.annotations.InjectResource;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+
+public class FieldResourceServiceImpl implements FieldResourceService
+{
+    @InjectResource
+    private String serviceId;
+
+    @InjectResource
+    private Collection<String> configuration;
+
+    public String getServiceId()
+    {
+        return serviceId;
+    }
+
+    public List<String> getLabels()
+    {
+        List<String> result = CollectionFactory.newList(configuration);
+
+        Collections.sort(result);
+
+        return result;
+    }
+}

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java?rev=713263&r1=713262&r2=713263&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
 Tue Nov 11 20:39:46 2008
@@ -1014,4 +1014,42 @@
 
         r.shutdown();
     }
+
+    /**
+     * TAP5-292
+     */
+    @Test
+    public void field_resource_injection()
+    {
+        Registry r = buildRegistry(FieldResourceInjectionModule.class);
+
+        FieldResourceService s = r.getService(FieldResourceService.class);
+
+        assertEquals(s.getServiceId(), "FieldResourceService");
+        assertListsEquals(s.getLabels(), "Barney", "Betty", "Fred", "Wilma");
+
+        r.shutdown();
+    }
+
+    /**
+     * TAP5-292
+     */
+    @Test
+    public void failed_field_resource_injection()
+    {
+        Registry r = buildRegistry(FieldResourceInjectionModule.class);
+
+        StringTransformer s = r.getService(StringTransformer.class);
+
+        try
+        {
+            s.transform("hello");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex,
+                                  "Unable to determine resource value to 
inject into field 'unknownRunnable' (of type java.lang.Runnable).");
+        }
+    }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/InternalUtilsTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/InternalUtilsTest.java?rev=713263&r1=713262&r2=713263&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/InternalUtilsTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/InternalUtilsTest.java
 Tue Nov 11 20:39:46 2008
@@ -473,7 +473,7 @@
 
         replay();
 
-        InternalUtils.injectIntoFields(target, ol, tracker);
+        InternalUtils.injectIntoFields(target, ol, null, tracker);
 
         assertSame(target.getFred(), fred);
 
@@ -507,7 +507,7 @@
 
         replay();
 
-        InternalUtils.injectIntoFields(target, ol, tracker);
+        InternalUtils.injectIntoFields(target, ol, null, tracker);
 
         assertSame(target.getSymbolSource(), ss);
 
@@ -530,7 +530,7 @@
 
         try
         {
-            InternalUtils.injectIntoFields(target, ol, tracker);
+            InternalUtils.injectIntoFields(target, ol, null, tracker);
 
             unreachable();
         }


Reply via email to