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 2011/04/21 00:45:46 UTC

svn commit: r1095544 [1/2] - in /tapestry/tapestry5/trunk: plastic/src/main/java/org/apache/tapestry5/internal/plastic/ plastic/src/main/java/org/apache/tapestry5/plastic/ plastic/src/test/groovy/org/apache/tapestry5/plastic/ plastic/src/test/java/test...

Author: hlship
Date: Wed Apr 20 22:45:44 2011
New Revision: 1095544

URL: http://svn.apache.org/viewvc?rev=1095544&view=rev
Log:
TAP5-853: Replace annotation copying (from implementation class into proxy class) with AnnotationAccess interface and similar methods
that provide access to annotations (preferring implementation class annotations to interface annotation)

Added:
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/AnnotationAccess.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/def/ServiceDef3.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AnnotationAccessImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AbtractAspectInterceptorBuilder.java
Removed:
    tapestry/tapestry5/trunk/plastic/src/test/java/testinterfaces/AnnotationTransfer.java
    tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/AnnotationTransferImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/InternalServiceDef.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AbstractInvocation.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/MethodInfo.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/AbstractInvocationTest.java
Modified:
    tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
    tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassPool.java
    tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticClass.java
    tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ProxyCreation.groovy
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ApplicationMessageCatalogObjectProvider.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/MethodAdviceReceiver.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ServiceResources.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AdvisorStackBuilder.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/InterceptorStackBuilder.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/InternalRegistry.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/Module.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDefImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceResourcesImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectDecoratorImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectInterceptorBuilderImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PerThreadServiceLifecycle.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/AspectDecorator.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PlasticProxyFactory.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/IOCInternalTestCase.java
    tapestry/tapestry5/trunk/tapestry-jpa/src/test/java/org/apache/tapestry5/internal/jpa/JpaTransactionAdvisorImplTest.java

Modified: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java (original)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java Wed Apr 20 22:45:44 2011
@@ -2274,116 +2274,6 @@ public class PlasticClassImpl extends Lo
         return methodBundle.isImplemented(description.methodName, nameCache.toDesc(description));
     }
 
-    public PlasticClass copyAnnotations(String sourceClassName)
-    {
-        assert PlasticInternalUtils.isNonBlank(sourceClassName);
-
-        ClassNode sourceClass = pool.constructClassNode(sourceClassName, false);
-
-        if (sourceClass == null)
-            return this;
-
-        if (sourceClass.visibleAnnotations != null)
-        {
-            if (classNode.visibleAnnotations == null)
-                classNode.visibleAnnotations = PlasticInternalUtils.newList();
-
-            mergeAnnotations(classNode.visibleAnnotations, sourceClass.visibleAnnotations);
-        }
-
-        Map<String, MethodNode> sourceMethods = buildMethodNodeMap(sourceClass, true);
-
-        if (sourceMethods.isEmpty())
-            return this;
-
-        Map<String, MethodNode> targetMethods = buildMethodNodeMap(classNode, false);
-
-        for (Map.Entry<String, MethodNode> entry : sourceMethods.entrySet())
-        {
-            MethodNode target = targetMethods.get(entry.getKey());
-
-            // Not all source methods (especially private ones) will be in the target class,
-            // which is typically a proxy, implementing just public methods defined in an interface.
-
-            if (target == null)
-                continue;
-
-            MethodNode source = entry.getValue();
-
-            if (source.visibleAnnotations != null)
-            {
-                if (target.visibleAnnotations == null)
-                    target.visibleAnnotations = PlasticInternalUtils.newList();
-
-                mergeAnnotations(target.visibleAnnotations, source.visibleAnnotations);
-            }
-
-            if (source.visibleParameterAnnotations != null)
-            {
-                int count = source.visibleParameterAnnotations.length;
-
-                if (target.visibleParameterAnnotations == null)
-                    target.visibleParameterAnnotations = new List[count];
-
-                for (int i = 0; i < count; i++)
-                {
-                    if (source.visibleParameterAnnotations[i] == null)
-                        continue;
-
-                    if (target.visibleParameterAnnotations[i] == null)
-                        target.visibleParameterAnnotations[i] = PlasticInternalUtils.newList();
-
-                    mergeAnnotations(target.visibleParameterAnnotations[i], source.visibleParameterAnnotations[i]);
-                }
-
-            }
-        }
-
-        return this;
-    }
-
-    /**
-     * Copies nodes from the source list to the target list, as long as they don't conflict with an
-     * annotation already present in the target list (as annotations must be unique).
-     */
-    private static void mergeAnnotations(List<AnnotationNode> targetAnnotations, List<AnnotationNode> sourceAnnotations)
-    {
-        Set<String> targetDescs = PlasticInternalUtils.newSet();
-
-        for (AnnotationNode targetNode : targetAnnotations)
-        {
-            targetDescs.add(targetNode.desc);
-        }
-
-        for (AnnotationNode sourceNode : sourceAnnotations)
-        {
-            if (targetDescs.contains(sourceNode.desc))
-                continue;
-
-            targetAnnotations.add(sourceNode);
-        }
-    }
-
-    private static Map<String, MethodNode> buildMethodNodeMap(ClassNode source, boolean withAnnotationsOnly)
-    {
-        boolean all = !withAnnotationsOnly;
-
-        Map<String, MethodNode> result = new HashMap<String, MethodNode>();
-
-        for (Object m : source.methods)
-        {
-            MethodNode mn = (MethodNode) m;
-
-            if (mn.name.equals(CONSTRUCTOR_NAME))
-                continue;
-
-            if (all || hasAnnotations(mn))
-                result.put(mn.name + ":" + mn.desc, mn);
-        }
-
-        return result;
-    }
-
     /**
      * True if the node has any visible annotations, or it has visible annotations on any
      * parameter.
@@ -2412,12 +2302,4 @@ public class PlasticClassImpl extends Lo
     {
         return l != null && !l.isEmpty();
     }
-
-    public PlasticClass copyAnnotations(Class sourceClass)
-    {
-        assert sourceClass != null;
-
-        return copyAnnotations(sourceClass.getName());
-    }
-
 }

Modified: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassPool.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassPool.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassPool.java (original)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassPool.java Wed Apr 20 22:45:44 2011
@@ -55,8 +55,6 @@ public class PlasticClassPool implements
 
     private final StaticContext emptyStaticContext = new StaticContext();
 
-    private final Map<String, byte[]> createdClassesBytecode = PlasticInternalUtils.newMap();
-
     private final Cache<String, TypeCategory> typeName2Category = new Cache<String, TypeCategory>()
     {
 
@@ -125,8 +123,6 @@ public class PlasticClassPool implements
 
         String className = PlasticInternalUtils.toClassName(classNode.name);
 
-        createdClassesBytecode.put(className, bytecode);
-
         return loader.defineClassWithBytecode(className, bytecode);
     }
 
@@ -257,7 +253,7 @@ public class PlasticClassPool implements
 
     private Class loadInnerClass(String className)
     {
-        byte[] bytecode = readBytecode(className, true);
+        byte[] bytecode = readBytecode(className);
 
         return loader.defineClassWithBytecode(className, bytecode);
     }
@@ -309,7 +305,7 @@ public class PlasticClassPool implements
      */
     public ClassNode constructClassNode(String className, boolean mustExist)
     {
-        byte[] bytecode = readBytecode(className, mustExist);
+        byte[] bytecode = readBytecode(className);
 
         if (bytecode == null)
             return null;
@@ -328,27 +324,16 @@ public class PlasticClassPool implements
         return result;
     }
 
-    private byte[] readBytecode(String className, boolean mustExist)
+    private byte[] readBytecode(String className)
     {
-        byte[] createdBytecode = createdClassesBytecode.get(className);
-
-        if (createdBytecode != null)
-            return createdBytecode;
-
         ClassLoader parentClassLoader = loader.getParent();
 
         String path = PlasticInternalUtils.toClassPath(className);
 
         InputStream stream = parentClassLoader.getResourceAsStream(path);
 
-        if (stream == null)
-        {
-            if (mustExist)
-                throw new RuntimeException(String.format("Unable to locate class file for '%s' in class loader %s.",
-                        className, parentClassLoader));
-
-            return null;
-        }
+        if (stream == null) { throw new RuntimeException(String.format(
+                "Unable to locate class file for '%s' in class loader %s.", className, parentClassLoader)); }
 
         try
         {

Modified: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticClass.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticClass.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticClass.java (original)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticClass.java Wed Apr 20 22:45:44 2011
@@ -185,28 +185,4 @@ public interface PlasticClass extends An
      * @return this plastic class, for further configuration
      */
     PlasticClass addToString(String toStringValue);
-
-    /**
-     * Copies annotations from the indicated source class name; this copies all class annotations,
-     * and for each method that exists in both classes, copies over method and parameter annotations. This addresses
-     * a specific use case for Tapestry IoC, where a proxy class is expected to expose the visible annotations of the
-     * implementation class. As currently implemented, copied annotations <em>overwrite</em> annotations in this
-     * PlasticClass (because it is expected that there are no annotations in a proxy).
-     * <p>
-     * This method should be invoked late in the PlasticClass transformation; copied annotations may not be visible as
-     * annotations on the PlasticClass or {@link PlasticMethod}s of the PlasticClass.
-     * 
-     * @param sourceClassName
-     *            source class from which to extract annotations
-     * @return this plastic class, for further configuration
-     */
-    PlasticClass copyAnnotations(String sourceClassName);
-
-    /**
-     * An convenience for {@link #copyAnnotations(String)}.
-     * 
-     * @param sourceClass
-     * @return this plastic class, for further configuration
-     */
-    PlasticClass copyAnnotations(Class sourceClass);
 }

Modified: tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ProxyCreation.groovy
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ProxyCreation.groovy?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ProxyCreation.groovy (original)
+++ tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ProxyCreation.groovy Wed Apr 20 22:45:44 2011
@@ -1,10 +1,6 @@
 package org.apache.tapestry5.plastic
 
 import spock.lang.Specification
-import testannotations.Maybe
-import testannotations.Truth
-import testinterfaces.AnnotationTransfer
-import testsubjects.AnnotationTransferImpl
 
 class ProxyCreation extends Specification {
     def "create a field delegating proxy"() {
@@ -94,24 +90,4 @@ class ProxyCreation extends Specificatio
         e.message == "Class java.lang.String is not an interface; proxies may only be created for interfaces."
     }
 
-    def "copying of annotations"() {
-        setup:
-        def mgr = new PlasticManager()
-
-        def o = mgr.createProxy (AnnotationTransfer.class, { PlasticClass pc ->
-
-            pc.copyAnnotations (AnnotationTransferImpl.class)
-        } as PlasticClassTransformer).newInstance()
-
-        def oc = o.getClass()
-        def method1 = oc.getMethod("method1", int.class)
-
-        expect:
-
-        oc.getAnnotation(Maybe.class).value() == Truth.YES
-
-        method1.getAnnotation(Maybe.class).value() == Truth.YES
-        method1.getParameterAnnotations()[0][0].annotationType() == Maybe.class
-        method1.getParameterAnnotations()[0][0].value() == Truth.YES
-    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ApplicationMessageCatalogObjectProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ApplicationMessageCatalogObjectProvider.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ApplicationMessageCatalogObjectProvider.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ApplicationMessageCatalogObjectProvider.java Wed Apr 20 22:45:44 2011
@@ -89,7 +89,7 @@ public class ApplicationMessageCatalogOb
                     PlasticProxyFactory.class);
 
             proxy = proxyFactory.createProxy(Messages.class, new ApplicationMessagesObjectCreator(),
-                    null, "<ApplicationMessagesProxy>");
+                    "<ApplicationMessagesProxy>");
 
             // Listen for invalidations; clear our cache of localized Messages bundles when
             // and invalidation occurs.

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/AnnotationAccess.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/AnnotationAccess.java?rev=1095544&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/AnnotationAccess.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/AnnotationAccess.java Wed Apr 20 22:45:44 2011
@@ -0,0 +1,41 @@
+// Copyright 2011 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;
+
+/**
+ * Introduced for Tapestry 5.3, contains new methods to provide access to annotations on the class,
+ * and on methods of the class. In rare cases, the same annotation type will appear on the service interface
+ * and on the class (or method implementation in the class); the implementation annotation always
+ * has precedence over the interface annotation.
+ * 
+ * @since 5.3.0
+ */
+public interface AnnotationAccess
+{
+    /**
+     * Returns a provider for annotations on the service class and interface. This will reflect annotations defined by
+     * the implementation class itself, plus annotations defined by the service interface (implementation class
+     * annotations take precedence).
+     */
+    AnnotationProvider getClassAnnotationProvider();
+
+    /**
+     * Returns a provider for annotations of a method of the class. This includes annotations on
+     * the implementation method, plus annotations on the corresponding service interface method
+     * (if such a method exists), with precedence on the implementation class method annotations.
+     */
+    AnnotationProvider getMethodAnnotationProvider(String methodName, Class... parameterTypes);
+
+}

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/MethodAdviceReceiver.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/MethodAdviceReceiver.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/MethodAdviceReceiver.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/MethodAdviceReceiver.java Wed Apr 20 22:45:44 2011
@@ -1,10 +1,10 @@
-// Copyright 2009 The Apache Software Foundation
+// Copyright 2009, 2011 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
+// 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,
@@ -14,19 +14,22 @@
 
 package org.apache.tapestry5.ioc;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 
 /**
- * Interface used with service advisor methods to define advice.  Allows advice on specific methods, or on all methods.
+ * Interface used with service advisor methods to define advice. Allows advice on specific methods, or on all methods.
  */
-public interface MethodAdviceReceiver
+public interface MethodAdviceReceiver extends AnnotationAccess
 {
     /**
      * Adds advice for a specific method of the aspect interceptor being constructed.
-     *
-     * @param method method (of the interface for which an interceptor is being constructed) to be advised. Multiple
-     *               advice is allowed for a single method; the advice will be executed in the order it is added.
-     * @param advice the advice for this particular method.   Advice must be threadsafe.
+     * 
+     * @param method
+     *            method (of the interface for which an interceptor is being constructed) to be advised. Multiple
+     *            advice is allowed for a single method; the advice will be executed in the order it is added.
+     * @param advice
+     *            the advice for this particular method. Advice must be threadsafe.
      */
     void adviseMethod(Method method, MethodAdvice advice);
 
@@ -37,9 +40,23 @@ public interface MethodAdviceReceiver
 
     /**
      * Returns the interface for which methods may be advised.
-     *
+     * 
      * @see org.apache.tapestry5.ioc.services.MethodIterator
      * @since 5.1.0.0
      */
     Class getInterface();
+
+    /**
+     * Gets an annotation from a method, via {@link AnnotationAccess#getMethodAnnotationProvider(String, Class...)}.
+     * 
+     * @param <T>
+     *            type of annotation
+     * @param method
+     *            method to search
+     * @param annotationType
+     *            type of annotation
+     * @return the annotation found on the underlying implementation class (if known) or service interface, or null if
+     *         not found
+     */
+    <T extends Annotation> T getMethodAnnotation(Method method, Class<T> annotationType);
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ServiceResources.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ServiceResources.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ServiceResources.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ServiceResources.java Wed Apr 20 22:45:44 2011
@@ -4,7 +4,7 @@
 // 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
+// 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,
@@ -18,10 +18,10 @@ import org.slf4j.Logger;
 
 /**
  * Contains resources that may be provided to a service when it initializes, which includes other services defined in
- * the registry. ServiceResources provides access to other services (it extends {@link
- * org.apache.tapestry5.ioc.ObjectLocator}).
+ * the registry. ServiceResources provides access to other services (it extends
+ * {@link org.apache.tapestry5.ioc.ObjectLocator}).
  */
-public interface ServiceResources extends ObjectLocator
+public interface ServiceResources extends ObjectLocator, AnnotationAccess
 {
     /**
      * Returns the fully qualified id of the service.
@@ -45,11 +45,12 @@ public interface ServiceResources extend
      * initializing the service.
      */
     OperationTracker getTracker();
-    
+
     /**
-     * Returns the service implementation class.
+     * Returns null (as of 5.3.0).
      * 
      * @since 5.2.0
+     * @deprecated Deprecated in 5.3.0 with no replacement. May be removed in 5.4.
      */
     Class getImplementationClass();
 }

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/def/ServiceDef3.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/def/ServiceDef3.java?rev=1095544&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/def/ServiceDef3.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/def/ServiceDef3.java Wed Apr 20 22:45:44 2011
@@ -0,0 +1,29 @@
+// Copyright 2011 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.def;
+
+import org.apache.tapestry5.ioc.AnnotationAccess;
+
+/**
+ * Introduced for Tapestry 5.3, contains new methods to provide access to annotations on the class,
+ * and on methods of the class. In rare cases, the same annotation type will appear on the service interface
+ * and on the class (or method implementation in the class); the implementation annotation always
+ * has precedence over the interface annotation.
+ * 
+ * @since 5.3.0
+ */
+public interface ServiceDef3 extends ServiceDef2, AnnotationAccess
+{
+}

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AdvisorStackBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AdvisorStackBuilder.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AdvisorStackBuilder.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AdvisorStackBuilder.java Wed Apr 20 22:45:44 2011
@@ -1,10 +1,10 @@
-// Copyright 2009 The Apache Software Foundation
+// Copyright 2009, 2011 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
+// 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,
@@ -14,24 +14,24 @@
 
 package org.apache.tapestry5.ioc.internal;
 
+import java.util.List;
+
 import org.apache.tapestry5.ioc.ObjectCreator;
 import org.apache.tapestry5.ioc.ServiceAdvisor;
-import org.apache.tapestry5.ioc.def.ServiceDef;
+import org.apache.tapestry5.ioc.def.ServiceDef3;
 import org.apache.tapestry5.ioc.services.AspectDecorator;
 import org.apache.tapestry5.ioc.services.AspectInterceptorBuilder;
 
-import java.util.List;
-
 /**
- * Equivalent of {@link org.apache.tapestry5.ioc.internal.InterceptorStackBuilder}, but works using an {@link
- * org.apache.tapestry5.ioc.services.AspectInterceptorBuilder} that receives advice from {@link
- * org.apache.tapestry5.ioc.ServiceAdvisor}s.
- *
+ * Equivalent of {@link org.apache.tapestry5.ioc.internal.InterceptorStackBuilder}, but works using an
+ * {@link org.apache.tapestry5.ioc.services.AspectInterceptorBuilder} that receives advice from
+ * {@link org.apache.tapestry5.ioc.ServiceAdvisor}s.
+ * 
  * @since 5.1.0.0
  */
 public class AdvisorStackBuilder implements ObjectCreator
 {
-    private final ServiceDef serviceDef;
+    private final ServiceDef3 serviceDef;
 
     private final ObjectCreator delegate;
 
@@ -40,14 +40,17 @@ public class AdvisorStackBuilder impleme
     private final InternalRegistry registry;
 
     /**
-     * @param serviceDef      the service that is ultimately being constructed
-     * @param delegate        responsible for creating the object to be decorated
-     * @param aspectDecorator used to create the {@link org.apache.tapestry5.ioc.services.AspectInterceptorBuilder}
-     *                        passed to each {@link org.apache.tapestry5.ioc.ServiceAdvisor}
+     * @param serviceDef
+     *            the service that is ultimately being constructed
+     * @param delegate
+     *            responsible for creating the object to be decorated
+     * @param aspectDecorator
+     *            used to create the {@link org.apache.tapestry5.ioc.services.AspectInterceptorBuilder} passed to each
+     *            {@link org.apache.tapestry5.ioc.ServiceAdvisor}
      * @param registry
      */
-    public AdvisorStackBuilder(ServiceDef serviceDef, ObjectCreator delegate,
-                               AspectDecorator aspectDecorator, InternalRegistry registry)
+    public AdvisorStackBuilder(ServiceDef3 serviceDef, ObjectCreator delegate, AspectDecorator aspectDecorator,
+            InternalRegistry registry)
     {
         this.serviceDef = serviceDef;
         this.delegate = delegate;
@@ -65,10 +68,9 @@ public class AdvisorStackBuilder impleme
             return service;
 
         final AspectInterceptorBuilder builder = aspectDecorator.createBuilder(serviceDef.getServiceInterface(),
-                                                                               service,
-                                                                               String.format("<AspectProxy for %s(%s)>",
-                                                                                             serviceDef.getServiceId(),
-                                                                                             serviceDef.getServiceInterface().getName()));
+                service, serviceDef, String.format("<AspectProxy for %s(%s)>", serviceDef.getServiceId(), serviceDef
+                        .getServiceInterface().getName()));
+
         for (final ServiceAdvisor advisor : advisors)
         {
             registry.run("Invoking " + advisor, new Runnable()

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AnnotationAccessImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AnnotationAccessImpl.java?rev=1095544&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AnnotationAccessImpl.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AnnotationAccessImpl.java Wed Apr 20 22:45:44 2011
@@ -0,0 +1,45 @@
+// Copyright 2011 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;
+
+import org.apache.tapestry5.ioc.AnnotationAccess;
+import org.apache.tapestry5.ioc.AnnotationProvider;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+
+/**
+ * Standard AnnotationAccess for a specific type.
+ * 
+ * @since 5.3.0
+ */
+public class AnnotationAccessImpl implements AnnotationAccess
+{
+    private final Class type;
+
+    public AnnotationAccessImpl(Class type)
+    {
+        this.type = type;
+    }
+
+    public AnnotationProvider getClassAnnotationProvider()
+    {
+        return InternalUtils.toAnnotationProvider(type);
+    }
+
+    public AnnotationProvider getMethodAnnotationProvider(String methodName, Class... parameterTypes)
+    {
+        return InternalUtils.toAnnotationProvider(InternalUtils.findMethod(type, methodName, parameterTypes));
+    }
+
+}

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/InterceptorStackBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/InterceptorStackBuilder.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/InterceptorStackBuilder.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/InterceptorStackBuilder.java Wed Apr 20 22:45:44 2011
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2011 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
+// 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,
@@ -14,33 +14,35 @@
 
 package org.apache.tapestry5.ioc.internal;
 
+import java.util.Collections;
+import java.util.List;
+
 import org.apache.tapestry5.ioc.Invokable;
 import org.apache.tapestry5.ioc.ObjectCreator;
 import org.apache.tapestry5.ioc.ServiceDecorator;
-import org.apache.tapestry5.ioc.def.ServiceDef;
-
-import java.util.Collections;
-import java.util.List;
+import org.apache.tapestry5.ioc.def.ServiceDef3;
 
 /**
- * Responsible for constructing the interceptor stack, on demand, by invoking an ordered series of decorators ({@link
- * org.apache.tapestry5.ioc.def.DecoratorDef} (which are converted into {@link ServiceDecorator}s).
+ * Responsible for constructing the interceptor stack, on demand, by invoking an ordered series of decorators (
+ * {@link org.apache.tapestry5.ioc.def.DecoratorDef} (which are converted into {@link ServiceDecorator}s).
  */
 public class InterceptorStackBuilder implements ObjectCreator
 {
-    private final ServiceDef serviceDef;
+    private final ServiceDef3 serviceDef;
 
     private final ObjectCreator delegate;
 
     private final InternalRegistry registry;
 
     /**
-     * @param serviceDef service begin decorated
-     * @param delegate   responsible for creating the object to be decorated
-     * @param registry   access to service decorators
+     * @param serviceDef
+     *            service begin decorated
+     * @param delegate
+     *            responsible for creating the object to be decorated
+     * @param registry
+     *            access to service decorators
      */
-    public InterceptorStackBuilder(ServiceDef serviceDef, ObjectCreator delegate,
-                                   InternalRegistry registry)
+    public InterceptorStackBuilder(ServiceDef3 serviceDef, ObjectCreator delegate, InternalRegistry registry)
     {
         this.serviceDef = serviceDef;
         this.delegate = delegate;
@@ -62,19 +64,19 @@ public class InterceptorStackBuilder imp
         {
             final Object delegate = current;
 
-            Object interceptor =
-                    registry.invoke("Invoking " + decorator, new Invokable<Object>()
-                    {
-                        public Object invoke()
-                        {
-                            return decorator.createInterceptor(delegate);
-                        }
-                    });
+            Object interceptor = registry.invoke("Invoking " + decorator, new Invokable<Object>()
+            {
+                public Object invoke()
+                {
+                    return decorator.createInterceptor(delegate);
+                }
+            });
 
             // Decorator methods may return null; this indicates that the decorator chose not to
             // decorate.
 
-            if (interceptor != null) current = interceptor;
+            if (interceptor != null)
+                current = interceptor;
         }
 
         // The stack of interceptors (plus the core service implementation) are "represented" to the

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/InternalRegistry.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/InternalRegistry.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/InternalRegistry.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/InternalRegistry.java Wed Apr 20 22:45:44 2011
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2011 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.
@@ -26,7 +26,7 @@ import org.apache.tapestry5.ioc.Registry
 import org.apache.tapestry5.ioc.ServiceAdvisor;
 import org.apache.tapestry5.ioc.ServiceDecorator;
 import org.apache.tapestry5.ioc.ServiceLifecycle2;
-import org.apache.tapestry5.ioc.def.ServiceDef;
+import org.apache.tapestry5.ioc.def.ServiceDef3;
 import org.apache.tapestry5.ioc.services.ClassFab;
 import org.apache.tapestry5.ioc.services.RegistryShutdownHub;
 import org.slf4j.Logger;
@@ -69,14 +69,14 @@ public interface InternalRegistry extend
      * s
      * are ordered, then converted into {@link ServiceDecorator}s.
      */
-    List<ServiceDecorator> findDecoratorsForService(ServiceDef serviceDef);
+    List<ServiceDecorator> findDecoratorsForService(ServiceDef3 serviceDef);
 
     /**
      * Searches for advisors for a particular service, returning them in order of application.
      * 
      * @since 5.1.0.0
      */
-    List<ServiceAdvisor> findAdvisorsForService(ServiceDef serviceDef);
+    List<ServiceAdvisor> findAdvisorsForService(ServiceDef3 serviceDef);
 
     /**
      * Builds up an unordered collection by invoking service contributor methods that target the service (from any
@@ -89,7 +89,7 @@ public interface InternalRegistry extend
      *            identifies the type of object allowed into the collection
      * @return the final collection
      */
-    <T> Collection<T> getUnorderedConfiguration(ServiceDef serviceDef, Class<T> valueType);
+    <T> Collection<T> getUnorderedConfiguration(ServiceDef3 serviceDef, Class<T> valueType);
 
     /**
      * Builds up an ordered collection by invoking service contributor methods that target the service (from any module,
@@ -103,7 +103,7 @@ public interface InternalRegistry extend
      *            identifies the type of object allowed into the collection
      * @return the final ordered list
      */
-    <T> List<T> getOrderedConfiguration(ServiceDef serviceDef, Class<T> valueType);
+    <T> List<T> getOrderedConfiguration(ServiceDef3 serviceDef, Class<T> valueType);
 
     /**
      * Builds up a map of key/value pairs by invoking service contribution methods that tharget the service (from any
@@ -119,7 +119,7 @@ public interface InternalRegistry extend
      *            identifies the type of value object allowed into the map
      * @return the final ordered list
      */
-    <K, V> Map<K, V> getMappedConfiguration(ServiceDef serviceDef, Class<K> keyType, Class<V> valueType);
+    <K, V> Map<K, V> getMappedConfiguration(ServiceDef3 serviceDef, Class<K> keyType, Class<V> valueType);
 
     /**
      * Convieience for creating a new {@link org.apache.tapestry5.ioc.services.ClassFab} instance using a

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/Module.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/Module.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/Module.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/Module.java Wed Apr 20 22:45:44 2011
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2011 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
+// 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,
@@ -22,7 +22,7 @@ import org.apache.tapestry5.ioc.ModuleBu
 import org.apache.tapestry5.ioc.def.ContributionDef2;
 import org.apache.tapestry5.ioc.def.DecoratorDef;
 import org.apache.tapestry5.ioc.def.ServiceDef;
-import org.apache.tapestry5.ioc.def.ServiceDef2;
+import org.apache.tapestry5.ioc.def.ServiceDef3;
 
 /**
  * A module within the Tapestry IoC registry. Each Module is constructed around a corresponding module builder instance;
@@ -32,20 +32,24 @@ public interface Module extends ModuleBu
 {
     /**
      * Locates a service given a service id and the corresponding service interface type.
-     *
+     * 
      * @param <T>
-     * @param serviceId        identifies the service to access
-     * @param serviceInterface the interface the service implements
+     * @param serviceId
+     *            identifies the service to access
+     * @param serviceInterface
+     *            the interface the service implements
      * @return the service's proxy
-     * @throws RuntimeException if there is an error instantiating the service proxy
+     * @throws RuntimeException
+     *             if there is an error instantiating the service proxy
      */
     <T> T getService(String serviceId, Class<T> serviceInterface);
 
     /**
      * Locates the ids of all services that implement the provided service interface, or whose service interface is
      * assignable to the provided service interface (is a super-class or super-interface).
-     *
-     * @param serviceInterface the interface to search for
+     * 
+     * @param serviceInterface
+     *            the interface to search for
      * @return a collection of service ids
      */
     Collection<String> findServiceIdsForInterface(Class serviceInterface);
@@ -53,8 +57,9 @@ public interface Module extends ModuleBu
     /**
      * Iterates over any decorator definitions defined by the module and returns those that apply to the provided
      * service definition.
-     *
-     * @param serviceDef for which decorators are being assembled
+     * 
+     * @param serviceDef
+     *            for which decorators are being assembled
      * @return set of decorators, possibly empty (but not null)
      */
     Set<DecoratorDef> findMatchingDecoratorDefs(ServiceDef serviceDef);
@@ -62,8 +67,9 @@ public interface Module extends ModuleBu
     /**
      * Iterates over any advisor definitions defined by the module and returns those that apply to the provided service
      * definition.
-     *
-     * @param serviceDef for which advisors are being assembled
+     * 
+     * @param serviceDef
+     *            for which advisors are being assembled
      * @return set of advisors, possibly empty but not null
      * @since 5.1.0.0
      */
@@ -77,23 +83,25 @@ public interface Module extends ModuleBu
     /**
      * Locates services with the {@link org.apache.tapestry5.ioc.annotations.EagerLoad} annotation and generates proxies
      * for them, then adds them to the proxies list for instantiation.
-     *
-     * @param proxies collection of proxies to which any eager load services in the module should be added
+     * 
+     * @param proxies
+     *            collection of proxies to which any eager load services in the module should be added
      */
     void collectEagerLoadServices(Collection<EagerLoadServiceProxy> proxies);
 
     /**
      * Returns the service definition for the given service id.
-     *
-     * @param serviceId unique id for the service (caseless)
+     * 
+     * @param serviceId
+     *            unique id for the service (caseless)
      * @return the service definition or null
      */
-    ServiceDef2 getServiceDef(String serviceId);
+    ServiceDef3 getServiceDef(String serviceId);
 
     /**
      * Returns the name used to obtain a logger for the module. Services within the module suffix this with a period and
      * the service id.
-     *
+     * 
      * @return module logger name
      */
     String getLoggerName();

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java Wed Apr 20 22:45:44 2011
@@ -45,6 +45,7 @@ import org.apache.tapestry5.ioc.def.Modu
 import org.apache.tapestry5.ioc.def.ModuleDef2;
 import org.apache.tapestry5.ioc.def.ServiceDef;
 import org.apache.tapestry5.ioc.def.ServiceDef2;
+import org.apache.tapestry5.ioc.def.ServiceDef3;
 import org.apache.tapestry5.ioc.internal.services.JustInTimeObjectCreator;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.ConcurrentBarrier;
@@ -92,7 +93,7 @@ public class ModuleImpl implements Modul
      */
     private final Map<String, Object> services = CollectionFactory.newCaseInsensitiveMap();
 
-    private final Map<String, ServiceDef2> serviceDefs = CollectionFactory.newCaseInsensitiveMap();
+    private final Map<String, ServiceDef3> serviceDefs = CollectionFactory.newCaseInsensitiveMap();
 
     /**
      * The barrier is shared by all modules, which means that creation of *any* service for any module is single
@@ -118,9 +119,9 @@ public class ModuleImpl implements Modul
         {
             ServiceDef sd = moduleDef.getServiceDef(id);
 
-            ServiceDef2 sd2 = InternalUtils.toServiceDef2(sd);
+            ServiceDef3 sd3 = InternalUtils.toServiceDef3(sd);
 
-            serviceDefs.put(id, sd2);
+            serviceDefs.put(id, sd3);
         }
     }
 
@@ -128,7 +129,7 @@ public class ModuleImpl implements Modul
     {
         assert InternalUtils.isNonBlank(serviceId);
         assert serviceInterface != null;
-        ServiceDef2 def = getServiceDef(serviceId);
+        ServiceDef3 def = getServiceDef(serviceId);
 
         // RegistryImpl should already have checked that the service exists.
         assert def != null;
@@ -200,7 +201,7 @@ public class ModuleImpl implements Modul
      *            collection into which proxies for eager loaded services are added (or null)
      * @return the service proxy
      */
-    private Object findOrCreate(final ServiceDef2 def, final Collection<EagerLoadServiceProxy> eagerLoadProxies)
+    private Object findOrCreate(final ServiceDef3 def, final Collection<EagerLoadServiceProxy> eagerLoadProxies)
     {
         final String key = def.getServiceId();
 
@@ -249,7 +250,7 @@ public class ModuleImpl implements Modul
         {
             public void run()
             {
-                for (ServiceDef2 def : serviceDefs.values())
+                for (ServiceDef3 def : serviceDefs.values())
                 {
                     if (def.isEagerLoad())
                         findOrCreate(def, proxies);
@@ -266,7 +267,7 @@ public class ModuleImpl implements Modul
      * @param eagerLoadProxies
      *            a list into which any eager loaded proxies should be added
      */
-    private Object create(final ServiceDef2 def, final Collection<EagerLoadServiceProxy> eagerLoadProxies)
+    private Object create(final ServiceDef3 def, final Collection<EagerLoadServiceProxy> eagerLoadProxies)
     {
         final String serviceId = def.getServiceId();
 
@@ -535,9 +536,6 @@ public class ModuleImpl implements Modul
                 });
 
                 plasticClass.addToString(description);
-
-                if (serviceImplementation != null)
-                    plasticClass.copyAnnotations(serviceImplementation);
             }
         });
 
@@ -602,7 +600,7 @@ public class ModuleImpl implements Modul
         return serviceDefs.containsKey(serviceDef.getServiceId());
     }
 
-    public ServiceDef2 getServiceDef(String serviceId)
+    public ServiceDef3 getServiceDef(String serviceId)
     {
         return serviceDefs.get(serviceId);
     }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java Wed Apr 20 22:45:44 2011
@@ -54,6 +54,7 @@ import org.apache.tapestry5.ioc.def.Deco
 import org.apache.tapestry5.ioc.def.ModuleDef;
 import org.apache.tapestry5.ioc.def.ServiceDef;
 import org.apache.tapestry5.ioc.def.ServiceDef2;
+import org.apache.tapestry5.ioc.def.ServiceDef3;
 import org.apache.tapestry5.ioc.internal.services.PerthreadManagerImpl;
 import org.apache.tapestry5.ioc.internal.services.RegistryShutdownHubImpl;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
@@ -75,7 +76,6 @@ import org.apache.tapestry5.ioc.services
 import org.apache.tapestry5.ioc.services.Status;
 import org.apache.tapestry5.ioc.services.SymbolSource;
 import org.apache.tapestry5.ioc.services.TapestryIOCModule;
-import org.apache.tapestry5.ioc.services.TypeCoercer;
 import org.apache.tapestry5.ioc.util.AvailableValues;
 import org.apache.tapestry5.ioc.util.UnknownValueException;
 import org.apache.tapestry5.services.UpdateListenerHub;
@@ -484,7 +484,7 @@ public class RegistryImpl implements Reg
         return module;
     }
 
-    public <T> Collection<T> getUnorderedConfiguration(ServiceDef serviceDef, Class<T> objectType)
+    public <T> Collection<T> getUnorderedConfiguration(ServiceDef3 serviceDef, Class<T> objectType)
     {
         lock.check();
 
@@ -497,7 +497,7 @@ public class RegistryImpl implements Reg
     }
 
     @SuppressWarnings("unchecked")
-    public <T> List<T> getOrderedConfiguration(ServiceDef serviceDef, Class<T> objectType)
+    public <T> List<T> getOrderedConfiguration(ServiceDef3 serviceDef, Class<T> objectType)
     {
         lock.check();
 
@@ -532,7 +532,7 @@ public class RegistryImpl implements Reg
         return orderer.getOrdered();
     }
 
-    public <K, V> Map<K, V> getMappedConfiguration(ServiceDef serviceDef, Class<K> keyType, Class<V> objectType)
+    public <K, V> Map<K, V> getMappedConfiguration(ServiceDef3 serviceDef, Class<K> keyType, Class<V> objectType)
     {
         lock.check();
 
@@ -567,7 +567,7 @@ public class RegistryImpl implements Reg
     }
 
     private <K, V> void addToMappedConfiguration(Map<K, V> map, Map<K, MappedConfigurationOverride<K, V>> overrides,
-            Map<K, ContributionDef> keyToContribution, Class<K> keyClass, Class<V> valueType, ServiceDef serviceDef,
+            Map<K, ContributionDef> keyToContribution, Class<K> keyClass, Class<V> valueType, ServiceDef3 serviceDef,
             final Module module)
     {
         String serviceId = serviceDef.getServiceId();
@@ -602,7 +602,7 @@ public class RegistryImpl implements Reg
         }
     }
 
-    private <T> void addToUnorderedConfiguration(Collection<T> collection, Class<T> valueType, ServiceDef serviceDef,
+    private <T> void addToUnorderedConfiguration(Collection<T> collection, Class<T> valueType, ServiceDef3 serviceDef,
             final Module module)
     {
         String serviceId = serviceDef.getServiceId();
@@ -638,7 +638,7 @@ public class RegistryImpl implements Reg
     }
 
     private <T> void addToOrderedConfiguration(Orderer<T> orderer,
-            Map<String, OrderedConfigurationOverride<T>> overrides, Class<T> valueType, ServiceDef serviceDef,
+            Map<String, OrderedConfigurationOverride<T>> overrides, Class<T> valueType, ServiceDef3 serviceDef,
             final Module module)
     {
         String serviceId = serviceDef.getServiceId();
@@ -739,7 +739,7 @@ public class RegistryImpl implements Reg
         return InternalUtils.toServiceLifecycle2(result);
     }
 
-    public List<ServiceDecorator> findDecoratorsForService(ServiceDef serviceDef)
+    public List<ServiceDecorator> findDecoratorsForService(ServiceDef3 serviceDef)
     {
         lock.check();
 
@@ -769,7 +769,7 @@ public class RegistryImpl implements Reg
         return orderer.getOrdered();
     }
 
-    public List<ServiceAdvisor> findAdvisorsForService(ServiceDef serviceDef)
+    public List<ServiceAdvisor> findAdvisorsForService(ServiceDef3 serviceDef)
     {
         lock.check();
 
@@ -1051,8 +1051,7 @@ public class RegistryImpl implements Reg
             }
         };
 
-        return proxyFactory.createProxy(interfaceClass, justInTime, implementationClass,
-                String.format("<Autobuild proxy %s(%s)>", implementationClass.getName(), interfaceClass.getName()));
+        return proxyFactory.createProxy(interfaceClass, justInTime, String.format("<Autobuild proxy %s(%s)>", implementationClass.getName(), interfaceClass.getName()));
     }
 
     private <T> T createReloadingProxy(Class<T> interfaceClass, final Class<? extends T> implementationClass,
@@ -1063,8 +1062,7 @@ public class RegistryImpl implements Reg
 
         getService(UpdateListenerHub.class).addUpdateListener(creator);
 
-        return proxyFactory.createProxy(interfaceClass, (ObjectCreator<T>) creator, implementationClass,
-                String.format("<Autoreload proxy %s(%s)>", implementationClass.getName(), interfaceClass.getName()));
+        return proxyFactory.createProxy(interfaceClass, (ObjectCreator<T>) creator, String.format("<Autoreload proxy %s(%s)>", implementationClass.getName(), interfaceClass.getName()));
     }
 
     public Object provideServiceProxy(String serviceId)

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java Wed Apr 20 22:45:44 2011
@@ -74,7 +74,6 @@ public class ReloadableObjectCreatorSour
         if (eagerLoad)
             reloadableCreator.createObject();
 
-        return proxyFactory.createProxy(serviceInterfaceClass, reloadableCreator, serviceImplementationClass,
-                getDescription());
+        return proxyFactory.createProxy(serviceInterfaceClass, reloadableCreator, getDescription());
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDefImpl.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDefImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDefImpl.java Wed Apr 20 22:45:44 2011
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2011 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
+// 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,
@@ -14,15 +14,23 @@
 
 package org.apache.tapestry5.ioc.internal;
 
+import java.lang.reflect.Method;
 import java.util.Set;
 
+import org.apache.tapestry5.func.F;
+import org.apache.tapestry5.func.Flow;
+import org.apache.tapestry5.func.Mapper;
+import org.apache.tapestry5.ioc.AnnotationProvider;
 import org.apache.tapestry5.ioc.ObjectCreator;
 import org.apache.tapestry5.ioc.ServiceBuilderResources;
+import org.apache.tapestry5.ioc.def.ServiceDef3;
+import org.apache.tapestry5.ioc.internal.services.AnnotationProviderChain;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 
-public class ServiceDefImpl implements InternalServiceDef
+public class ServiceDefImpl implements ServiceDef3
 {
     private final Class serviceInterface;
-    
+
     private final Class serviceImplementation;
 
     private final String serviceId;
@@ -38,18 +46,26 @@ public class ServiceDefImpl implements I
     private final boolean preventDecoration;
 
     /**
-     * @param serviceInterface  interface implemented by the service (or the service implementation class, for
-     *                          non-proxied services)
-     * @param serviceImplementation service implementation class if exists                
-     * @param serviceId         unique id for the service
-     * @param markers           set of marker annotation classes (will be retained not copied)
-     * @param scope             scope of the service (i.e., {@link org.apache.tapestry5.ioc.ScopeConstants#DEFAULT}).
-     * @param eagerLoad         if true, the service is realized at startup, rather than on-demand
-     * @param preventDecoration if true, the service may not be decorated
-     * @param source            used to create the service implementation when needed
+     * @param serviceInterface
+     *            interface implemented by the service (or the service implementation class, for
+     *            non-proxied services)
+     * @param serviceImplementation
+     *            service implementation class if exists
+     * @param serviceId
+     *            unique id for the service
+     * @param markers
+     *            set of marker annotation classes (will be retained not copied)
+     * @param scope
+     *            scope of the service (i.e., {@link org.apache.tapestry5.ioc.ScopeConstants#DEFAULT}).
+     * @param eagerLoad
+     *            if true, the service is realized at startup, rather than on-demand
+     * @param preventDecoration
+     *            if true, the service may not be decorated
+     * @param source
+     *            used to create the service implementation when needed
      */
-    ServiceDefImpl(Class serviceInterface, Class serviceImplementation, String serviceId, Set<Class> markers, String scope,
-                   boolean eagerLoad, boolean preventDecoration, ObjectCreatorSource source)
+    ServiceDefImpl(Class serviceInterface, Class serviceImplementation, String serviceId, Set<Class> markers,
+            String scope, boolean eagerLoad, boolean preventDecoration, ObjectCreatorSource source)
     {
         this.serviceInterface = serviceInterface;
         this.serviceImplementation = serviceImplementation;
@@ -103,8 +119,24 @@ public class ServiceDefImpl implements I
         return preventDecoration;
     }
 
-    public Class getImplementationClass()
+    private Flow<Class> searchPath()
+    {
+        return F.flow(serviceImplementation, serviceInterface).removeNulls();
+    }
+
+    public AnnotationProvider getClassAnnotationProvider()
+    {
+        return AnnotationProviderChain.create(searchPath().map(InternalUtils.CLASS_TO_AP_MAPPER).toList());
+    }
+
+    public AnnotationProvider getMethodAnnotationProvider(final String methodName, final Class... argumentTypes)
     {
-        return serviceImplementation;
+        return AnnotationProviderChain.create(searchPath().map(new Mapper<Class, Method>()
+        {
+            public Method map(Class element)
+            {
+                return InternalUtils.findMethod(element, methodName, argumentTypes);
+            }
+        }).map(InternalUtils.METHOD_TO_AP_MAPPER).toList());
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceResourcesImpl.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceResourcesImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceResourcesImpl.java Wed Apr 20 22:45:44 2011
@@ -19,23 +19,23 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.tapestry5.ioc.AnnotationProvider;
 import org.apache.tapestry5.ioc.Invokable;
 import org.apache.tapestry5.ioc.ObjectCreator;
 import org.apache.tapestry5.ioc.OperationTracker;
 import org.apache.tapestry5.ioc.ServiceBuilderResources;
 import org.apache.tapestry5.ioc.def.ServiceDef;
+import org.apache.tapestry5.ioc.def.ServiceDef3;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
 import org.slf4j.Logger;
 
 /**
  * Implementation of {@link org.apache.tapestry5.ioc.ServiceBuilderResources}. We just have one
- * implementation that
- * fills the purposes of methods that need a {@link org.apache.tapestry5.ioc.ServiceResources} (which includes service
- * decorator methods) as well as methods that need a {@link org.apache.tapestry5.ioc.ServiceBuilderResources} (which is
- * just service builder methods). Since it is most commonly used for the former, we'll just leave
- * the name as
- * ServiceResourcesImpl.
+ * implementation that fills the purposes of methods that need a {@link org.apache.tapestry5.ioc.ServiceResources}
+ * (which includes service decorator methods) as well as methods that need a
+ * {@link org.apache.tapestry5.ioc.ServiceBuilderResources} (which is just service builder methods). Since it is most
+ * commonly used for the former, we'll just leave the name as ServiceResourcesImpl.
  */
 @SuppressWarnings("all")
 public class ServiceResourcesImpl extends ObjectLocatorImpl implements ServiceBuilderResources
@@ -44,20 +44,20 @@ public class ServiceResourcesImpl extend
 
     private final Module module;
 
-    private final InternalServiceDef serviceDef;
+    private final ServiceDef3 serviceDef;
 
     private final Logger logger;
 
     private final PlasticProxyFactory proxyFactory;
 
-    public ServiceResourcesImpl(InternalRegistry registry, Module module, ServiceDef serviceDef,
+    public ServiceResourcesImpl(InternalRegistry registry, Module module, ServiceDef3 serviceDef,
             PlasticProxyFactory proxyFactory, Logger logger)
     {
         super(registry, module);
 
         this.registry = registry;
         this.module = module;
-        this.serviceDef = InternalUtils.toInternalServiceDef(serviceDef);
+        this.serviceDef = serviceDef;
         this.proxyFactory = proxyFactory;
         this.logger = logger;
     }
@@ -177,6 +177,16 @@ public class ServiceResourcesImpl extend
 
     public Class getImplementationClass()
     {
-        return serviceDef.getImplementationClass();
+        return null;
+    }
+
+    public AnnotationProvider getClassAnnotationProvider()
+    {
+        return serviceDef.getClassAnnotationProvider();
+    }
+
+    public AnnotationProvider getMethodAnnotationProvider(String methodName, Class... parameterTypes)
+    {
+        return serviceDef.getMethodAnnotationProvider(methodName, parameterTypes);
     }
 }

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AbtractAspectInterceptorBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AbtractAspectInterceptorBuilder.java?rev=1095544&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AbtractAspectInterceptorBuilder.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AbtractAspectInterceptorBuilder.java Wed Apr 20 22:45:44 2011
@@ -0,0 +1,47 @@
+// Copyright 2011 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.services;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import org.apache.tapestry5.ioc.AnnotationAccess;
+import org.apache.tapestry5.ioc.AnnotationProvider;
+import org.apache.tapestry5.ioc.services.AspectInterceptorBuilder;
+
+public abstract class AbtractAspectInterceptorBuilder<T> implements AspectInterceptorBuilder<T>
+{
+    protected final AnnotationAccess annotationAccess;
+
+    public AbtractAspectInterceptorBuilder(AnnotationAccess annotationAccess)
+    {
+        this.annotationAccess = annotationAccess;
+    }
+
+    public AnnotationProvider getClassAnnotationProvider()
+    {
+        return annotationAccess.getClassAnnotationProvider();
+    }
+
+    public AnnotationProvider getMethodAnnotationProvider(String methodName, Class... parameterTypes)
+    {
+        return annotationAccess.getMethodAnnotationProvider(methodName, parameterTypes);
+    }
+
+    public <T extends Annotation> T getMethodAnnotation(Method method, Class<T> annotationType)
+    {
+        return getMethodAnnotationProvider(method.getName(), method.getParameterTypes()).getAnnotation(annotationType);
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectDecoratorImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectDecoratorImpl.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectDecoratorImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectDecoratorImpl.java Wed Apr 20 22:45:44 2011
@@ -16,8 +16,10 @@ package org.apache.tapestry5.ioc.interna
 
 import java.lang.reflect.Method;
 
+import org.apache.tapestry5.ioc.AnnotationAccess;
 import org.apache.tapestry5.ioc.MethodAdvice;
 import org.apache.tapestry5.ioc.annotations.PreventServiceDecoration;
+import org.apache.tapestry5.ioc.internal.AnnotationAccessImpl;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.ioc.services.AspectDecorator;
 import org.apache.tapestry5.ioc.services.AspectInterceptorBuilder;
@@ -45,8 +47,13 @@ public class AspectDecoratorImpl impleme
         return builder.build();
     }
 
+    public <T> AspectInterceptorBuilder<T> createBuilder(Class<T> serviceInterface, final T delegate, String description)
+    {
+        return createBuilder(serviceInterface, delegate, new AnnotationAccessImpl(serviceInterface), description);
+    }
+
     public <T> AspectInterceptorBuilder<T> createBuilder(final Class<T> serviceInterface, final T delegate,
-            final String description)
+            AnnotationAccess annotationAccess, final String description)
     {
         assert serviceInterface != null;
         assert delegate != null;
@@ -55,7 +62,7 @@ public class AspectDecoratorImpl impleme
         // The inner class here prevents the needless creation of the AspectInterceptorBuilderImpl,
         // and the various Plastic related overhead, until there's some actual advice.
 
-        return new AspectInterceptorBuilder<T>()
+        return new AbtractAspectInterceptorBuilder<T>(annotationAccess)
         {
             private AspectInterceptorBuilder<T> builder;
 
@@ -82,7 +89,8 @@ public class AspectDecoratorImpl impleme
             private AspectInterceptorBuilder<T> getBuilder()
             {
                 if (builder == null)
-                    builder = new AspectInterceptorBuilderImpl<T>(proxyFactory, serviceInterface, delegate, description);
+                    builder = new AspectInterceptorBuilderImpl<T>(annotationAccess, proxyFactory, serviceInterface,
+                            delegate, description);
 
                 return builder;
             }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectInterceptorBuilderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectInterceptorBuilderImpl.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectInterceptorBuilderImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectInterceptorBuilderImpl.java Wed Apr 20 22:45:44 2011
@@ -14,28 +14,22 @@
 
 package org.apache.tapestry5.ioc.internal.services;
 
-import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.util.Arrays;
-import java.util.Map;
 import java.util.Set;
 
+import org.apache.tapestry5.ioc.AnnotationAccess;
+import org.apache.tapestry5.ioc.AnnotationProvider;
 import org.apache.tapestry5.ioc.MethodAdvice;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
-import org.apache.tapestry5.ioc.internal.util.OneShotLock;
-import org.apache.tapestry5.ioc.services.AspectInterceptorBuilder;
-import org.apache.tapestry5.ioc.services.ClassFab;
-import org.apache.tapestry5.ioc.services.ClassFabUtils;
-import org.apache.tapestry5.ioc.services.MethodSignature;
 import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
 import org.apache.tapestry5.plastic.PlasticClass;
 import org.apache.tapestry5.plastic.PlasticClassTransformation;
 import org.apache.tapestry5.plastic.PlasticField;
 
 @SuppressWarnings("all")
-public class AspectInterceptorBuilderImpl<T> implements AspectInterceptorBuilder<T>
+public class AspectInterceptorBuilderImpl<T> extends AbtractAspectInterceptorBuilder<T>
 {
     private final Class<T> serviceInterface;
 
@@ -45,9 +39,11 @@ public class AspectInterceptorBuilderImp
 
     private final PlasticClass plasticClass;
 
-    public AspectInterceptorBuilderImpl(PlasticProxyFactory plasticProxyFactory, Class<T> serviceInterface, T delegate,
-            String description)
+    public AspectInterceptorBuilderImpl(AnnotationAccess annotationAccess, PlasticProxyFactory plasticProxyFactory,
+            Class<T> serviceInterface, T delegate, String description)
     {
+        super(annotationAccess);
+
         this.serviceInterface = serviceInterface;
 
         transformation = plasticProxyFactory.createProxyTransformation(serviceInterface);
@@ -63,8 +59,6 @@ public class AspectInterceptorBuilderImp
         {
             plasticClass.introduceMethod(method).delegateTo(delegateField);
         }
-
-        plasticClass.copyAnnotations(delegate.getClass());
     }
 
     public void adviseMethod(Method method, MethodAdvice advice)
@@ -76,7 +70,11 @@ public class AspectInterceptorBuilderImp
             throw new IllegalArgumentException(String.format("Method %s is not defined for interface %s.", method,
                     serviceInterface));
 
-        plasticClass.introduceMethod(method).addAdvice(InternalUtils.toPlasticMethodAdvice(advice));
+        AnnotationProvider methodAnnotationProvider = getMethodAnnotationProvider(method.getName(),
+                method.getParameterTypes());
+
+        plasticClass.introduceMethod(method).addAdvice(
+                InternalUtils.toPlasticMethodAdvice(advice, methodAnnotationProvider));
     }
 
     public void adviseAllMethods(MethodAdvice advice)

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PerThreadServiceLifecycle.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PerThreadServiceLifecycle.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PerThreadServiceLifecycle.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PerThreadServiceLifecycle.java Wed Apr 20 22:45:44 2011
@@ -60,7 +60,6 @@ public class PerThreadServiceLifecycle i
 
         Class serviceInterface = resources.getServiceInterface();
 
-        return proxyFactory.createProxy(serviceInterface, perThreadCreator, resources.getImplementationClass(),
-                String.format("<PerThread Proxy for %s(%s)>", resources.getServiceId(), serviceInterface.getName()));
+        return proxyFactory.createProxy(serviceInterface, perThreadCreator, String.format("<PerThread Proxy for %s(%s)>", resources.getServiceId(), serviceInterface.getName()));
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java?rev=1095544&r1=1095543&r2=1095544&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java Wed Apr 20 22:45:44 2011
@@ -61,8 +61,7 @@ public class PlasticProxyFactoryImpl imp
         return manager.createProxyTransformation(interfaceType);
     }
 
-    public <T> T createProxy(final Class<T> interfaceType, final ObjectCreator<T> creator,
-            final Class<? extends T> annotationSource, final String description)
+    public <T> T createProxy(final Class<T> interfaceType, final ObjectCreator<T> creator, final String description)
     {
         assert creator != null;
         assert InternalUtils.isNonBlank(description);
@@ -93,9 +92,6 @@ public class PlasticProxyFactoryImpl imp
                 }
 
                 plasticClass.addToString(description);
-
-                if (annotationSource != null)
-                    plasticClass.copyAnnotations(annotationSource);
             }
         });
 

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=1095544&r1=1095543&r2=1095544&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 Wed Apr 20 22:45:44 2011
@@ -43,10 +43,13 @@ 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;
 import org.apache.tapestry5.ioc.AdvisorDef2;
+import org.apache.tapestry5.ioc.AnnotationAccess;
 import org.apache.tapestry5.ioc.AnnotationProvider;
 import org.apache.tapestry5.ioc.Configuration;
 import org.apache.tapestry5.ioc.IOCConstants;
@@ -78,9 +81,10 @@ import org.apache.tapestry5.ioc.def.Modu
 import org.apache.tapestry5.ioc.def.ModuleDef2;
 import org.apache.tapestry5.ioc.def.ServiceDef;
 import org.apache.tapestry5.ioc.def.ServiceDef2;
-import org.apache.tapestry5.ioc.internal.InternalServiceDef;
+import org.apache.tapestry5.ioc.def.ServiceDef3;
+import org.apache.tapestry5.ioc.internal.NullAnnotationProvider;
+import org.apache.tapestry5.ioc.internal.services.AnnotationProviderChain;
 import org.apache.tapestry5.ioc.services.ClassFabUtils;
-import org.apache.tapestry5.ioc.services.ClassFactory;
 import org.apache.tapestry5.ioc.services.Coercion;
 import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
 import org.apache.tapestry5.plastic.MethodAdvice;
@@ -107,6 +111,9 @@ public class InternalUtils
     private static final Pattern NAME_PATTERN = Pattern.compile("^[_|$]*([\\p{javaJavaIdentifierPart}]+?)[_|$]*$",
             Pattern.CASE_INSENSITIVE);
 
+    /** @since 5.3.0 */
+    public static AnnotationProvider NULL_ANNOTATION_PROVIDER = new NullAnnotationProvider();
+
     /**
      * Converts a method to a user presentable string using a {@link PlasticProxyFactory} to obtain a {@link Location}
      * (where possible). {@link #asString(Method)} is used under the covers, to present a detailed, but not excessive,
@@ -883,51 +890,113 @@ public class InternalUtils
                             constructor));
     }
 
-    public static InternalServiceDef toInternalServiceDef(final ServiceDef sd)
+    /** @since 5.3.0 */
+    public static final Mapper<Class, AnnotationProvider> CLASS_TO_AP_MAPPER = new Mapper<Class, AnnotationProvider>()
+    {
+        public AnnotationProvider map(final Class element)
+        {
+            return toAnnotationProvider(element);
+        }
+
+    };
+
+    /** @since 5.3.0 */
+    public static AnnotationProvider toAnnotationProvider(final Class element)
+    {
+        return new AnnotationProvider()
+        {
+            public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+            {
+                return annotationClass.cast(element.getAnnotation(annotationClass));
+            }
+        };
+    };
+
+    /** @since 5.3.0 */
+    public static final Mapper<Method, AnnotationProvider> METHOD_TO_AP_MAPPER = new Mapper<Method, AnnotationProvider>()
     {
-        if (sd instanceof InternalServiceDef)
-            return (InternalServiceDef) sd;
+        public AnnotationProvider map(final Method element)
+        {
+            return toAnnotationProvider(element);
+        }
+    };
+
+    public static final Method findMethod(Class containingClass, String methodName, Class... parameterTypes)
+    {
+        if (containingClass == null)
+            return null;
+
+        try
+        {
+            return containingClass.getMethod(methodName, parameterTypes);
+        }
+        catch (SecurityException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+        catch (NoSuchMethodException ex)
+        {
+            return null;
+        }
+    }
+
+    /** @since 5.3.0 */
+    public static ServiceDef3 toServiceDef3(ServiceDef sd)
+    {
+        if (sd instanceof ServiceDef3)
+            return (ServiceDef3) sd;
+
+        final ServiceDef2 sd2 = toServiceDef2(sd);
 
-        return new InternalServiceDef()
+        return new ServiceDef3()
         {
+            // ServiceDef3 methods:
+
+            public AnnotationProvider getClassAnnotationProvider()
+            {
+                return toAnnotationProvider(getServiceInterface());
+            }
+
+            public AnnotationProvider getMethodAnnotationProvider(final String methodName, final Class... argumentTypes)
+            {
+                return toAnnotationProvider(findMethod(getServiceInterface(), methodName, argumentTypes));
+            }
+
+            // ServiceDef2 methods:
+
             public boolean isPreventDecoration()
             {
-                return false;
+                return sd2.isPreventDecoration();
             }
 
             public ObjectCreator createServiceCreator(ServiceBuilderResources resources)
             {
-                return sd.createServiceCreator(resources);
+                return sd2.createServiceCreator(resources);
             }
 
             public String getServiceId()
             {
-                return sd.getServiceId();
+                return sd2.getServiceId();
             }
 
             public Set<Class> getMarkers()
             {
-                return sd.getMarkers();
+                return sd2.getMarkers();
             }
 
             public Class getServiceInterface()
             {
-                return sd.getServiceInterface();
+                return sd2.getServiceInterface();
             }
 
             public String getServiceScope()
             {
-                return sd.getServiceScope();
+                return sd2.getServiceScope();
             }
 
             public boolean isEagerLoad()
             {
-                return sd.isEagerLoad();
-            }
-
-            public Class getImplementationClass()
-            {
-                return null;
+                return sd2.isEagerLoad();
             }
         };
     }
@@ -939,11 +1008,15 @@ public class InternalUtils
 
         return new ServiceDef2()
         {
+            // ServiceDef2 methods:
+
             public boolean isPreventDecoration()
             {
                 return false;
             }
 
+            // ServiceDef methods:
+
             public ObjectCreator createServiceCreator(ServiceBuilderResources resources)
             {
                 return sd.createServiceCreator(resources);
@@ -1284,13 +1357,14 @@ public class InternalUtils
 
     /**
      * Converts old-style Tapestry IoC {@link org.apache.tapestry5.ioc.MethodAdvice} to modern
-     * Plastic {@link MethodAdvice}
+     * Plastic {@link MethodAdvice}.
      * 
      * @param iocMethodAdvice
      *            old style advice
      * @return new style advice
      */
-    public static MethodAdvice toPlasticMethodAdvice(final org.apache.tapestry5.ioc.MethodAdvice iocMethodAdvice)
+    public static MethodAdvice toPlasticMethodAdvice(final org.apache.tapestry5.ioc.MethodAdvice iocMethodAdvice,
+            final AnnotationProvider methodAnnotationProvider)
     {
         assert iocMethodAdvice != null;
 
@@ -1367,7 +1441,7 @@ public class InternalUtils
 
                     public <T extends Annotation> T getMethodAnnotation(Class<T> annotationClass)
                     {
-                        return invocation.getAnnotation(annotationClass);
+                        return methodAnnotationProvider.getAnnotation(annotationClass);
                     }
                 };
 
@@ -1375,4 +1449,18 @@ public class InternalUtils
             }
         };
     }
+
+    public static AnnotationProvider toAnnotationProvider(final Method element)
+    {
+        if (element == null)
+            return NULL_ANNOTATION_PROVIDER;
+
+        return new AnnotationProvider()
+        {
+            public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+            {
+                return element.getAnnotation(annotationClass);
+            }
+        };
+    }
 }