Return-Path: Delivered-To: apmail-tapestry-dev-archive@www.apache.org Received: (qmail 54409 invoked from network); 9 Jan 2011 21:35:25 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 9 Jan 2011 21:35:25 -0000 Received: (qmail 87838 invoked by uid 500); 9 Jan 2011 21:35:25 -0000 Delivered-To: apmail-tapestry-dev-archive@tapestry.apache.org Received: (qmail 87810 invoked by uid 500); 9 Jan 2011 21:35:25 -0000 Mailing-List: contact commits-help@tapestry.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@tapestry.apache.org Delivered-To: mailing list commits@tapestry.apache.org Received: (qmail 87803 invoked by uid 99); 9 Jan 2011 21:35:25 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 09 Jan 2011 21:35:25 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 09 Jan 2011 21:35:18 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 27A302388A2C; Sun, 9 Jan 2011 21:34:55 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commits@tapestry.apache.org From: drobiazko@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110109213455.27A302388A2C@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 fields = transformation.matchFields(new Predicate() + { + + 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. *

* 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 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 matchFields(final ClassTransformation transformation) + { + Predicate predicate = new Predicate() + { + 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 void train_getAnnotation(TransformField field, Class 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(""); + + // is a test for an anonymous @Inject and + // ComponentResourcesInjectionProvider + assertTextPresent("ComponentResources[AtInjectDemo]"); + + // Another test, DefaultInjectionProvider + assertTextPresent(""); + + 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 @@ + +

Demonstrates the use of the @javax.inject.Inject annotation.

+

WebRequest: ${request}

+

ComponentResources: ${resources}

+

BindingSource: ${bindingSource}

+

Injected Symbol: ${injectedSymbol}

+

Injection via Marker: ${greeting}

+

Injection via @Named: ${musicLibrary.tracks.size()} tracks in music library

+ 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 @@ - - 4.0.0 - org.apache.tapestry - tapestry-ioc - jar - - - org.apache.tapestry - tapestry-project - 5.3.0-SNAPSHOT - - Tapestry Inversion of Control Container - + + 4.0.0 + org.apache.tapestry + tapestry-ioc + jar + + + org.apache.tapestry + tapestry-project + 5.3.0-SNAPSHOT + + Tapestry Inversion of Control Container + A code-centric, high-performance, simple Inversion of Control container. - 2006 + 2006 - - - org.apache.tapestry - tapestry5-annotations - ${project.version} - - - - org.apache.tapestry - tapestry-func - ${project.version} - - - - javassist - javassist - 3.12.1.GA - - - - org.slf4j - slf4j-api - 1.6.1 - - - - - log4j - log4j - 1.2.14 - - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - - - - - - org.easymock - easymock - provided - - - - org.testng - testng - - ${testng-version} - provided - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - org.apache.maven.plugins - maven-source-plugin - - - org.apache.maven.plugins - maven-assembly-plugin - - - - org.codehaus.mojo - cobertura-maven-plugin - ${cobertura-plugin-version} - - - clean - - clean - - - - - - - - - - org.apache.maven.plugins - maven-project-info-reports-plugin - - - - summary - dependencies - - - - - - org.codehaus.mojo - cobertura-maven-plugin - ${cobertura-plugin-version} - - - org.codehaus.mojo - clirr-maven-plugin - - 5.1.0.5 - - **/internal/** - **/test/** - - - - - - - - - jboss - https://repository.jboss.org/nexus/content/repositories/releases - - + + + org.apache.tapestry + tapestry5-annotations + ${project.version} + + + + org.apache.tapestry + tapestry-func + ${project.version} + + + + javassist + javassist + 3.12.1.GA + + + + org.slf4j + slf4j-api + 1.6.1 + + + + javax.inject + javax.inject + 1 + + + + + log4j + log4j + 1.2.14 + + + + + org.slf4j + slf4j-log4j12 + 1.6.1 + + + + + + org.easymock + easymock + provided + + + + org.testng + testng + + ${testng-version} + provided + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-assembly-plugin + + + + org.codehaus.mojo + cobertura-maven-plugin + ${cobertura-plugin-version} + + + clean + + clean + + + + + + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + + + summary + dependencies + + + + + + org.codehaus.mojo + cobertura-maven-plugin + ${cobertura-plugin-version} + + + org.codehaus.mojo + clirr-maven-plugin + + 5.1.0.5 + + **/internal/** + **/test/** + + + + + + + + + jboss + https://repository.jboss.org/nexus/content/repositories/releases + + 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 Constructor findConstructorByAnnotation(Constructor[] constructors, Class 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 configuration, + @Named("zip.Zap") + UpcaseService service) + { + configuration.add(service); + } + public void contributeOrderedParameter(OrderedConfiguration configuration, @InjectService("zip.Zap") UpcaseService service) @@ -199,6 +285,13 @@ public class ContributionDefImplTest ext configuration.add("fred", service); } + public void contributeOrderedParameterNamedServiceLookup(OrderedConfiguration configuration, + @Named("zip.Zap") + UpcaseService service) + { + configuration.add("fred", service); + } + public void contributeMappedParameter(MappedConfiguration configuration, @InjectService("zip.Zap") UpcaseService service) @@ -206,6 +299,13 @@ public class ContributionDefImplTest ext configuration.add("upcase", service); } + public void contributeMappedParameterNamedServiceLookup(MappedConfiguration 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