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(); + } } }