You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2007/10/09 17:22:37 UTC

svn commit: r583192 [3/4] - in /tapestry/tapestry5/trunk: tapestry-core/src/main/java/org/apache/tapestry/ tapestry-core/src/main/java/org/apache/tapestry/annotations/ tapestry-core/src/main/java/org/apache/tapestry/corelib/base/ tapestry-core/src/main...

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/test/PageTesterSessionTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/test/PageTesterSessionTest.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/test/PageTesterSessionTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/test/PageTesterSessionTest.java Tue Oct  9 08:22:27 2007
@@ -14,13 +14,12 @@
 
 package org.apache.tapestry.internal.test;
 
-import java.util.Arrays;
-import java.util.Collections;
-
-import org.apache.tapestry.internal.test.PageTesterSession;
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
 
 public class PageTesterSessionTest extends Assert
 {

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/AbstractFoo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/AbstractFoo.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/AbstractFoo.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/AbstractFoo.java Tue Oct  9 08:22:27 2007
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.internal.transform.pages;
 
-import org.apache.tapestry.internal.services.FooInterface;
+import org.apache.tapestry.internal.services.FooInterface;
 
 /**
  * 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/BarImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/BarImpl.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/BarImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/BarImpl.java Tue Oct  9 08:22:27 2007
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.internal.transform.pages;
 
-import org.apache.tapestry.internal.services.BarInterface;
+import org.apache.tapestry.internal.services.BarInterface;
 
 /**
  * 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/FooImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/FooImpl.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/FooImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/FooImpl.java Tue Oct  9 08:22:27 2007
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.internal.transform.pages;
 
-import org.apache.tapestry.internal.services.FooInterface;
+import org.apache.tapestry.internal.services.FooInterface;
 
 /**
  * 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/util/Base64Tests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/util/Base64Tests.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/util/Base64Tests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/util/Base64Tests.java Tue Oct  9 08:22:27 2007
@@ -15,15 +15,15 @@
 package org.apache.tapestry.internal.util;
 
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
-
-import java.io.EOFException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.Map;
-
-import org.testng.Assert;
-import org.testng.annotations.Test;
+
+import java.io.EOFException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Map;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
 
 /**
  * Tests for {@link Base64InputStream} and {@link Base64OutputStream}, etc.

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/util/ContentTypeTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/util/ContentTypeTest.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/util/ContentTypeTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/util/ContentTypeTest.java Tue Oct  9 08:22:27 2007
@@ -16,7 +16,6 @@
 
 import java.util.List;
 
-import org.apache.tapestry.internal.util.ContentType;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/util/MethodInvocationBuilderTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/util/MethodInvocationBuilderTest.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/util/MethodInvocationBuilderTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/util/MethodInvocationBuilderTest.java Tue Oct  9 08:22:27 2007
@@ -14,14 +14,13 @@
 
 package org.apache.tapestry.internal.util;
 
-import java.lang.reflect.Modifier;
-
-import org.apache.tapestry.MarkupWriter;
-import org.apache.tapestry.internal.util.MethodInvocationBuilder;
-import org.apache.tapestry.services.ClassTransformation;
-import org.apache.tapestry.services.TransformMethodSignature;
-import org.apache.tapestry.test.TapestryTestCase;
-import org.testng.annotations.Test;
+import java.lang.reflect.Modifier;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.TransformMethodSignature;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
 
 public class MethodInvocationBuilderTest extends TapestryTestCase
 {

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/services/SyncCostBench.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/services/SyncCostBench.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/services/SyncCostBench.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/services/SyncCostBench.java Tue Oct  9 08:22:27 2007
@@ -14,12 +14,12 @@
 
 package org.apache.tapestry.services;
 
-import static java.lang.String.format;
-import static java.lang.System.out;
-
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
+import static java.lang.String.format;
+import static java.lang.System.out;
+
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
 import org.apache.tapestry.ioc.internal.util.ConcurrentBarrier;
 
 /**

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/services/TransformUtilsTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/services/TransformUtilsTest.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/services/TransformUtilsTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/services/TransformUtilsTest.java Tue Oct  9 08:22:27 2007
@@ -14,16 +14,16 @@
 
 package org.apache.tapestry.services;
 
-import static org.apache.tapestry.services.TransformUtils.getDefaultValue;
-import static org.apache.tapestry.services.TransformUtils.getUnwrapperMethodName;
-import static org.apache.tapestry.services.TransformUtils.getWrapperType;
-import static org.apache.tapestry.services.TransformUtils.getWrapperTypeName;
-import static org.apache.tapestry.services.TransformUtils.isPrimitive;
-
-import java.util.Map;
-
-import org.testng.Assert;
-import org.testng.annotations.Test;
+import static org.apache.tapestry.services.TransformUtils.getDefaultValue;
+import static org.apache.tapestry.services.TransformUtils.getUnwrapperMethodName;
+import static org.apache.tapestry.services.TransformUtils.getWrapperType;
+import static org.apache.tapestry.services.TransformUtils.getWrapperTypeName;
+import static org.apache.tapestry.services.TransformUtils.isPrimitive;
+
+import java.util.Map;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
 
 /**
  * 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/util/DefaultPrimaryKeyEncoderTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/util/DefaultPrimaryKeyEncoderTest.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/util/DefaultPrimaryKeyEncoderTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/util/DefaultPrimaryKeyEncoderTest.java Tue Oct  9 08:22:27 2007
@@ -17,7 +17,6 @@
 import java.util.Arrays;
 
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
-import org.apache.tapestry.util.DefaultPrimaryKeyEncoder;
 import org.testng.annotations.Test;
 
 public class DefaultPrimaryKeyEncoderTest extends InternalBaseTestCase

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/util/FindTheParameterizedType.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/util/FindTheParameterizedType.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/util/FindTheParameterizedType.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/util/FindTheParameterizedType.java Tue Oct  9 08:22:27 2007
@@ -14,14 +14,14 @@
 
 package org.apache.tapestry.util;
 
-import static java.lang.System.out;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.List;
-import java.util.Map;
-
+import static java.lang.System.out;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.tapestry.ioc.internal.util.Orderer;
 
 public class FindTheParameterizedType

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/util/StringToEnumCoercionTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/util/StringToEnumCoercionTest.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/util/StringToEnumCoercionTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/util/StringToEnumCoercionTest.java Tue Oct  9 08:22:27 2007
@@ -17,7 +17,6 @@
 import junit.framework.AssertionFailedError;
 
 import org.apache.tapestry.Stooge;
-import org.apache.tapestry.util.StringToEnumCoercion;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectDemo.tml?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectDemo.tml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectDemo.tml Tue Oct  9 08:22:27 2007
@@ -4,6 +4,7 @@
     <p>ComponentResources: ${resources}</p>
     <p>BindingSource: ${bindingSource}</p>
     <p>Injected Symbol: ${injectedSymbol}</p>
+    <p>Injection via Marker: ${greeting}</p>
     
     
     <p>

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBindingOptions.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBindingOptions.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBindingOptions.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBindingOptions.java Tue Oct  9 08:22:27 2007
@@ -14,6 +14,8 @@
 
 package org.apache.tapestry.ioc;
 
+import java.lang.annotation.Annotation;
+
 import org.apache.tapestry.ioc.annotations.EagerLoad;
 import org.apache.tapestry.ioc.annotations.Scope;
 import org.apache.tapestry.ioc.def.ServiceDef;
@@ -52,4 +54,6 @@
      * @return this binding options, for further configuration
      */
     ServiceBindingOptions eagerLoad();
+
+    <T extends Annotation> ServiceBindingOptions withMarker(Class<T> marker);
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Inject.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Inject.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Inject.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Inject.java Tue Oct  9 08:22:27 2007
@@ -14,6 +14,7 @@
 
 package org.apache.tapestry.ioc.annotations;
 
+import static java.lang.annotation.ElementType.FIELD;
 import static java.lang.annotation.ElementType.PARAMETER;
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
@@ -24,13 +25,24 @@
 import org.apache.tapestry.ioc.ObjectProvider;
 
 /**
- * Normally, resources take precedence over annotations when injecting. The Inject annotation
- * overrides this default, forcing the resolution of the parameters value via the master
- * {@link ObjectProvider}, even when the parameter's type matches a type that is normally a
- * resource. This is most often used in conjunction with {@link Value} annotation when injecting a
- * string, as normally, the String would be matched as the service id.
+ * This annotation serves two similar purposes: it marks parameters that should be injected in the
+ * IoC container, and it marks fields that should be injected inside Tapestry components.
+ * <p>
+ * In terms of the IoC container; normally, resources take precedence over annotations when
+ * injecting. The Inject annotation overrides this default, forcing the resolution of the parameters
+ * value via the master {@link ObjectProvider}, even when the parameter's type matches a type that
+ * is normally a resource. This is most often used in conjunction with {@link Value} annotation when
+ * injecting a string, as normally, the String would be matched as the service id.
+ * <p>
+ * In terms of the IoC container, the Inject annotation is only used on parameters to service
+ * builder methods and constructors. However, inside Tapestry components (<em>and only inside components</em>),
+ * it may be applied to fields. On fields that require injection, the Inject annotation is
+ * <em>required</em>.
+ * 
+ * @see ObjectProvider
  */
-@Target(PARAMETER)
+@Target(
+{ PARAMETER, FIELD })
 @Retention(RUNTIME)
 @Documented
 public @interface Inject

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/InjectService.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/InjectService.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/InjectService.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/InjectService.java Tue Oct  9 08:22:27 2007
@@ -14,12 +14,12 @@
 
 package org.apache.tapestry.ioc.annotations;
 
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
 
 @Target(PARAMETER)
 @Retention(RUNTIME)

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Marker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Marker.java?rev=583192&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Marker.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Marker.java Tue Oct  9 08:22:27 2007
@@ -0,0 +1,41 @@
+// Copyright 2007 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.tapestry.ioc.annotations;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import org.apache.tapestry.ioc.def.ServiceDef;
+
+/**
+ * Used to define a {@linkplain ServiceDef#getMarker() marker annotation} for a service
+ * implementation. This allows for injection based on the combination of type and marker interface.
+ * These marker interfaces should not have any values. The mere presence of the marker annotation is
+ * all that is needed.
+ */
+@Target(
+{ TYPE, METHOD })
+@Retention(RUNTIME)
+@Documented
+public @interface Marker
+{
+    /** The type of annotation (which will be present at the injection point). */
+    Class value();
+}

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Match.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Match.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Match.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Match.java Tue Oct  9 08:22:27 2007
@@ -14,12 +14,12 @@
 
 package org.apache.tapestry.ioc.annotations;
 
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
 
 /**
  * Optional, but typically used, annotation for service decorator methods, used to define which

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Order.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Order.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Order.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Order.java Tue Oct  9 08:22:27 2007
@@ -14,12 +14,12 @@
 
 package org.apache.tapestry.ioc.annotations;
 
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
 
 /**
  * Used with a service decorator method to control the order in which decorations occur. Identifies

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/SubModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/SubModule.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/SubModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/SubModule.java Tue Oct  9 08:22:27 2007
@@ -14,12 +14,12 @@
 
 package org.apache.tapestry.ioc.annotations;
 
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
 
 /**
  * Attached to a module class, this annotation identifies other module classes that should also be

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java Tue Oct  9 08:22:27 2007
@@ -17,8 +17,8 @@
 import org.apache.tapestry.ioc.Configuration;
 import org.apache.tapestry.ioc.MappedConfiguration;
 import org.apache.tapestry.ioc.ModuleBuilderSource;
-import org.apache.tapestry.ioc.OrderedConfiguration;
 import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.OrderedConfiguration;
 
 /**
  * Contribution to a service configuration.

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ServiceDef.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ServiceDef.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ServiceDef.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ServiceDef.java Tue Oct  9 08:22:27 2007
@@ -14,6 +14,7 @@
 
 package org.apache.tapestry.ioc.def;
 
+
 import org.apache.tapestry.ioc.ObjectCreator;
 import org.apache.tapestry.ioc.ServiceBuilderResources;
 
@@ -31,10 +32,25 @@
      */
     ObjectCreator createServiceCreator(ServiceBuilderResources resources);
 
-    /** Returns the service id, derived from the method name. */
+    /**
+     * Returns the service id, derived from the method name or the unqualified service interface
+     * name. Service ids must be unique among <em>all</em> services in all modules. Service ids
+     * are used in a heavy handed way to support ultimate disambiguation, but their primary purpose
+     * is to support service contribution methods.
+     */
     String getServiceId();
 
     /**
+     * Returns an optional <em>marker annotation</em>. Marker annotations are used to
+     * disambiguate services; the combination of a marker annotation and a service type is expected
+     * to be unique. The annotation is placed on the field or method/constructor parameter and the
+     * service is located by combining the marker with service type (the parameter or field type).
+     * 
+     * @return the annotation, or null if the service has no annotation
+     */
+    Class getMarker();
+
+    /**
      * Returns the service interface associated with this service. This is the interface exposed to
      * the outside world, as well as the one used to build proxies. In cases where the service is
      * <em>not</em> defined in terms of an interface, this will return the actual implementation
@@ -47,7 +63,7 @@
      * {@link org.apache.tapestry.ioc.annotations.Scope} annotation to the service builder method
      * for the service.
      * <p>
-     * Services that are not proxied will ignore thier scope; such services are always treated as
+     * Services that are not proxied will ignore their scope; such services are always treated as
      * singletons.
      */
     String getServiceScope();

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ContributionDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ContributionDefImpl.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ContributionDefImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ContributionDefImpl.java Tue Oct  9 08:22:27 2007
@@ -23,8 +23,8 @@
 import org.apache.tapestry.ioc.Configuration;
 import org.apache.tapestry.ioc.MappedConfiguration;
 import org.apache.tapestry.ioc.ModuleBuilderSource;
-import org.apache.tapestry.ioc.OrderedConfiguration;
 import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.OrderedConfiguration;
 import org.apache.tapestry.ioc.def.ContributionDef;
 import org.apache.tapestry.ioc.internal.util.InternalUtils;
 import org.apache.tapestry.ioc.services.ClassFactory;

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java Tue Oct  9 08:22:27 2007
@@ -40,9 +40,10 @@
 import org.apache.tapestry.ioc.ServiceBinder;
 import org.apache.tapestry.ioc.ServiceBuilderResources;
 import org.apache.tapestry.ioc.annotations.EagerLoad;
-import org.apache.tapestry.ioc.annotations.Scope;
+import org.apache.tapestry.ioc.annotations.Marker;
 import org.apache.tapestry.ioc.annotations.Match;
 import org.apache.tapestry.ioc.annotations.Order;
+import org.apache.tapestry.ioc.annotations.Scope;
 import org.apache.tapestry.ioc.def.ContributionDef;
 import org.apache.tapestry.ioc.def.DecoratorDef;
 import org.apache.tapestry.ioc.def.ModuleDef;
@@ -312,10 +313,19 @@
             }
         };
 
-        ServiceDefImpl serviceDef = new ServiceDefImpl(returnType, serviceId, scope, eagerLoad,
-                source);
+        Class marker = extractMarker(method);
+
+        ServiceDefImpl serviceDef = new ServiceDefImpl(returnType, serviceId, marker, scope,
+                eagerLoad, source);
 
         addServiceDef(serviceDef);
+    }
+
+    private Class extractMarker(Method method)
+    {
+        Marker annotation = method.getAnnotation(Marker.class);
+
+        return annotation == null ? null : annotation.value();
     }
 
     public void addServiceDef(ServiceDef serviceDef)

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCMessages.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCMessages.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCMessages.java Tue Oct  9 08:22:27 2007
@@ -29,6 +29,7 @@
 import org.apache.tapestry.ioc.def.ServiceDef;
 import org.apache.tapestry.ioc.internal.util.InternalUtils;
 import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
 
 final class IOCMessages
 {
@@ -303,5 +304,19 @@
     static String autobuildConstructorError(String constructorDescription, Throwable cause)
     {
         return MESSAGES.format("autobuild-constructor-error", constructorDescription, cause);
+    }
+
+    static String noServicesMatchMarker(Class objectType, Class marker)
+    {
+        return MESSAGES.format("no-services-match-marker", ClassFabUtils
+                .toJavaClassName(objectType), ClassFabUtils.toJavaClassName(marker));
+    }
+
+    static String manyServicesMatchMarker(Class objectType, Class marker,
+            Collection<ServiceDef> matchingServices)
+    {
+        return MESSAGES.format("many-services-match-marker", ClassFabUtils
+                .toJavaClassName(objectType), ClassFabUtils.toJavaClassName(marker), InternalUtils
+                .joinSorted(matchingServices));
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java Tue Oct  9 08:22:27 2007
@@ -74,6 +74,9 @@
     // the constructor. Guarded by MUTEX.
     private boolean _insideConstructor;
 
+    /** Keyed on fully qualified service id; values are instantiated services (proxies). */
+    private final Map<String, Object> _services = newCaseInsensitiveMap();
+
     public ModuleImpl(InternalRegistry registry, ModuleDef moduleDef, ClassFactory classFactory,
             Logger logger)
     {
@@ -82,9 +85,6 @@
         _classFactory = classFactory;
         _logger = logger;
     }
-
-    /** Keyed on fully qualified service id; values are instantiated services (proxies). */
-    private final Map<String, Object> _services = newCaseInsensitiveMap();
 
     public <T> T getService(String serviceId, Class<T> serviceInterface)
     {

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/OrIdMatcher.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/OrIdMatcher.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/OrIdMatcher.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/OrIdMatcher.java Tue Oct  9 08:22:27 2007
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.ioc.internal;
 
-import java.util.Collection;
+import java.util.Collection;
 
 import org.apache.tapestry.ioc.IdMatcher;
 

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java Tue Oct  9 08:22:27 2007
@@ -33,6 +33,7 @@
 import org.apache.tapestry.ioc.LoggerSource;
 import org.apache.tapestry.ioc.MappedConfiguration;
 import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
 import org.apache.tapestry.ioc.OrderedConfiguration;
 import org.apache.tapestry.ioc.Registry;
 import org.apache.tapestry.ioc.ServiceDecorator;
@@ -99,6 +100,11 @@
 
     private final List<Module> _modules = newList();
 
+    /**
+     * From marker type to a list of marked service instances.
+     */
+    private final Map<Class, List<ServiceDef>> _markerToServiceDef = newMap();
+
     public static final class OrderedConfigurationToOrdererAdaptor<T> implements
             OrderedConfiguration<T>
     {
@@ -140,13 +146,21 @@
 
             for (String serviceId : def.getServiceIds())
             {
+                ServiceDef serviceDef = module.getServiceDef(serviceId);
+
                 Module existing = _serviceIdToModule.get(serviceId);
 
                 if (existing != null)
                     throw new RuntimeException(IOCMessages.serviceIdConflict(serviceId, existing
-                            .getServiceDef(serviceId), module.getServiceDef(serviceId)));
+                            .getServiceDef(serviceId), serviceDef));
 
                 _serviceIdToModule.put(serviceId, module);
+
+                Class marker = serviceDef.getMarker();
+
+                if (marker != null)
+                    InternalUtils.addToMapList(_markerToServiceDef, marker, serviceDef);
+
             }
         }
 
@@ -210,6 +224,9 @@
     {
         _builtinTypes.put(serviceId, serviceInterface);
         _builtinServices.put(serviceId, service);
+
+        // TODO: Figure out a way to "mark" the builtins with the TapestryIoCModule.Builtin
+        // annotation.
     }
 
     public synchronized void shutdown()
@@ -292,6 +309,7 @@
         return result;
     }
 
+    @SuppressWarnings("unchecked")
     public <T> List<T> getOrderedConfiguration(ServiceDef serviceDef, Class<T> objectType)
     {
         _lock.check();
@@ -308,6 +326,23 @@
         for (Module m : modules)
             addToOrderedConfiguration(configuration, objectType, serviceDef, m);
 
+        // An ugly hack ... perhaps we should introduce a new builtin service so that this can be
+        // accomplished in the normal way?
+
+        if (serviceId.equals("MasterObjectProvider"))
+        {
+            ObjectProvider contribution = new ObjectProvider()
+            {
+                public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider,
+                        ObjectLocator locator)
+                {
+                    return findServiceByMarkerAndType(objectType, annotationProvider);
+                }
+            };
+
+            configuration.add("ServiceByMarker", (T) contribution);
+        }
+
         return orderer.getOrdered();
     }
 
@@ -543,16 +578,75 @@
     {
         _lock.check();
 
+        AnnotationProvider effectiveProvider = annotationProvider != null ? annotationProvider
+                : new NullAnnotationProvider();
+
+        // We do a check here for known marker/type combinations, so that you can use a marker
+        // annotation
+        // to inject into a contribution method that contributes to MasterObjectProvider.
+        // We also force a contribution into MasterObjectProvider to accomplish the same thing.
+
+        T result = findServiceByMarkerAndType(objectType, annotationProvider);
+
+        if (result != null) return result;
+
         MasterObjectProvider masterProvider = getService(
                 IOCConstants.MASTER_OBJECT_PROVIDER_SERVICE_ID,
                 MasterObjectProvider.class);
 
-        AnnotationProvider effectiveProvider = annotationProvider != null ? annotationProvider
-                : new NullAnnotationProvider();
-
         return masterProvider.provide(objectType, effectiveProvider, locator, true);
     }
 
+    @SuppressWarnings("unchecked")
+    private <T> T findServiceByMarkerAndType(Class<T> objectType, AnnotationProvider provider)
+    {
+        if (provider == null) return null;
+
+        for (Class marker : _markerToServiceDef.keySet())
+        {
+            if (provider.getAnnotation(marker) == null) continue;
+
+            List<ServiceDef> matches = newList();
+
+            for (ServiceDef def : _markerToServiceDef.get(marker))
+            {
+                if (objectType.isAssignableFrom(def.getServiceInterface())) matches.add(def);
+            }
+
+            switch (matches.size())
+            {
+
+                case 1:
+
+                    ServiceDef def = matches.get(0);
+
+                    return getService(def.getServiceId(), objectType);
+
+                case 0:
+
+                    // It's no accident that the user put the marker annotation at the injection
+                    // point, since it matches a known marker annotation, it better be there for
+                    // a reason. So if we don't get a match, we have to assume the user expected
+                    // one, and that is an error.
+
+                    // This doesn't help when the user places an annotation they *think* is a marker
+                    // but isn't really a marker (because no service is marked by the annotation).
+
+                    throw new RuntimeException(IOCMessages
+                            .noServicesMatchMarker(objectType, marker));
+
+                default:
+                    throw new RuntimeException(IOCMessages.manyServicesMatchMarker(
+                            objectType,
+                            marker,
+                            matches));
+            }
+
+        }
+
+        return null;
+    }
+
     public <T> T getObject(Class<T> objectType, AnnotationProvider annotationProvider)
     {
         _lock.check();
@@ -624,7 +718,6 @@
 
         throw new RuntimeException(IOCMessages.autobuildConstructorError(description, failure),
                 failure);
-
     }
 
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryWrapper.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryWrapper.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryWrapper.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryWrapper.java Tue Oct  9 08:22:27 2007
@@ -15,8 +15,8 @@
 package org.apache.tapestry.ioc.internal;
 
 import org.apache.tapestry.ioc.AnnotationProvider;
-import org.apache.tapestry.ioc.Registry;
 import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.Registry;
 
 /**
  * A wrapper around {@link InternalRegistry} that exists to expand symbols in a service id before

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBinderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBinderImpl.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBinderImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBinderImpl.java Tue Oct  9 08:22:27 2007
@@ -17,6 +17,7 @@
 import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
 import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 
 import org.apache.tapestry.ioc.IOCConstants;
@@ -25,6 +26,7 @@
 import org.apache.tapestry.ioc.ServiceBindingOptions;
 import org.apache.tapestry.ioc.ServiceBuilderResources;
 import org.apache.tapestry.ioc.annotations.EagerLoad;
+import org.apache.tapestry.ioc.annotations.Marker;
 import org.apache.tapestry.ioc.annotations.Scope;
 import org.apache.tapestry.ioc.def.ServiceDef;
 import org.apache.tapestry.ioc.internal.util.InternalUtils;
@@ -49,6 +51,8 @@
 
     private Class _serviceInterface;
 
+    private Class _marker;
+
     private Class _serviceImplementation;
 
     private boolean _eagerLoad;
@@ -81,13 +85,14 @@
             }
         };
 
-        ServiceDef serviceDef = new ServiceDefImpl(_serviceInterface, _serviceId, _scope,
+        ServiceDef serviceDef = new ServiceDefImpl(_serviceInterface, _serviceId, _marker, _scope,
                 _eagerLoad, source);
 
         _accumulator.addServiceDef(serviceDef);
 
         _serviceId = null;
         _serviceInterface = null;
+        _marker = null;
         _serviceImplementation = null;
         _eagerLoad = false;
         _scope = null;
@@ -131,6 +136,10 @@
 
         _scope = scope != null ? scope.value() : IOCConstants.DEFAULT_SCOPE;
 
+        Marker marker = serviceImplementation.getAnnotation(Marker.class);
+
+        _marker = marker != null ? marker.value() : null;
+
         return this;
     }
 
@@ -161,6 +170,17 @@
         _lock.check();
 
         _scope = scope;
+
+        return this;
+    }
+
+    public <T extends Annotation> ServiceBindingOptions withMarker(Class<T> marker)
+    {
+        notNull(marker, "marker");
+
+        _lock.check();
+
+        _marker = marker;
 
         return this;
     }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefImpl.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefImpl.java Tue Oct  9 08:22:27 2007
@@ -14,6 +14,7 @@
 
 package org.apache.tapestry.ioc.internal;
 
+
 import org.apache.tapestry.ioc.ObjectCreator;
 import org.apache.tapestry.ioc.ServiceBuilderResources;
 import org.apache.tapestry.ioc.def.ServiceDef;
@@ -30,11 +31,14 @@
 
     private final ObjectCreatorSource _source;
 
-    ServiceDefImpl(Class serviceInterface, String serviceId, String scope, boolean eagerLoad,
-            ObjectCreatorSource source)
+    private Class _marker;
+
+    ServiceDefImpl(Class serviceInterface, String serviceId, Class marker,
+            String scope, boolean eagerLoad, ObjectCreatorSource source)
     {
         _serviceInterface = serviceInterface;
         _serviceId = serviceId;
+        _marker = marker;
         _scope = scope;
         _eagerLoad = eagerLoad;
         _source = source;
@@ -69,6 +73,11 @@
     public boolean isEagerLoad()
     {
         return _eagerLoad;
+    }
+
+    public Class getMarker()
+    {
+        return _marker;
     }
 
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SingletonServiceLifecycle.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SingletonServiceLifecycle.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SingletonServiceLifecycle.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SingletonServiceLifecycle.java Tue Oct  9 08:22:27 2007
@@ -14,9 +14,9 @@
 
 package org.apache.tapestry.ioc.internal;
 
-import org.apache.tapestry.ioc.ObjectCreator;
-import org.apache.tapestry.ioc.ServiceLifecycle;
-import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.ServiceLifecycle;
+import org.apache.tapestry.ioc.ServiceResources;
 
 /**
  * The basic implementation of a service lifecycle, which simply uses the

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryClassPool.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryClassPool.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryClassPool.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryClassPool.java Tue Oct  9 08:22:27 2007
@@ -14,19 +14,19 @@
 
 package org.apache.tapestry.ioc.internal.services;
 
-import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newSet;
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newSet;
 
-import java.util.Set;
 import java.util.Map;
-
-import org.apache.tapestry.ioc.services.ClassFabUtils;
+import java.util.Set;
 
 import javassist.ClassPath;
 import javassist.ClassPool;
 import javassist.CtClass;
 import javassist.LoaderClassPath;
 import javassist.NotFoundException;
+
+import org.apache.tapestry.ioc.services.ClassFabUtils;
 
 /**
  * Used to ensure that {@link javassist.ClassPool#appendClassPath(javassist.ClassPath)} is invoked

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionAnalysisImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionAnalysisImpl.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionAnalysisImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionAnalysisImpl.java Tue Oct  9 08:22:27 2007
@@ -14,12 +14,12 @@
 
 package org.apache.tapestry.ioc.internal.services;
 
-import static java.util.Collections.unmodifiableList;
-
-import java.util.List;
-
-import org.apache.tapestry.ioc.services.ExceptionAnalysis;
-import org.apache.tapestry.ioc.services.ExceptionInfo;
+import static java.util.Collections.unmodifiableList;
+
+import java.util.List;
+
+import org.apache.tapestry.ioc.services.ExceptionAnalysis;
+import org.apache.tapestry.ioc.services.ExceptionInfo;
 
 /**
  * 

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PerThreadServiceCreator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PerThreadServiceCreator.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PerThreadServiceCreator.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PerThreadServiceCreator.java Tue Oct  9 08:22:27 2007
@@ -17,9 +17,9 @@
  */
 package org.apache.tapestry.ioc.internal.services;
 
-import org.apache.tapestry.ioc.ObjectCreator;
-import org.apache.tapestry.ioc.services.ThreadCleanupHub;
-import org.apache.tapestry.ioc.services.ThreadCleanupListener;
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.services.ThreadCleanupHub;
+import org.apache.tapestry.ioc.services.ThreadCleanupListener;
 
 /**
  * Provides per-thread implementations of services, along with end-of-request thread cleanup.

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImpl.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImpl.java Tue Oct  9 08:22:27 2007
@@ -14,9 +14,9 @@
 
 package org.apache.tapestry.ioc.internal.services;
 
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newConcurrentMap;
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newLinkedList;
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
-import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newConcurrentMap;
 
 import java.beans.BeanInfo;
 import java.beans.IntrospectionException;

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/SymbolSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/SymbolSourceImpl.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/SymbolSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/SymbolSourceImpl.java Tue Oct  9 08:22:27 2007
@@ -14,8 +14,8 @@
 
 package org.apache.tapestry.ioc.internal.services;
 
-import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newLinkedList;
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newConcurrentMap;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newLinkedList;
 
 import java.util.LinkedList;
 import java.util.List;

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/TypeCoercerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/TypeCoercerImpl.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/TypeCoercerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/TypeCoercerImpl.java Tue Oct  9 08:22:27 2007
@@ -14,11 +14,11 @@
 
 package org.apache.tapestry.ioc.internal.services;
 
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newConcurrentMap;
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newLinkedList;
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newSet;
-import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newConcurrentMap;
 import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
 
 import java.util.Collection;
@@ -103,23 +103,8 @@
         {
             Class key = tuple.getSourceType();
 
-            addTuple(key, tuple);
+            InternalUtils.addToMapList(_sourceTypeToTuple, key, tuple);
         }
-    }
-
-    @SuppressWarnings(
-    { "unchecked", "unchecked" })
-    private void addTuple(Class key, CoercionTuple tuple)
-    {
-        List<CoercionTuple> list = _sourceTypeToTuple.get(key);
-
-        if (list == null)
-        {
-            list = newList();
-            _sourceTypeToTuple.put(key, list);
-        }
-
-        list.add(tuple);
     }
 
     @SuppressWarnings("unchecked")

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ValueObjectProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ValueObjectProvider.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ValueObjectProvider.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ValueObjectProvider.java Tue Oct  9 08:22:27 2007
@@ -15,8 +15,8 @@
 package org.apache.tapestry.ioc.internal.services;
 
 import org.apache.tapestry.ioc.AnnotationProvider;
-import org.apache.tapestry.ioc.ObjectProvider;
 import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
 import org.apache.tapestry.ioc.annotations.InjectService;
 import org.apache.tapestry.ioc.annotations.Value;
 import org.apache.tapestry.ioc.services.SymbolSource;

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/ConcurrentBarrier.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/ConcurrentBarrier.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/ConcurrentBarrier.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/ConcurrentBarrier.java Tue Oct  9 08:22:27 2007
@@ -14,9 +14,9 @@
 
 package org.apache.tapestry.ioc.internal.util;
 
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.concurrent.TimeUnit;
 
 /**
  * A barrier used to execute code in a context where it is guarded by read/write locks. In addition,

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/IdAllocator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/IdAllocator.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/IdAllocator.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/IdAllocator.java Tue Oct  9 08:22:27 2007
@@ -15,11 +15,11 @@
 package org.apache.tapestry.ioc.internal.util;
 
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
-
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
+
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
 
 
 /**

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java Tue Oct  9 08:22:27 2007
@@ -463,4 +463,32 @@
 
         return constructors[0];
     }
+
+    /**
+     * Adds a value to a specially organized map where the values are lists of objects. This
+     * somewhat simulates a map that allows mutiple values for the same key.
+     * @param map
+     *            to store value into
+     * @param key
+     *            for which a value is added
+     * @param value
+     *            to add
+     * 
+     * @param <K>
+     *            the type of key
+     * @param <V>
+     *            the type of the list
+     */
+    public static <K, V> void addToMapList(Map<K, List<V>> map, K key, V value)
+    {
+        List<V> list = map.get(key);
+
+        if (list == null)
+        {
+            list = newList();
+            map.put(key, list);
+        }
+
+        list.add(value);
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ChainBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ChainBuilder.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ChainBuilder.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ChainBuilder.java Tue Oct  9 08:22:27 2007
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.ioc.services;
 
-import java.util.List;
+import java.util.List;
 
 /**
  * A service which can assemble an implementation based on a command interface, and an ordered list

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionAnalysis.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionAnalysis.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionAnalysis.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionAnalysis.java Tue Oct  9 08:22:27 2007
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.ioc.services;
 
-import java.util.List;
+import java.util.List;
 
 /**
  * An analysis of an exception (including nested exceptions).

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionInfo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionInfo.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionInfo.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionInfo.java Tue Oct  9 08:22:27 2007
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.ioc.services;
 
-import java.util.List;
+import java.util.List;
 
 /**
  * Contains information about an analyzed exception.

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/RegistryShutdownListener.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/RegistryShutdownListener.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/RegistryShutdownListener.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/RegistryShutdownListener.java Tue Oct  9 08:22:27 2007
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.ioc.services;
 
-import java.util.EventListener;
+import java.util.EventListener;
 
 /**
  * Event listener interfaces for objects that need to know when the Registry shutsdown.

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceLifecycleSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceLifecycleSource.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceLifecycleSource.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceLifecycleSource.java Tue Oct  9 08:22:27 2007
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.ioc.services;
 
-import org.apache.tapestry.ioc.ServiceLifecycle;
+import org.apache.tapestry.ioc.ServiceLifecycle;
 
 /**
  * Provides access to user defined lifecycles (beyond the two built-in lifecycles: "singleton" and

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java Tue Oct  9 08:22:27 2007
@@ -14,8 +14,14 @@
 
 package org.apache.tapestry.ioc.services;
 
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
 import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
 
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
 import java.lang.reflect.Array;
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -33,6 +39,7 @@
 import org.apache.tapestry.ioc.ServiceBinder;
 import org.apache.tapestry.ioc.ServiceLifecycle;
 import org.apache.tapestry.ioc.annotations.InjectService;
+import org.apache.tapestry.ioc.annotations.Marker;
 import org.apache.tapestry.ioc.annotations.Value;
 import org.apache.tapestry.ioc.internal.services.ChainBuilderImpl;
 import org.apache.tapestry.ioc.internal.services.DefaultImplementationBuilderImpl;
@@ -60,24 +67,46 @@
  */
 public final class TapestryIOCModule
 {
+
+    /**
+     * Marks services provided by this module that may need to be unambiguously referenced.
+     * Injecting with this marker annotation and the correct type ensure that the version defined in
+     * this module is used, even if another module provides a service with the same service
+     * interface.
+     */
+    @Target(
+    { PARAMETER, FIELD })
+    @Retention(RUNTIME)
+    @Documented
+    public @interface Builtin
+    {
+
+    };
+
     public static void bind(ServiceBinder binder)
     {
-        binder.bind(LoggingDecorator.class, LoggingDecoratorImpl.class);
-        binder.bind(ChainBuilder.class, ChainBuilderImpl.class);
-        binder.bind(PropertyAccess.class, PropertyAccessImpl.class);
-        binder.bind(StrategyBuilder.class, StrategyBuilderImpl.class);
-        binder.bind(PropertyShadowBuilder.class, PropertyShadowBuilderImpl.class);
-        binder.bind(PipelineBuilder.class, PipelineBuilderImpl.class);
-        binder.bind(DefaultImplementationBuilder.class, DefaultImplementationBuilderImpl.class);
-        binder.bind(ExceptionTracker.class, ExceptionTrackerImpl.class);
-        binder.bind(ExceptionAnalyzer.class, ExceptionAnalyzerImpl.class);
-        binder.bind(TypeCoercer.class, TypeCoercerImpl.class);
-        binder.bind(ThreadLocale.class, ThreadLocaleImpl.class);
-        binder.bind(SymbolSource.class, SymbolSourceImpl.class);
-        binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("ApplicationDefaults");
-        binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("FactoryDefaults");
-        binder.bind(Runnable.class, RegistryStartup.class).withId("RegistryStartup");
-        binder.bind(MasterObjectProvider.class, MasterObjectProviderImpl.class);
+        binder.bind(LoggingDecorator.class, LoggingDecoratorImpl.class).withMarker(Builtin.class);
+        binder.bind(ChainBuilder.class, ChainBuilderImpl.class).withMarker(Builtin.class);
+        binder.bind(PropertyAccess.class, PropertyAccessImpl.class).withMarker(Builtin.class);
+        binder.bind(StrategyBuilder.class, StrategyBuilderImpl.class).withMarker(Builtin.class);
+        binder.bind(PropertyShadowBuilder.class, PropertyShadowBuilderImpl.class).withMarker(
+                Builtin.class);
+        binder.bind(PipelineBuilder.class, PipelineBuilderImpl.class).withMarker(Builtin.class);
+        binder.bind(DefaultImplementationBuilder.class, DefaultImplementationBuilderImpl.class)
+                .withMarker(Builtin.class);
+        binder.bind(ExceptionTracker.class, ExceptionTrackerImpl.class).withMarker(Builtin.class);
+        binder.bind(ExceptionAnalyzer.class, ExceptionAnalyzerImpl.class).withMarker(Builtin.class);
+        binder.bind(TypeCoercer.class, TypeCoercerImpl.class).withMarker(Builtin.class);
+        binder.bind(ThreadLocale.class, ThreadLocaleImpl.class).withMarker(Builtin.class);
+        binder.bind(SymbolSource.class, SymbolSourceImpl.class).withMarker(Builtin.class);
+        binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("ApplicationDefaults")
+                .withMarker(Builtin.class);
+        binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("FactoryDefaults")
+                .withMarker(Builtin.class);
+        binder.bind(Runnable.class, RegistryStartup.class).withId("RegistryStartup").withMarker(
+                Builtin.class);
+        binder.bind(MasterObjectProvider.class, MasterObjectProviderImpl.class).withMarker(
+                Builtin.class);
     }
 
     /**
@@ -86,6 +115,7 @@
      * proxiable services (those with explicit service interfaces) can be managed in terms of a
      * lifecycle.
      */
+    @Marker(Builtin.class)
     public static ServiceLifecycleSource build(final Map<String, ServiceLifecycle> configuration)
     {
         return new ServiceLifecycleSource()

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java Tue Oct  9 08:22:27 2007
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.ioc.services;
 
-import java.util.EventListener;
+import java.util.EventListener;
 
 /**
  * Listener interface for object that need to know about thread event cleanup.

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java Tue Oct  9 08:22:27 2007
@@ -29,6 +29,7 @@
 import org.apache.tapestry.ioc.MessageFormatter;
 import org.apache.tapestry.ioc.Messages;
 import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.ObjectLocator;
 import org.apache.tapestry.ioc.ObjectProvider;
 import org.apache.tapestry.ioc.OrderedConfiguration;
 import org.apache.tapestry.ioc.Registry;
@@ -36,7 +37,6 @@
 import org.apache.tapestry.ioc.Resource;
 import org.apache.tapestry.ioc.ServiceBuilderResources;
 import org.apache.tapestry.ioc.ServiceDecorator;
-import org.apache.tapestry.ioc.ObjectLocator;
 import org.apache.tapestry.ioc.ServiceResources;
 import org.apache.tapestry.ioc.def.ContributionDef;
 import org.apache.tapestry.ioc.def.DecoratorDef;

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/BodyBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/BodyBuilder.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/BodyBuilder.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/BodyBuilder.java Tue Oct  9 08:22:27 2007
@@ -16,6 +16,8 @@
 
 import java.util.Formatter;
 
+import org.apache.tapestry.ioc.services.MethodSignature;
+
 /**
  * Utility class for assembling the <em>body</em> used with Javassist when defining a method or
  * constructor. Basically, assists with formatting and with indentation. This makes the code that

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/IOCStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/IOCStrings.properties?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/IOCStrings.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/IOCStrings.properties Tue Oct  9 08:22:27 2007
@@ -15,10 +15,10 @@
 build-method-conflict=Service building method %s conflicts with (has the same name as, but different parameters than) \
   previously seen method %s and has been ignored.
 build-method-wrong-return-type=Method %s is named like a service builder method, \
- but the return type (%s) is not acceptible (try an interface). \
+ but the return type (%s) is not acceptable (try an interface). \
  The method has been ignored.
 decorator-method-wrong-return-type=Method %s is named like a service decorator method, \
-  but the return type (%s) is not acceptible (try Object). The method has been ignored.
+  but the return type (%s) is not acceptable (try Object). The method has been ignored.
 builder-locked=The Registry Builder has created the Registry, further operations are not allowed.
 service-wrong-interface=Service '%s' implements interface %s, which is not compatible with the requested type %s.
 instantiate-builder-error=Unable to instantiate class %s as a module builder: %s
@@ -28,7 +28,10 @@
 builder-method-returned-null=Builder method %s (for service '%s') returned null.
 no-service-matches-type=No service implements the interface %s.
 many-service-matches=Service interface %s is matched by %d services: %s.  \
-  Automatic dependency resolution requires that exactly one service implement the interface.
+  Automatic dependency resolution requires that exactly one service implement the interface.
+no-services-match-marker=Unable to locate any service assignable to type %s with marker annotation %s.
+many-services-match-marker=Unable to locate a single service assignable to type %s with marker annotation %s.  \
+ All of the following services match: %s.
 unknown-scope=Unknown service scope '%s'.
 decorator-method-needs-delegate-parameter=Decorator methods must a parameter for the service delegate \
  (i.e., the object the created interceptor will delegate to). \

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/provider.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/provider.apt?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/provider.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/provider.apt Tue Oct  9 08:22:27 2007
@@ -4,7 +4,7 @@
 
 Object Providers
 
-  When you don't provide the {{{../apidocs/org/apache/tapestry/annotations/InjectService.html}InjectService}} annotation
+  When you don't provide the {{{../apidocs/org/apache/tapestry/ioc/annotations/InjectService.html}InjectService}} annotation
   on a parameter (to a service builder method or constructor), Tapestry will
   resolve the parameter automatically.
   

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/service.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/service.apt?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/service.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/service.apt Tue Oct  9 08:22:27 2007
@@ -148,7 +148,7 @@
   it down to a <single> service. At this point, it is necessary to <disambiguate> the link between
   the service interface and <one> service.  One approach is to use
   the 
-  {{{../apidocs/org/apache/tapestry/annotations/InjectService.html}InjectService}} annotation:
+  {{{../apidocs/org/apache/tapestry/ioc/annotations/InjectService.html}InjectService}} annotation:
   
   
 +-----------------------------------------------------------------------------------+
@@ -428,7 +428,7 @@
 
   It doesn't work because type String always gets the service id, as a resource (as with the serviceId parameter).
   In order to get this to work, we need to turn off the resource injection for the alertEmail parameter.
-  That's what the {{{../apidocs/org/apache/tapestry/annotations/Inject.html}Inject}} annotation does:
+  That's what the {{{../apidocs/org/apache/tapestry/ioc/annotations/Inject.html}Inject}} annotation does:
   
 +-----------------------------------------------------------------------------------+
   public static Indexer build(String serviceId, Log serviceLog,  

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/BlueMarker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/BlueMarker.java?rev=583192&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/BlueMarker.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/BlueMarker.java Tue Oct  9 08:22:27 2007
@@ -0,0 +1,32 @@
+// Copyright 2007 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.tapestry.ioc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Target(
+{ PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+public @interface BlueMarker
+{
+
+}

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/DecoratorList.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/DecoratorList.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/DecoratorList.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/DecoratorList.java Tue Oct  9 08:22:27 2007
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.ioc;
 
-import java.util.List;
+import java.util.List;
 
 /**
  * Used to track the order in which decorators are invoked.

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/GreeterModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/GreeterModule.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/GreeterModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/GreeterModule.java Tue Oct  9 08:22:27 2007
@@ -15,9 +15,16 @@
 package org.apache.tapestry.ioc;
 
 import org.apache.tapestry.ioc.annotations.InjectService;
+import org.apache.tapestry.ioc.annotations.Marker;
 
 public class GreeterModule
 {
+    @Marker(YellowMarker.class)
+    public NameListHolder buildYellowThing()
+    {
+        return null;
+    }
+
     public Greeter buildHelloGreeter()
     {
         return new Greeter()
@@ -38,6 +45,48 @@
                 return "Goodbye";
             }
         };
+    }
+
+    @Marker(BlueMarker.class)
+    public Greeter buildBlueGreeter()
+    {
+        return new Greeter()
+        {
+            public String getGreeting()
+            {
+                return "Blue";
+            }
+        };
+    }
+
+    @Marker(RedMarker.class)
+    public Greeter buildRedGreeter1()
+    {
+        return null;
+    }
+
+    @Marker(RedMarker.class)
+    public Greeter buildRedGreeter2()
+    {
+        return null;
+    }
+
+    public Greeter buildInjectedBlueGreeter(@BlueMarker
+    Greeter greeter)
+    {
+        return greeter;
+    }
+
+    public Greeter buildInjectedRedGreeter(@RedMarker
+    Greeter greeter)
+    {
+        return greeter;
+    }
+
+    public Greeter buildInjectedYellowGreeter(@YellowMarker
+    Greeter greeter)
+    {
+        return greeter;
     }
 
     public Greeter buildGreeter(@InjectService("${greeter}")

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java Tue Oct  9 08:22:27 2007
@@ -585,4 +585,58 @@
         assertEquals(g.toString(), "<Proxy for HelloGreeter(org.apache.tapestry.ioc.Greeter)>");
     }
 
+    @Test
+    public void injection_by_marker_with_single_match()
+    {
+        Registry r = buildRegistry(GreeterModule.class);
+
+        Greeter g = r.getService("InjectedBlueGreeter", Greeter.class);
+
+        assertEquals(g.getGreeting(), "Blue");
+    }
+
+    @Test
+    public void injection_by_marker_with_multiple_matches()
+    {
+        Registry r = buildRegistry(GreeterModule.class);
+
+        Greeter g = r.getService("InjectedRedGreeter", Greeter.class);
+
+        try
+        {
+            g.getGreeting();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(
+                    ex,
+                    "Error invoking service builder method",
+                    "Unable to locate a single service assignable to type org.apache.tapestry.ioc.Greeter with marker annotation org.apache.tapestry.ioc.RedMarker",
+                    "org.apache.tapestry.ioc.GreeterModule.buildRedGreeter1()",
+                    "org.apache.tapestry.ioc.GreeterModule.buildRedGreeter2()");
+        }
+    }
+
+    @Test
+    public void injection_by_marker_with_zero_matches()
+    {
+        Registry r = buildRegistry(GreeterModule.class);
+
+        Greeter g = r.getService("InjectedYellowGreeter", Greeter.class);
+
+        try
+        {
+            g.getGreeting();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(
+                    ex,
+                    "Error invoking service builder method",
+                    " Unable to locate any service assignable to type org.apache.tapestry.ioc.Greeter with marker annotation org.apache.tapestry.ioc.YellowMarker.");
+        }
+
+    }
 }

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/MarkerModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/MarkerModule.java?rev=583192&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/MarkerModule.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/MarkerModule.java Tue Oct  9 08:22:27 2007
@@ -0,0 +1,35 @@
+// Copyright 2007 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.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotations.Marker;
+
+public class MarkerModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(Greeter.class, RedGreeterImpl.class).withId("RedGreeter");
+        binder.bind(Greeter.class, UnknownColorGreeterImpl.class).withId("SecondRedGreeter")
+                .withMarker(RedMarker.class);
+        binder.bind(Greeter.class, RedGreeterImpl.class).withId("SurprisinglyBlueGreeter")
+                .withMarker(BlueMarker.class);
+    }
+
+    @Marker(BlueMarker.class)
+    public Greeter build()
+    {
+        return null;
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/NameListHolder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/NameListHolder.java?rev=583192&r1=583191&r2=583192&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/NameListHolder.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/NameListHolder.java Tue Oct  9 08:22:27 2007
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.ioc;
 
-import java.util.List;
+import java.util.List;
 
 /**
  * Used for testing of ordered and unordered contributions. The names are contributed in from