make annotationType available as early as possible for stubbed annotations; implement stubbed annotation arrays as nested annotation members
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/proxy/branches/version-2.0-work@1554962 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationBuilder.java b/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationBuilder.java
index 75b3ae3..48dafd8 100644
--- a/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationBuilder.java
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationBuilder.java
@@ -235,18 +235,21 @@
{
super(PROXY_FACTORY, type, invoker);
this.annotationType = type;
+ train(new AnnotationTypeTrainer<A>(type));
}
private AnnotationBuilder(Class<A> type, ObjectProvider<? extends A> provider)
{
super(PROXY_FACTORY, type, provider);
this.annotationType = type;
+ train(new AnnotationTypeTrainer<A>(type));
}
private AnnotationBuilder(Class<A> type, A target)
{
super(PROXY_FACTORY, type, target);
this.annotationType = type;
+ train(new AnnotationTypeTrainer<A>(type));
}
public AnnotationBuilder<A> withMembers(Map<String, ?> members)
@@ -259,18 +262,4 @@
{
return (AnnotationBuilder<A>) super.train(trainer);
}
-
- @Override
- public A build()
- {
- train(new AnnotationTrainer<A>(annotationType)
- {
- @Override
- protected void train(A trainee)
- {
- when(trainee.annotationType()).thenReturn(annotationType);
- }
- });
- return super.build();
- }
}
diff --git a/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationTypeTrainer.java b/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationTypeTrainer.java
new file mode 100644
index 0000000..5754458
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationTypeTrainer.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons.proxy2.stub;
+
+import java.lang.annotation.Annotation;
+
+class AnnotationTypeTrainer<R extends Annotation> extends AnnotationTrainer<R>
+{
+
+ AnnotationTypeTrainer(Class<R> annotationType)
+ {
+ super(annotationType);
+ }
+
+ @Override
+ protected void train(R trainee)
+ {
+ when(trainee.annotationType()).thenReturn(traineeType);
+ }
+
+}
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/commons/proxy2/stub/BaseAnnotationTrainer.java b/core/src/main/java/org/apache/commons/proxy2/stub/BaseAnnotationTrainer.java
index 39ae6b7..2a23fcf 100644
--- a/core/src/main/java/org/apache/commons/proxy2/stub/BaseAnnotationTrainer.java
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/BaseAnnotationTrainer.java
@@ -21,26 +21,31 @@
import org.apache.commons.proxy2.interceptor.InterceptorUtils;
-public abstract class BaseAnnotationTrainer<S extends BaseAnnotationTrainer<S, A>, A extends Annotation> extends BaseTrainer<S, A>
+public abstract class BaseAnnotationTrainer<S extends BaseAnnotationTrainer<S, A>, A extends Annotation> extends
+ BaseTrainer<S, A>
{
- protected BaseAnnotationTrainer() {
+ protected BaseAnnotationTrainer()
+ {
super();
}
- protected BaseAnnotationTrainer(Class<A> traineeType) {
+ protected BaseAnnotationTrainer(Class<A> traineeType)
+ {
super(traineeType);
}
protected class WhenAnnotation<R> extends WhenObject<R>
{
- public S thenStub(Class<R> type) {
+ public S thenStub(Class<R> type)
+ {
trainingContext().push(type);
trainingContext().then(InterceptorUtils.constant(trainingContext().pop(AnnotationInvoker.INSTANCE)));
return self();
}
@Override
- public S thenStub(BaseTrainer<?, R> trainer) {
+ public S thenStub(BaseTrainer<?, R> trainer)
+ {
final R trainee = trainingContext().push(trainer.traineeType);
trainer.train(trainee);
trainingContext().then(InterceptorUtils.constant(trainingContext().pop(AnnotationInvoker.INSTANCE)));
@@ -48,9 +53,59 @@
}
}
+ protected class WhenAnnotationArray<R> extends WhenObjectArray<R>
+ {
+ protected WhenAnnotationArray(Class<? extends R> componentType)
+ {
+ super(componentType);
+ }
+
+ @Override
+ public StubAnnotationArrayBuilder<R> thenBuildArray()
+ {
+ return new StubAnnotationArrayBuilder<R>(componentType);
+ }
+ }
+
+ protected class StubAnnotationArrayBuilder<R> extends StubArrayBuilder<R>
+ {
+ private final BaseTrainer<?, R> annotationTypeTrainer;
+
+ private <N extends Annotation> StubAnnotationArrayBuilder(final Class<? extends R> componentType)
+ {
+ super(componentType);
+ @SuppressWarnings("unchecked")
+ final Class<N> annotationType = (Class<N>) componentType;
+ @SuppressWarnings("unchecked")
+ final BaseTrainer<?, R> annotationTypeTrainer = (BaseTrainer<?, R>) new AnnotationTypeTrainer<N>(
+ annotationType);
+ this.annotationTypeTrainer = annotationTypeTrainer;
+ }
+
+ @Override
+ public StubAnnotationArrayBuilder<R> addElement(BaseTrainer<?, R> trainer)
+ {
+ final R trainee = trainingContext().push(trainer.traineeType);
+
+ annotationTypeTrainer.train(trainee);
+ trainer.train(trainee);
+
+ elements.add(trainingContext().<R> pop());
+ return this;
+ }
+ }
+
@Override
- public <R> WhenAnnotation<R> when(R expression) {
+ public <R> WhenAnnotation<R> when(R expression)
+ {
return new WhenAnnotation<R>();
}
+ @Override
+ public <R> WhenAnnotationArray<R> when(R[] expression)
+ {
+ @SuppressWarnings("unchecked")
+ final Class<? extends R> componentType = (Class<? extends R>) expression.getClass().getComponentType();
+ return new WhenAnnotationArray<R>(componentType);
+ }
}
diff --git a/core/src/main/java/org/apache/commons/proxy2/stub/BaseTrainer.java b/core/src/main/java/org/apache/commons/proxy2/stub/BaseTrainer.java
index 6c97c8b..f053875 100644
--- a/core/src/main/java/org/apache/commons/proxy2/stub/BaseTrainer.java
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/BaseTrainer.java
@@ -300,9 +300,9 @@
protected class WhenObjectArray<R> extends BaseWhen<R[]>
{
- private final Class<? extends R> componentType;
+ protected final Class<? extends R> componentType;
- private WhenObjectArray(Class<? extends R> componentType)
+ protected WhenObjectArray(Class<? extends R> componentType)
{
this.componentType = componentType;
}
@@ -321,10 +321,10 @@
protected class StubArrayBuilder<R>
{
- private final Class<? extends R> componentType;
- private final List<R> elements = new ArrayList<R>();
+ protected final List<R> elements = new ArrayList<R>();
+ protected final Class<? extends R> componentType;
- private StubArrayBuilder(Class<? extends R> componentType)
+ protected StubArrayBuilder(Class<? extends R> componentType)
{
this.componentType = componentType;
}
diff --git a/test/src/test/java/org/apache/commons/proxy2/stub/AnnotationBuilderTest.java b/test/src/test/java/org/apache/commons/proxy2/stub/AnnotationBuilderTest.java
index 5a010be..d6f2bf0 100644
--- a/test/src/test/java/org/apache/commons/proxy2/stub/AnnotationBuilderTest.java
+++ b/test/src/test/java/org/apache/commons/proxy2/stub/AnnotationBuilderTest.java
@@ -102,6 +102,41 @@
assertEquals(Object.class, customAnnotation.someType());
}
+ @Test
+ public void testNestedStubbedAnnotationArray()
+ {
+ final NestingAnnotation nestingAnnotation = AnnotationBuilder.of(NestingAnnotation.class)
+ .train(new AnnotationTrainer<NestingAnnotation>()
+ {
+
+ @Override
+ protected void train(NestingAnnotation trainee)
+ {
+ when(trainee.children()).thenBuildArray().addElement(new AnnotationTrainer<CustomAnnotation>()
+ {
+ @Override
+ protected void train(CustomAnnotation trainee)
+ {
+ when(trainee.finiteValues()).thenReturn(FiniteValues.ONE, FiniteValues.THREE);
+ }
+ }).addElement(new AnnotationTrainer<CustomAnnotation>()
+ {
+ @Override
+ protected void train(CustomAnnotation trainee)
+ {
+ when(trainee.finiteValues()).thenReturn(FiniteValues.TWO);
+ }
+ }).build();
+ }
+ }).build();
+
+ assertNull(nestingAnnotation.child());
+ assertEquals(2, nestingAnnotation.children().length);
+ assertArrayEquals(new FiniteValues[] { FiniteValues.ONE, FiniteValues.THREE },
+ nestingAnnotation.children()[0].finiteValues());
+ assertArrayEquals(new FiniteValues[] { FiniteValues.TWO }, nestingAnnotation.children()[1].finiteValues());
+ }
+
@Test(expected = IllegalArgumentException.class)
public void testBadMemberMap()
{
@@ -114,6 +149,8 @@
CustomAnnotation child();
String somethingElse();
+
+ CustomAnnotation[] children() default {};
}
public @interface CustomAnnotation