tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From drobia...@apache.org
Subject svn commit: r1057035 - in /tapestry/tapestry5/trunk: tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ tapestry-core/src/main/java/org/apache/tapestry5/services/ tapestry-core/src/main/java/org/apache/tapestry5/test/ tapestry-core/sr...
Date Sun, 09 Jan 2011 21:34:54 GMT
Author: drobiazko
Date: Sun Jan  9 21:34:53 2011
New Revision: 1057035

URL: http://svn.apache.org/viewvc?rev=1057035&view=rev
Log:
TAP5-1385: Added basic support for JSR-330

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectNamedWorker.java   (with props)
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/AtInjectDemo.java   (with props)
    tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/AtInjectDemo.tml
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/FieldInjectionViaJavaxInject.java   (with props)
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/FieldInjectionViaJavaxNamed.java   (with props)
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/JavaxInjectBean.java   (with props)
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/TooManyAutobuildConstructorsBean.java   (with props)
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectWorker.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/InjectWorkerTest.java
    tapestry/tapestry5/trunk/tapestry-ioc/pom.xml
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ContributionDefImplTest.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodFixture.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodInvokerTest.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/InternalUtilsTest.java

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectNamedWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectNamedWorker.java?rev=1057035&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectNamedWorker.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectNamedWorker.java Sun Jan  9 21:34:53 2011
@@ -0,0 +1,73 @@
+// Copyright 2010 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.internal.transform;
+
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.tapestry5.func.Predicate;
+import org.apache.tapestry5.internal.services.ComponentClassCache;
+import org.apache.tapestry5.ioc.ObjectLocator;
+import org.apache.tapestry5.model.MutableComponentModel;
+import org.apache.tapestry5.services.ClassTransformation;
+import org.apache.tapestry5.services.ComponentClassTransformWorker;
+import org.apache.tapestry5.services.TransformField;
+
+/**
+ * Processes the combination of {@link javax.inject.Inject} and {@link javax.inject.Named} annotations.
+ * 
+ * @since 5.3.0
+ */
+public class InjectNamedWorker implements ComponentClassTransformWorker
+{
+    private final ObjectLocator locator;
+
+    private final ComponentClassCache cache;
+
+    public InjectNamedWorker(ObjectLocator locator, ComponentClassCache cache)
+    {
+        this.locator = locator;
+        this.cache = cache;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+    	
+    	List<TransformField> fields = transformation.matchFields(new Predicate<TransformField>() 
+    	{
+
+			public boolean accept(TransformField field) 
+			{
+				return field.getAnnotation(Inject.class) != null && field.getAnnotation(Named.class) != null;
+			}
+		});
+    	
+        for (TransformField field : fields)
+        {
+        	Named annotation = field.getAnnotation(Named.class);
+
+            field.claim(annotation);
+
+            Class fieldType = cache.forName(field.getType());
+
+            Object service = locator.getService(annotation.value(), fieldType);
+
+            field.inject(service);
+        }
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectNamedWorker.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectNamedWorker.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectWorker.java?rev=1057035&r1=1057034&r2=1057035&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectWorker.java Sun Jan  9 21:34:53 2011
@@ -14,6 +14,12 @@
 
 package org.apache.tapestry5.internal.transform;
 
+import java.lang.annotation.Annotation;
+import java.util.List;
+
+import javax.inject.Named;
+
+import org.apache.tapestry5.func.Predicate;
 import org.apache.tapestry5.ioc.ObjectLocator;
 import org.apache.tapestry5.ioc.OperationTracker;
 import org.apache.tapestry5.ioc.annotations.Inject;
@@ -25,7 +31,7 @@ import org.apache.tapestry5.services.Tra
 
 /**
  * Performs injection triggered by any field annotated with the {@link org.apache.tapestry5.ioc.annotations.Inject}
- * annotation.
+ * annotation or the {@link javax.inject.Inject} annotation.
  * <p/>
  * The implementation of this worker mostly delegates to a chain of command of
  * {@link org.apache.tapestry5.services.InjectionProvider}s.
@@ -49,18 +55,24 @@ public class InjectWorker implements Com
 
     public final void transform(final ClassTransformation transformation, final MutableComponentModel model)
     {
-        for (final String fieldName : transformation.findFieldsWithAnnotation(Inject.class))
+    	List<TransformField> fields = matchFields(transformation);
+    	
+        for (final TransformField field : fields)
         {
+        	final String fieldName = field.getName();
+        	
             tracker.run("Injecting field " + fieldName, new Runnable()
             {
                 public void run()
                 {
 
-                    Inject annotation = transformation.getFieldAnnotation(fieldName, Inject.class);
+                    Inject inject = field.getAnnotation(Inject.class);
+                    
+                    Annotation annotation = inject == null? field.getAnnotation(javax.inject.Inject.class): inject;
 
                     try
                     {
-                        String fieldType = transformation.getFieldType(fieldName);
+                        String fieldType = field.getType();
 
                         Class type = transformation.toClass(fieldType);
 
@@ -68,7 +80,7 @@ public class InjectWorker implements Com
                                 model);
 
                         if (success)
-                            transformation.claimField(fieldName, annotation);
+                            field.claim(annotation);
                     }
                     catch (RuntimeException ex)
                     {
@@ -79,4 +91,17 @@ public class InjectWorker implements Com
             });
         }
     }
+    
+    private List<TransformField> matchFields(final ClassTransformation transformation)
+    {	
+    	Predicate<TransformField> predicate = new Predicate<TransformField>()
+    	{
+			public boolean accept(TransformField field) 
+			{
+				return field.getAnnotation(Inject.class) != null 
+						|| (field.getAnnotation(javax.inject.Inject.class) != null && field.getAnnotation(Named.class) == null);
+			}
+		};
+    	return transformation.matchFields(predicate);
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=1057035&r1=1057034&r2=1057035&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Sun Jan  9 21:34:53 2011
@@ -595,6 +595,7 @@ public final class TapestryModule
 
         configuration.addInstance("Inject", InjectWorker.class);
         configuration.addInstance("InjectService", InjectServiceWorker.class);
+        configuration.addInstance("InjectNamed", InjectNamedWorker.class);
 
         configuration.add("MixinAfter", new MixinAfterWorker());
         configuration.add("Component", new ComponentWorker(resolver));

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java?rev=1057035&r1=1057034&r2=1057035&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java Sun Jan  9 21:34:53 2011
@@ -37,6 +37,7 @@ import org.apache.tapestry5.annotations.
 import org.apache.tapestry5.annotations.Path;
 import org.apache.tapestry5.beaneditor.BeanModel;
 import org.apache.tapestry5.beaneditor.PropertyModel;
+import org.apache.tapestry5.func.Predicate;
 import org.apache.tapestry5.internal.services.MapMessages;
 import org.apache.tapestry5.internal.services.MarkupWriterImpl;
 import org.apache.tapestry5.ioc.AnnotationProvider;
@@ -367,6 +368,21 @@ public abstract class TapestryTestCase e
     {
         expect(source.getAsset(root, path, locale)).andReturn(asset);
     }
+    
+    protected final void train_matchFields(ClassTransformation transformation, TransformField field)
+    {
+    	expect(transformation.matchFields(EasyMock.isA(Predicate.class))).andReturn(Arrays.asList(field));
+    }
+    
+    protected final void train_getName(TransformField field, String name)
+    {
+    	expect(field.getName()).andReturn(name);
+    }
+    
+    protected final <T extends Annotation> void train_getAnnotation(TransformField field, Class<T> annotationClass, T anotation)
+    {
+    	expect(field.getAnnotation(annotationClass)).andReturn(anotation);
+    }
 
     /** @deprecated May be removed in Tapestry 5.3 */
     protected final void train_findFieldsWithAnnotation(ClassTransformation transformation,
@@ -1115,6 +1131,11 @@ public abstract class TapestryTestCase e
     {
         expect(translator.getType()).andReturn(type).atLeastOnce();
     }
+    
+    protected final void train_getType(TransformField field, String type)
+    {
+        expect(field.getType()).andReturn(type).atLeastOnce();
+    }
 
     protected final void train_createDefaultTranslator(FieldTranslatorSource source, ComponentResources resources,
             String parameterName, FieldTranslator translator)

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java?rev=1057035&r1=1057034&r2=1057035&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java Sun Jan  9 21:34:53 2011
@@ -173,6 +173,31 @@ public class CoreBehaviorsTests extends 
 
         assertText("viaInjectService", "1722 tracks in music library");
     }
+    
+    @Test
+    public void atinjection() throws Exception
+    {
+        clickThru("@javax.inject.Inject Demo");
+
+        // is a test for a named @Inject:
+        assertTextPresent("<Proxy for Request(org.apache.tapestry5.services.Request)>");
+
+        // is a test for an anonymous @Inject and
+        // ComponentResourcesInjectionProvider
+        assertTextPresent("ComponentResources[AtInjectDemo]");
+
+        // Another test, DefaultInjectionProvider
+        assertTextPresent("<Proxy for BindingSource(org.apache.tapestry5.services.BindingSource)>");
+
+        assertTextPresent("Injected Symbol: Symbol contributed to ApplicationDefaults");
+
+        // Prove that injection using a marker annotation (to match against a
+        // marked service) works.
+
+        assertTextPresent("Injection via Marker: Bonjour!");
+
+        assertTextPresent("Injection via @Named: 1722 tracks in music library");
+    }
 
     @Test
     public void instance_mixin()

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/AtInjectDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/AtInjectDemo.java?rev=1057035&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/AtInjectDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/AtInjectDemo.java Sun Jan  9 21:34:53 2011
@@ -0,0 +1,82 @@
+// Copyright 2010 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.integration.app1.pages;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.integration.app1.services.French;
+import org.apache.tapestry5.integration.app1.services.Greeter;
+import org.apache.tapestry5.integration.app1.services.MusicLibrary;
+import org.apache.tapestry5.ioc.annotations.Symbol;
+import org.apache.tapestry5.services.BindingSource;
+import org.apache.tapestry5.services.Request;
+
+public class AtInjectDemo 
+{
+    // Named --- now demonstrating case insensitivity
+    // Now vestigial!
+    @Inject
+    private Request request;
+
+    @Inject
+    @Symbol("app.injected-symbol")
+    private String injectedSymbol;
+
+    // Via ComponentResourcesInjectionProvider
+    @Inject
+    private ComponentResources resources;
+
+    // Via ??? -- have to ensure that BindingSource
+    // stays unique.
+    @Inject
+    private BindingSource bindingSource;
+
+    @Inject
+    @French
+    private Greeter greeter;
+
+    @Property
+    @Inject
+    @Named("MusicLibrary")
+    private MusicLibrary musicLibrary;
+
+    public String getGreeting()
+    {
+        return greeter.getGreeting();
+    }
+
+    public BindingSource getBindingSource()
+    {
+        return bindingSource;
+    }
+
+    public Request getRequest()
+    {
+        return request;
+    }
+
+    public ComponentResources getResources()
+    {
+        return resources;
+    }
+
+    public String getInjectedSymbol()
+    {
+        return injectedSymbol;
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/AtInjectDemo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/AtInjectDemo.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java?rev=1057035&r1=1057034&r2=1057035&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java Sun Jan  9 21:34:53 2011
@@ -465,7 +465,9 @@ public class Index
                     new Item("DecorateComponentEventLinkDemo", "Decorate Component Event Link Demo",
                             "Decorating event links"),
 
-                    new Item("ValidatorMacroDemo", "Validator Macro Demo", "Using validator macros")
+                    new Item("ValidatorMacroDemo", "Validator Macro Demo", "Using validator macros"),
+
+                    new Item("AtInjectDemo", "@javax.inject.Inject Demo", "Using @javax.inject.Inject for injection")
 
             );
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/InjectWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/InjectWorkerTest.java?rev=1057035&r1=1057034&r2=1057035&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/InjectWorkerTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/InjectWorkerTest.java Sun Jan  9 21:34:53 2011
@@ -23,110 +23,121 @@ import org.apache.tapestry5.services.Cla
 import org.apache.tapestry5.services.ComponentClassTransformWorker;
 import org.apache.tapestry5.services.InjectionProvider;
 import org.apache.tapestry5.services.Request;
+import org.apache.tapestry5.services.TransformField;
 import org.testng.annotations.Test;
 
-public class InjectWorkerTest extends InternalBaseTestCase
-{
-    private static final String REQUEST_CLASS_NAME = Request.class.getName();
+public class InjectWorkerTest extends InternalBaseTestCase {
+	private static final String REQUEST_CLASS_NAME = Request.class.getName();
 
-    @Test
-    public void anonymous_injection()
-    {
-        ObjectLocator locator = mockObjectLocator();
-        InjectionProvider ip = newMock(InjectionProvider.class);
-        Inject annotation = newInject();
-        ClassTransformation ct = mockClassTransformation();
-        MutableComponentModel model = mockMutableComponentModel();
+	@Test
+	public void anonymous_injection() {
+		ObjectLocator locator = mockObjectLocator();
+		InjectionProvider ip = newMock(InjectionProvider.class);
+		Inject annotation = newInject();
+		ClassTransformation ct = mockClassTransformation();
+		MutableComponentModel model = mockMutableComponentModel();
+		TransformField field = newMock(TransformField.class);
 
-        train_findFieldsWithAnnotation(ct, Inject.class, "myfield");
-        train_getFieldAnnotation(ct, "myfield", Inject.class, annotation);
+		train_matchFields(ct, field);
 
-        train_getFieldType(ct, "myfield", REQUEST_CLASS_NAME);
-        train_toClass(ct, REQUEST_CLASS_NAME, Request.class);
+		train_getName(field, "myfield");
 
-        train_provideInjection(ip, "myfield", Request.class, locator, ct, model, true);
+		train_getAnnotation(field, Inject.class, annotation);
 
-        ct.claimField("myfield", annotation);
+		train_getType(field, REQUEST_CLASS_NAME);
+		train_toClass(ct, REQUEST_CLASS_NAME, Request.class);
 
-        replay();
+		train_provideInjection(ip, "myfield", Request.class, locator, ct,
+				model, true);
 
-        ComponentClassTransformWorker worker = new InjectWorker(locator, ip, new QuietOperationTracker());
+		field.claim(annotation);
 
-        worker.transform(ct, model);
+		replay();
 
-        verify();
-    }
+		ComponentClassTransformWorker worker = new InjectWorker(locator, ip,
+				new QuietOperationTracker());
 
-    @Test
-    public void anonymous_injection_not_provided()
-    {
-        ObjectLocator locator = mockObjectLocator();
-        InjectionProvider ip = newMock(InjectionProvider.class);
-        Inject annotation = newInject();
-        ClassTransformation ct = mockClassTransformation();
-        MutableComponentModel model = mockMutableComponentModel();
+		worker.transform(ct, model);
 
-        train_findFieldsWithAnnotation(ct, Inject.class, "myfield");
-        train_getFieldAnnotation(ct, "myfield", Inject.class, annotation);
+		verify();
+	}
 
-        train_getFieldType(ct, "myfield", REQUEST_CLASS_NAME);
-        train_toClass(ct, REQUEST_CLASS_NAME, Request.class);
+	@Test
+	public void anonymous_injection_not_provided() {
+		ObjectLocator locator = mockObjectLocator();
+		InjectionProvider ip = newMock(InjectionProvider.class);
+		Inject annotation = newInject();
+		ClassTransformation ct = mockClassTransformation();
+		MutableComponentModel model = mockMutableComponentModel();
+		TransformField field = newMock(TransformField.class);
 
-        train_provideInjection(ip, "myfield", Request.class, locator, ct, model, false);
+		train_matchFields(ct, field);
 
-        replay();
+		train_getName(field, "myfield");
 
-        ComponentClassTransformWorker worker = new InjectWorker(locator, ip, new QuietOperationTracker());
+		train_getAnnotation(field, Inject.class, annotation);
 
-        // Does the work but doesn't claim the field, since there was no match.
+		train_getType(field, REQUEST_CLASS_NAME);
+		train_toClass(ct, REQUEST_CLASS_NAME, Request.class);
 
-        worker.transform(ct, model);
+		train_provideInjection(ip, "myfield", Request.class, locator, ct,
+				model, false);
 
-        verify();
-    }
+		replay();
 
-    @Test
-    public void injection_provider_threw_exception()
-    {
-        ObjectLocator locator = mockObjectLocator();
-        InjectionProvider ip = newMock(InjectionProvider.class);
-        Inject annotation = newInject();
-        ClassTransformation ct = mockClassTransformation();
-        MutableComponentModel model = mockMutableComponentModel();
-        RuntimeException failure = new RuntimeException("Oops.");
+		ComponentClassTransformWorker worker = new InjectWorker(locator, ip,
+				new QuietOperationTracker());
 
-        train_findFieldsWithAnnotation(ct, Inject.class, "myfield");
-        train_getFieldAnnotation(ct, "myfield", Inject.class, annotation);
+		// Does the work but doesn't claim the field, since there was no match.
 
-        train_getFieldType(ct, "myfield", REQUEST_CLASS_NAME);
-        train_toClass(ct, REQUEST_CLASS_NAME, Request.class);
+		worker.transform(ct, model);
 
-        expect(ip.provideInjection("myfield", Request.class, locator, ct, model)).andThrow(failure);
+		verify();
+	}
 
-        train_getClassName(ct, "foo.bar.Baz");
+	@Test
+	public void injection_provider_threw_exception() {
+		ObjectLocator locator = mockObjectLocator();
+		InjectionProvider ip = newMock(InjectionProvider.class);
+		Inject annotation = newInject();
+		ClassTransformation ct = mockClassTransformation();
+		MutableComponentModel model = mockMutableComponentModel();
+		TransformField field = newMock(TransformField.class);
+		RuntimeException failure = new RuntimeException("Oops.");
 
-        replay();
+		train_matchFields(ct, field);
 
-        ComponentClassTransformWorker worker = new InjectWorker(locator, ip, new QuietOperationTracker());
+		train_getName(field, "myfield");
 
-        try
-        {
-            worker.transform(ct, model);
-            unreachable();
-        }
-        catch (RuntimeException ex)
-        {
-            assertEquals(
-                    ex.getMessage(),
-                    "Error obtaining injected value for field foo.bar.Baz.myfield: Oops.");
-            assertSame(ex.getCause(), failure);
-        }
+		train_getAnnotation(field, Inject.class, annotation);
 
-        verify();
-    }
+		train_getType(field, REQUEST_CLASS_NAME);
+		train_toClass(ct, REQUEST_CLASS_NAME, Request.class);
 
-    protected final Inject newInject()
-    {
-        return newMock(Inject.class);
-    }
+		expect(
+				ip.provideInjection("myfield", Request.class, locator, ct,
+						model)).andThrow(failure);
+
+		train_getClassName(ct, "foo.bar.Baz");
+
+		replay();
+
+		ComponentClassTransformWorker worker = new InjectWorker(locator, ip,
+				new QuietOperationTracker());
+
+		try {
+			worker.transform(ct, model);
+			unreachable();
+		} catch (RuntimeException ex) {
+			assertEquals(ex.getMessage(),
+					"Error obtaining injected value for field foo.bar.Baz.myfield: Oops.");
+			assertSame(ex.getCause(), failure);
+		}
+
+		verify();
+	}
+
+	protected final Inject newInject() {
+		return newMock(Inject.class);
+	}
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/AtInjectDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/AtInjectDemo.tml?rev=1057035&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/AtInjectDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/AtInjectDemo.tml Sun Jan  9 21:34:53 2011
@@ -0,0 +1,9 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <p>Demonstrates the use of the @javax.inject.Inject annotation.</p>
+    <p>WebRequest: ${request}</p>
+    <p>ComponentResources: ${resources}</p>
+    <p>BindingSource: ${bindingSource}</p>
+    <p>Injected Symbol: ${injectedSymbol}</p>
+    <p>Injection via Marker: ${greeting}</p>
+    <p>Injection via @Named: ${musicLibrary.tracks.size()} tracks in music library</p>
+</html>

Modified: tapestry/tapestry5/trunk/tapestry-ioc/pom.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/pom.xml?rev=1057035&r1=1057034&r2=1057035&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/pom.xml (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/pom.xml Sun Jan  9 21:34:53 2011
@@ -1,146 +1,154 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <groupId>org.apache.tapestry</groupId>
-    <artifactId>tapestry-ioc</artifactId>
-    <packaging>jar</packaging>
-    <!-- This should change to tapestry-project -->
-    <parent>
-        <groupId>org.apache.tapestry</groupId>
-        <artifactId>tapestry-project</artifactId>
-        <version>5.3.0-SNAPSHOT</version>
-    </parent>
-    <name>Tapestry Inversion of Control Container</name>
-    <description>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>org.apache.tapestry</groupId>
+	<artifactId>tapestry-ioc</artifactId>
+	<packaging>jar</packaging>
+	<!-- This should change to tapestry-project -->
+	<parent>
+		<groupId>org.apache.tapestry</groupId>
+		<artifactId>tapestry-project</artifactId>
+		<version>5.3.0-SNAPSHOT</version>
+	</parent>
+	<name>Tapestry Inversion of Control Container</name>
+	<description>
         A code-centric, high-performance, simple Inversion of Control
         container.
     </description>
-    <inceptionYear>2006</inceptionYear>
+	<inceptionYear>2006</inceptionYear>
 
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.tapestry</groupId>
-            <artifactId>tapestry5-annotations</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.tapestry</groupId>
-            <artifactId>tapestry-func</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        
-        <dependency>
-            <groupId>javassist</groupId>
-            <artifactId>javassist</artifactId>
-            <version>3.12.1.GA</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-            <version>1.6.1</version>
-        </dependency>
-
-        <!-- SLF4J now supports earlier versions of Log4J more cleanly, but still nice to include
-             a fully compatible version. -->
-        <dependency>
-            <groupId>log4j</groupId>
-            <artifactId>log4j</artifactId>
-            <version>1.2.14</version>
-        </dependency>
-
-        <!-- 0.00001% of applications will need to override this dependency to not use Log4J. -->
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-            <version>1.6.1</version>
-        </dependency>
-
-
-        <!-- Override parent pom: needed at compile time. -->
-        <dependency>
-            <groupId>org.easymock</groupId>
-            <artifactId>easymock</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <!-- Override parent pom: needed at compile time. -->
-        <dependency>
-            <groupId>org.testng</groupId>
-            <artifactId>testng</artifactId>
-            <!-- Looks like if you override scope, you have to provide version (and classifier) as well.
-   Or perhaps this has something to do with classifier. -->
-            <version>${testng-version}</version>
-            <scope>provided</scope>
-        </dependency>
-    </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-source-plugin</artifactId>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-assembly-plugin</artifactId>
-            </plugin>
-            <!-- This gets the plugin to clean up the cobertura.ser file left
-        in the root directory. -->
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>cobertura-maven-plugin</artifactId>
-                <version>${cobertura-plugin-version}</version>
-                <executions>
-                    <execution>
-                        <id>clean</id>
-                        <goals>
-                            <goal>clean</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-    <reporting>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-project-info-reports-plugin</artifactId>
-                <reportSets>
-                    <reportSet>
-                        <reports>
-                            <report>summary</report>
-                            <report>dependencies</report>
-                        </reports>
-                    </reportSet>
-                </reportSets>
-            </plugin>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>cobertura-maven-plugin</artifactId>
-                <version>${cobertura-plugin-version}</version>
-            </plugin>	    
-	    <plugin>
-		<groupId>org.codehaus.mojo</groupId>
-		<artifactId>clirr-maven-plugin</artifactId>
-		<configuration>
-		    <comparisonVersion>5.1.0.5</comparisonVersion>
-		    <excludes>
-			<exclude>**/internal/**</exclude>
-			<exclude>**/test/**</exclude>
-		    </excludes>
-		</configuration>
-	    </plugin>
-        </plugins>
-    </reporting>
-    <repositories>
-        <repository>
-            <!-- Needed to keep up with latest Javassist versions. -->
-            <id>jboss</id>
-            <url>https://repository.jboss.org/nexus/content/repositories/releases</url>
-        </repository>
-    </repositories>
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.tapestry</groupId>
+			<artifactId>tapestry5-annotations</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.tapestry</groupId>
+			<artifactId>tapestry-func</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>javassist</groupId>
+			<artifactId>javassist</artifactId>
+			<version>3.12.1.GA</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+			<version>1.6.1</version>
+		</dependency>
+
+		<dependency>
+			<groupId>javax.inject</groupId>
+			<artifactId>javax.inject</artifactId>
+			<version>1</version>
+		</dependency>
+
+		<!-- SLF4J now supports earlier versions of Log4J more cleanly, but still 
+			nice to include a fully compatible version. -->
+		<dependency>
+			<groupId>log4j</groupId>
+			<artifactId>log4j</artifactId>
+			<version>1.2.14</version>
+		</dependency>
+
+		<!-- 0.00001% of applications will need to override this dependency to 
+			not use Log4J. -->
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-log4j12</artifactId>
+			<version>1.6.1</version>
+		</dependency>
+
+
+		<!-- Override parent pom: needed at compile time. -->
+		<dependency>
+			<groupId>org.easymock</groupId>
+			<artifactId>easymock</artifactId>
+			<scope>provided</scope>
+		</dependency>
+		<!-- Override parent pom: needed at compile time. -->
+		<dependency>
+			<groupId>org.testng</groupId>
+			<artifactId>testng</artifactId>
+			<!-- Looks like if you override scope, you have to provide version (and 
+				classifier) as well. Or perhaps this has something to do with classifier. -->
+			<version>${testng-version}</version>
+			<scope>provided</scope>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-assembly-plugin</artifactId>
+			</plugin>
+			<!-- This gets the plugin to clean up the cobertura.ser file left in the 
+				root directory. -->
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>cobertura-maven-plugin</artifactId>
+				<version>${cobertura-plugin-version}</version>
+				<executions>
+					<execution>
+						<id>clean</id>
+						<goals>
+							<goal>clean</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+	<reporting>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-project-info-reports-plugin</artifactId>
+				<reportSets>
+					<reportSet>
+						<reports>
+							<report>summary</report>
+							<report>dependencies</report>
+						</reports>
+					</reportSet>
+				</reportSets>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>cobertura-maven-plugin</artifactId>
+				<version>${cobertura-plugin-version}</version>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>clirr-maven-plugin</artifactId>
+				<configuration>
+					<comparisonVersion>5.1.0.5</comparisonVersion>
+					<excludes>
+						<exclude>**/internal/**</exclude>
+						<exclude>**/test/**</exclude>
+					</excludes>
+				</configuration>
+			</plugin>
+		</plugins>
+	</reporting>
+	<repositories>
+		<repository>
+			<!-- Needed to keep up with latest Javassist versions. -->
+			<id>jboss</id>
+			<url>https://repository.jboss.org/nexus/content/repositories/releases</url>
+		</repository>
+	</repositories>
 </project>

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=1057035&r1=1057034&r2=1057035&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 Sun Jan  9 21:34:53 2011
@@ -40,6 +40,10 @@ import java.util.concurrent.atomic.Atomi
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import javax.inject.Named;
+
+import org.apache.tapestry5.func.F;
+import org.apache.tapestry5.func.Flow;
 import org.apache.tapestry5.func.Mapper;
 import org.apache.tapestry5.func.Predicate;
 import org.apache.tapestry5.ioc.AdvisorDef;
@@ -245,6 +249,14 @@ public class InternalUtils
 
             return locator.getService(serviceId, injectionType);
         }
+        
+        
+        Named named = provider.getAnnotation(Named.class);
+        
+        if(named != null)
+        {
+        	return locator.getService(named.value(), injectionType);
+        }
 
         // In the absence of @InjectService, try some autowiring. First, does the
         // parameter type match one of the resources (the parameter defaults)?
@@ -381,6 +393,22 @@ public class InternalUtils
                             return;
                         }
 
+                        if (ap.getAnnotation(javax.inject.Inject.class) != null)
+                        {
+                        	Named named = ap.getAnnotation(Named.class);
+                        	
+                        	if(named == null)
+                        	{
+                        		inject(object, f, locator.getObject(fieldType, ap));
+                        	}
+                        	else
+                        	{   
+                        		inject(object, f, locator.getService(named.value(), fieldType));
+                        	}
+                        	
+                            return;
+                        }
+
                         // Ignore fields that do not have the necessary annotation.
 
                     }
@@ -717,6 +745,21 @@ public class InternalUtils
             if (c.getAnnotation(Inject.class) != null)
                 return c;
         }
+        
+        Constructor standardConstructor = findConstructorByAnnotation(constructors, Inject.class);
+        Constructor javaxConstructor = findConstructorByAnnotation(constructors, javax.inject.Inject.class);
+        
+        if(standardConstructor != null && javaxConstructor != null)
+        	throw new IllegalArgumentException(
+        			String.format("Too many autobuilt constructors found. Please use either '@%s' or '@%s' annotation to mark a constructor for autobuilding.", 
+        						Inject.class.getName(), javax.inject.Inject.class.getName())); 
+        
+        if(standardConstructor != null) 
+        	return standardConstructor;
+        
+        if(javaxConstructor != null)
+        	return javaxConstructor;
+        
 
         // Choose a constructor with the most parameters.
 
@@ -732,6 +775,17 @@ public class InternalUtils
 
         return constructors[0];
     }
+    
+    private static <T extends Annotation> Constructor findConstructorByAnnotation(Constructor[] constructors, Class<T> annotationClass)
+    {
+        for (Constructor c : constructors)
+        {
+            if (c.getAnnotation(annotationClass) != null)
+                return c;
+        }
+        
+        return null;
+    }
 
     /**
      * Adds a value to a specially organized map where the values are lists of objects. This somewhat simulates a map

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ContributionDefImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ContributionDefImplTest.java?rev=1057035&r1=1057034&r2=1057035&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ContributionDefImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ContributionDefImplTest.java Sun Jan  9 21:34:53 2011
@@ -16,6 +16,8 @@ package org.apache.tapestry5.ioc.interna
 
 import java.lang.reflect.Method;
 
+import javax.inject.Named;
+
 import org.apache.tapestry5.ioc.Configuration;
 import org.apache.tapestry5.ioc.MappedConfiguration;
 import org.apache.tapestry5.ioc.ModuleBuilderSource;
@@ -87,6 +89,31 @@ public class ContributionDefImplTest ext
 
         verify();
     }
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void unordered_collection_with_named_service_lookup()
+    {
+        Configuration configuration = mockConfiguration();
+        ServiceResources resources = mockServiceResources(tracker);
+        UpcaseService service = mockUpcaseService();
+        Logger logger = mockLogger();
+
+        train_getLogger(resources, logger);
+        train_getService(resources, "zip.Zap", UpcaseService.class, service);
+        train_getServiceId(resources, "Bif");
+
+        configuration.add(service);
+
+        replay();
+
+        Method m = findMethod("contributeUnorderedParameterNamedServiceLookup");
+        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null, null, null);
+
+        def.contribute(this, resources, configuration);
+
+        verify();
+    }
 
     @Test
     public void unordered_collection_with_incorrect_configuration_parameter()
@@ -150,6 +177,32 @@ public class ContributionDefImplTest ext
 
     @SuppressWarnings("unchecked")
     @Test
+    public void ordered_collection_with_named_service_lookup()
+    {
+        OrderedConfiguration configuration = mockOrderedConfiguration();
+        ServiceResources resources = mockServiceResources(tracker);
+        UpcaseService service = mockUpcaseService();
+        Logger logger = mockLogger();
+
+        train_getLogger(resources, logger);
+
+        train_getService(resources, "zip.Zap", UpcaseService.class, service);
+        train_getServiceId(resources, "Bif");
+
+        configuration.add("fred", service);
+
+        replay();
+
+        Method m = findMethod("contributeOrderedParameterNamedServiceLookup");
+        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null, null, null);
+
+        def.contribute(this, resources, configuration);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
     public void mapped_collection_with_service_lookup()
     {
         MappedConfiguration configuration = mockMappedConfiguration();
@@ -174,6 +227,32 @@ public class ContributionDefImplTest ext
         verify();
     }
 
+    @SuppressWarnings("unchecked")
+    @Test
+    public void mapped_collection_with_named_service_lookup()
+    {
+        MappedConfiguration configuration = mockMappedConfiguration();
+        ServiceResources resources = mockServiceResources(tracker);
+        UpcaseService service = mockUpcaseService();
+        Logger logger = mockLogger();
+
+        train_getLogger(resources, logger);
+
+        train_getService(resources, "zip.Zap", UpcaseService.class, service);
+        train_getServiceId(resources, "Bif");
+
+        configuration.add("upcase", service);
+
+        replay();
+
+        Method m = findMethod("contributeMappedParameterNamedServiceLookup");
+        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null, null, null);
+
+        def.contribute(this, resources, configuration);
+
+        verify();
+    }
+
     private UpcaseService mockUpcaseService()
     {
         return newMock(UpcaseService.class);
@@ -192,6 +271,13 @@ public class ContributionDefImplTest ext
         configuration.add(service);
     }
 
+    public void contributeUnorderedParameterNamedServiceLookup(Configuration<UpcaseService> configuration,
+                                             @Named("zip.Zap")
+                                             UpcaseService service)
+    {
+        configuration.add(service);
+    }
+
     public void contributeOrderedParameter(OrderedConfiguration<UpcaseService> configuration,
                                            @InjectService("zip.Zap")
                                            UpcaseService service)
@@ -199,6 +285,13 @@ public class ContributionDefImplTest ext
         configuration.add("fred", service);
     }
 
+    public void contributeOrderedParameterNamedServiceLookup(OrderedConfiguration<UpcaseService> configuration,
+                                           @Named("zip.Zap")
+                                           UpcaseService service)
+    {
+        configuration.add("fred", service);
+    }
+
     public void contributeMappedParameter(MappedConfiguration<String, UpcaseService> configuration,
                                           @InjectService("zip.Zap")
                                           UpcaseService service)
@@ -206,6 +299,13 @@ public class ContributionDefImplTest ext
         configuration.add("upcase", service);
     }
 
+    public void contributeMappedParameterNamedServiceLookup(MappedConfiguration<String, UpcaseService> configuration,
+                                          @Named("zip.Zap")
+                                          UpcaseService service)
+    {
+        configuration.add("upcase", service);
+    }
+
     public void contributeUnorderedWrongParameter(MappedConfiguration configuration)
     {
         unreachable();

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodFixture.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodFixture.java?rev=1057035&r1=1057034&r2=1057035&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodFixture.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodFixture.java Sun Jan  9 21:34:53 2011
@@ -18,6 +18,8 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
+import javax.inject.Named;
+
 import org.apache.tapestry5.ioc.ServiceResources;
 import org.apache.tapestry5.ioc.annotations.InjectService;
 import org.apache.tapestry5.ioc.annotations.Value;
@@ -82,6 +84,16 @@ public class ServiceBuilderMethodFixture
 
         return fie;
     }
+    
+
+
+    public FieService build_named_injected(@Named("Foe")
+    FoeService foe)
+    {
+        assertSame(expectedFoe, foe);
+
+        return fie;
+    }
 
     public FieService build_auto(FoeService foe)
     {

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodInvokerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodInvokerTest.java?rev=1057035&r1=1057034&r2=1057035&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodInvokerTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ServiceBuilderMethodInvokerTest.java Sun Jan  9 21:34:53 2011
@@ -173,6 +173,36 @@ public class ServiceBuilderMethodInvoker
 
         verify();
     }
+    
+    @Test
+    public void named_injected_service_method()
+    {
+        ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
+        ServiceBuilderResources resources = mockServiceBuilderResources(tracker);
+        Logger logger = mockLogger();
+
+        fixture.fie = mockFieService();
+        fixture.expectedFoe = newFoe();
+
+        trainForConstructor(resources, logger);
+
+        train_getModuleBuilder(resources, fixture);
+
+        train_getService(resources, "Foe", FoeService.class, fixture.expectedFoe);
+
+        train_isDebugEnabled(logger, false);
+
+        replay();
+
+        ObjectCreator sc = new ServiceBuilderMethodInvoker(resources, CREATOR_DESCRIPTION, findMethod(fixture,
+                "build_named_injected"));
+
+        Object actual = sc.createObject();
+
+        assertSame(actual, fixture.fie);
+
+        verify();
+    }
 
     @SuppressWarnings("unchecked")
     @Test

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/FieldInjectionViaJavaxInject.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/FieldInjectionViaJavaxInject.java?rev=1057035&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/FieldInjectionViaJavaxInject.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/FieldInjectionViaJavaxInject.java Sun Jan  9 21:34:53 2011
@@ -0,0 +1,32 @@
+//  Copyright 2010 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 javax.inject.Inject;
+
+import org.apache.tapestry5.ioc.services.Builtin;
+import org.apache.tapestry5.ioc.services.SymbolSource;
+
+public class FieldInjectionViaJavaxInject
+{
+    @Inject
+    @Builtin
+    private SymbolSource symbolSource;
+
+    public SymbolSource getSymbolSource()
+    {
+        return symbolSource;
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/FieldInjectionViaJavaxInject.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/FieldInjectionViaJavaxInject.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/FieldInjectionViaJavaxNamed.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/FieldInjectionViaJavaxNamed.java?rev=1057035&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/FieldInjectionViaJavaxNamed.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/FieldInjectionViaJavaxNamed.java Sun Jan  9 21:34:53 2011
@@ -0,0 +1,27 @@
+//  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 javax.inject.Inject;
+import javax.inject.Named;
+
+public class FieldInjectionViaJavaxNamed
+{
+	@Inject
+    @Named("BarneyService")
+    private Runnable fred;
+
+    public Runnable getFred() { return fred; }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/FieldInjectionViaJavaxNamed.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/FieldInjectionViaJavaxNamed.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

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=1057035&r1=1057034&r2=1057035&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 Sun Jan  9 21:34:53 2011
@@ -455,6 +455,30 @@ public class InternalUtilsTest extends I
         assertEquals(c.getParameterTypes().length, 1);
         assertEquals(c.getParameterTypes()[0], String.class);
     }
+    
+    @Test
+    public void constructor_with_javax_inject_annotation()
+    {
+        Constructor c = InternalUtils.findAutobuildConstructor(JavaxInjectBean.class);
+
+        assertEquals(c.getParameterTypes().length, 1);
+        assertEquals(c.getParameterTypes()[0], String.class);
+    }
+    
+    @Test
+    public void too_many_autobuild_constructors()
+    {
+    	try
+    	{
+    		InternalUtils.findAutobuildConstructor(TooManyAutobuildConstructorsBean.class);
+    	}
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Too many autobuilt constructors found. Please use either '@org.apache.tapestry5.ioc.annotations' or '@javax.inject.Inject' annotation to mark a constructor for autobuilding.");
+        }
+    }
 
     @Test
     public void validate_constructor_class_not_public()
@@ -511,6 +535,60 @@ public class InternalUtilsTest extends I
 
         verify();
     }
+    
+    @Test
+    public void javax_inject_named_annotation_on_field()
+    {
+        ObjectLocator ol = mockObjectLocator();
+        FieldInjectionViaJavaxNamed target = new FieldInjectionViaJavaxNamed();
+        Runnable fred = mockRunnable();
+
+        train_getService(ol, "BarneyService", Runnable.class, fred);
+
+        replay();
+
+        InternalUtils.injectIntoFields(target, ol, null, tracker);
+
+        assertSame(target.getFred(), fred);
+
+        verify();
+    }
+    
+
+    
+    @Test
+    public void javax_inject_annotation_on_field()
+    {
+        ObjectLocator ol = mockObjectLocator();
+        FieldInjectionViaInject target = new FieldInjectionViaInject();
+        final SymbolSource ss = mockSymbolSource();
+
+        IAnswer answer = new IAnswer()
+        {
+            public Object answer() throws Throwable
+            {
+                Object[] args = EasyMock.getCurrentArguments();
+
+                AnnotationProvider ap = (AnnotationProvider) args[1];
+
+                // Verify that annotations on the field are accessible.
+
+                assertNotNull(ap.getAnnotation(Builtin.class));
+
+                return ss;
+            }
+        };
+
+        expect(ol.getObject(eq(SymbolSource.class), isA(AnnotationProvider.class))).andAnswer(answer);
+
+        replay();
+
+        InternalUtils.injectIntoFields(target, ol, null, tracker);
+
+        assertSame(target.getSymbolSource(), ss);
+
+        verify();
+    }
 
     @Test
     public void inject_annotation_on_field()

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/JavaxInjectBean.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/JavaxInjectBean.java?rev=1057035&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/JavaxInjectBean.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/JavaxInjectBean.java Sun Jan  9 21:34:53 2011
@@ -0,0 +1,55 @@
+// 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 javax.inject.Inject;
+
+
+public class JavaxInjectBean
+{
+    private final String foo;
+    private final Runnable bar;
+
+    public JavaxInjectBean()
+    {
+        this(null);
+    }
+
+    @Inject
+    public JavaxInjectBean(String foo)
+    {
+        this(foo, null);
+    }
+
+    /**
+     * Normally, this would be chosen as it has the most parameters.
+     */
+    public JavaxInjectBean(String foo, Runnable bar)
+    {
+
+        this.foo = foo;
+        this.bar = bar;
+    }
+
+    public String getFoo()
+    {
+        return foo;
+    }
+
+    public Runnable getBar()
+    {
+        return bar;
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/JavaxInjectBean.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/JavaxInjectBean.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/TooManyAutobuildConstructorsBean.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/TooManyAutobuildConstructorsBean.java?rev=1057035&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/TooManyAutobuildConstructorsBean.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/TooManyAutobuildConstructorsBean.java Sun Jan  9 21:34:53 2011
@@ -0,0 +1,53 @@
+// 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 javax.inject.Inject;
+
+
+public class TooManyAutobuildConstructorsBean
+{
+    private final String foo;
+    private final Runnable bar;
+
+    public TooManyAutobuildConstructorsBean()
+    {
+        this(null);
+    }
+
+    @Inject
+    public TooManyAutobuildConstructorsBean(String foo)
+    {
+        this(foo, null);
+    }
+
+    @javax.inject.Inject
+    public TooManyAutobuildConstructorsBean(String foo, Runnable bar)
+    {
+
+        this.foo = foo;
+        this.bar = bar;
+    }
+
+    public String getFoo()
+    {
+        return foo;
+    }
+
+    public Runnable getBar()
+    {
+        return bar;
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/TooManyAutobuildConstructorsBean.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/TooManyAutobuildConstructorsBean.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message