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

Nested Class Summary
static class Collector.CollectorFactory
          Works as a backup Collector factory for every enum constant that neither implements Collector nor provides any implementation through CallbackFactory.getCallback().
 
Method Summary
<T> void
collect(Collection<T> collection)
          Implementations are expected to add objects to the collection.
 

Method Detail

collect

<T> void collect(Collection<T> collection)
Implementations are expected to add objects to the collection.



Copyright © 2010-2013 Henrik Kaipe. All Rights Reserved.