You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mb...@apache.org on 2010/09/23 20:06:50 UTC

svn commit: r1000560 - in /commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub: AnnotationConfigurer.java AnnotationFactory.java

Author: mbenson
Date: Thu Sep 23 18:06:50 2010
New Revision: 1000560

URL: http://svn.apache.org/viewvc?rev=1000560&view=rev
Log:
clean up nested context code a bit + reuse classloader for children

Modified:
    commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationConfigurer.java
    commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationFactory.java

Modified: commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationConfigurer.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationConfigurer.java?rev=1000560&r1=1000559&r2=1000560&view=diff
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationConfigurer.java (original)
+++ commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationConfigurer.java Thu Sep 23 18:06:50 2010
@@ -18,14 +18,14 @@ package org.apache.commons.proxy2.stub;
 
 import java.lang.annotation.Annotation;
 
+import org.apache.commons.lang3.Pair;
+
 /**
  * Special {@link StubConfigurer} subclass that makes creating nested annotations (somewhat more) convenient.
  *
  * @param <A>
  */
 public abstract class AnnotationConfigurer<A extends Annotation> extends StubConfigurer<A> {
-    AnnotationFactory annotationFactory;
-
     /**
      * Create a child annotation of the specified type using a StubConfigurer.
      * @param <T>
@@ -38,7 +38,8 @@ public abstract class AnnotationConfigur
         if (configurer == this) {
             throw new IllegalArgumentException("An AnnotationConfigurer cannot configure its own child annotation");
         }
-        return requireAnnotationFactory().create(configurer);
+        Pair<AnnotationFactory, ClassLoader> context = requireContext();
+        return context.left.create(context.right, configurer);
     }
 
     /**
@@ -49,18 +50,21 @@ public abstract class AnnotationConfigur
      * @throws IllegalStateException if called other than when an {@link AnnotationFactory} is executing {@link #configure(Object)}
      */
     protected final <T extends Annotation> T child(Class<T> annotationType) {
-        return requireAnnotationFactory().create(annotationType);
+        Pair<AnnotationFactory, ClassLoader> context = requireContext();
+        return context.left.create(context.right, annotationType);
     }
 
     /**
-     * Get the registered annotationFactory.
-     * @return AnnotationFactory
+     * Get the registered {@link AnnotationFactory}/{@link ClassLoader}.
+     * @return a {@link Pair}
      * @throws IllegalStateException if no ongoing annotation stubbing could be detected
      */
-    synchronized AnnotationFactory requireAnnotationFactory() throws IllegalStateException {
-        if (annotationFactory == null) {
+    synchronized Pair<AnnotationFactory, ClassLoader> requireContext() throws IllegalStateException {
+        Pair<AnnotationFactory, ClassLoader> result = AnnotationFactory.CONTEXT.get();
+        if (result == null) {
             throw new IllegalStateException("Could not detect ongoing annotation stubbing");
         }
-        return annotationFactory;
+        return result;
     }
+
 }
\ No newline at end of file

Modified: commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationFactory.java?rev=1000560&r1=1000559&r2=1000560&view=diff
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationFactory.java (original)
+++ commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationFactory.java Thu Sep 23 18:06:50 2010
@@ -25,6 +25,7 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 
 import org.apache.commons.lang3.AnnotationUtils;
+import org.apache.commons.lang3.Pair;
 import org.apache.commons.proxy2.Interceptor;
 import org.apache.commons.proxy2.Invocation;
 import org.apache.commons.proxy2.Invoker;
@@ -47,6 +48,12 @@ public class AnnotationFactory {
     /** Statically available instance */
     public static final AnnotationFactory INSTANCE;
 
+    /**
+     * Record the context of a call for possible use by nested annotation creations.
+     */
+    static final ThreadLocal<Pair<AnnotationFactory, ClassLoader>> CONTEXT =
+        new ThreadLocal<Pair<AnnotationFactory, ClassLoader>>();
+
     private static final ProxyFactory PROXY_FACTORY;
 
     static {
@@ -175,21 +182,7 @@ public class AnnotationFactory {
             if (o instanceof StubConfigurer<?>) {
                 @SuppressWarnings("unchecked")
                 final StubConfigurer<Annotation> configurer = (StubConfigurer<Annotation>) o;
-                boolean deregisterFactory = false;
-                synchronized (configurer) {
-                    try {
-                        if (configurer instanceof AnnotationConfigurer<?>) {
-                            AnnotationConfigurer<?> annotationConfigurer = (AnnotationConfigurer<?>) configurer;
-                            deregisterFactory = true;
-                            annotationConfigurer.annotationFactory = AnnotationFactory.this;
-                        }
-                        configurer.configure(requireStubInterceptor(), stub);
-                    } finally {
-                        if (deregisterFactory) {
-                            ((AnnotationConfigurer<?>) configurer).annotationFactory = null;
-                        }
-                    }
-                }
+                configurer.configure(requireStubInterceptor(), stub);
             }
         }
     };
@@ -256,8 +249,12 @@ public class AnnotationFactory {
 
     private <A extends Annotation> A createInternal(ClassLoader classLoader, Object configurer) {
         final Object existingConfigurer = CONFIGURER.get();
+        final boolean outerContext = CONTEXT.get() == null;
         try {
             CONFIGURER.set(configurer);
+            if (outerContext) {
+                CONTEXT.set(Pair.of(this, classLoader));
+            }
             @SuppressWarnings("unchecked")
             final A result = (A) proxyFactory.createInvokerProxy(classLoader, ANNOTATION_INVOKER, getStubType());
             return result;
@@ -267,6 +264,9 @@ public class AnnotationFactory {
             } else {
                 CONFIGURER.set(existingConfigurer);
             }
+            if (outerContext) {
+                CONTEXT.remove();
+            }
         }
     }