org.callbackparams.sandbox
Interface Collector<A extends Annotation>
public interface Collector<A extends Annotation>
When used as a callback-interface, this single-method interface leverages
bleeding-edge framework features that allows callback-value declaration
through annotations.
The example use-case looks something like this ...
@Retention(RetentionPolicy.RUNTIME)
@interface Throws {
Class<? extends Exception> value();
}
@RunWith(CallbackParamsRunner
)
public class MyTest {
Set<Class<?>> expectedExceptions = new HashSet();
@Before
public void collectExpectedExceptions(Collector<Throws> exceptionCollector) { // (1)
exceptionCollector.collect(expectedExceptions);
}
@Test
public void runTest(DummyCallbackInterface callback) { // (2)
try {
// ...
// Test-case execution functionality goes here
// ...
assertTrue("Expected exception(s): " + expectedExceptions,
expectedExceptions.isEmpty()
} catch (Exception x) {
assertTrue("Expected exception(s) " + expectedExceptions + " but was " + x.getClass(),
expectedExceptions.contains(x.getClass());
}
}
enum MyEnum implements DummyCallbackInterface {
@Throws(IllegalArgumentException.class) EMPTY(""),
@Throws(IllegalArgumentException.class) BLANK(" "),
@Throws(NullPointerException.class) NULL(null),
FOO("foo"), BAR("bar");
// ...
// enum-body goes here
// ...
}
}
The above test-class uses two callback-interfaces -
DummyCallbackInterface
(2)
and Collector
(1).
Five callback-values are provided by the enum MyEnum
and since
the enum implements DummyCallbackInterface
by itself, there will
be exactly one callback-value for DummyCallbackInterface
per
test-run. On the other hand -
Collector
is not implemented which implies there
won't be any Collector
callback-values for any of the test-runs.
However, what really happens is that three of the MyEnum
constants (EMPTY, BLANK & NULL) will actually produce one callback-value
each, which collect(Collection)
implementation
will add the class-instance of their
respective Throws
annotation to the argument collection. The
explanation to this magic is nested within the interface
Collector
, where there is a class-declaration that will work as
a backup Collector
factory for every enum constant that neither
implements Collector
nor provides any implementation
through CallbackFactory.getCallback()
. The
Collector
factory will check its callback-declaration for
a generic parameter annotation-class (i.e. Throws
in the
above case at (1)) and, if an enum-constant is annotated with that very
annotation class, the return-value(s) of the annotation's
value()
method
will be added to the argument collection in the resulting
collect(Collection)
implementation.
The nested
factory-class takes advantage of a bleeding-edge (i.e. not yet stable) API,
which primary purpose is to provide shortcuts
frequent for cross-cutting concerns that through annotations can
eliminate considerable amounts of copy-paste code.
- Author:
- Henrik Kaipe
Method Summary |
|
collect(Collection<T> collection)
Implementations are expected to add objects to the collection. |
collect
<T> void collect(Collection<T> collection)
- Implementations are expected to add objects to the collection.
Copyright © 2010-2013 Henrik Kaipe. All Rights Reserved.