[Aprog]
[aprog.git] / Aprog / test / net / sourceforge / aprog / events / EventsTestingTools.java
blob03f9f2750ed7849b61831afe594a925e1668d33a
1 /*
2 * The MIT License
3 *
4 * Copyright 2010 Codist Monk.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
25 package net.sourceforge.aprog.events;
27 import java.lang.reflect.Method;
28 import java.lang.reflect.Proxy;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.List;
33 import net.sourceforge.aprog.tools.AbstractInvocationHandler;
34 import net.sourceforge.aprog.tools.IllegalInstantiationException;
35 import net.sourceforge.aprog.tools.Tools;
37 /**
39 * @author codistmonk (creation 2010-07-04)
41 public final class EventsTestingTools {
43 /**
44 * @throws IllegalInstantiationException To prevent instantiation
46 private EventsTestingTools() {
47 throw new IllegalInstantiationException();
50 /**
52 * @param <R> The (multi)listener recorder proxy type
53 * @param listenerTypes
54 * <br>Not null
55 * @return
56 * <br>Not null
57 * <br>New
59 @SuppressWarnings("unchecked")
60 public static final <R extends EventRecorder<?>> R newEventRecorder(
61 final Class<?>... listenerTypes) {
62 return (R) Proxy.newProxyInstance(
63 Tools.getCallerClass().getClassLoader(),
64 Tools.append(listenerTypes, EventRecorder.class),
65 new RecorderInvocationHandler<Object>());
68 /**
70 * @author codistmonk (creation 2010-06-18)
72 * @param <E> The base event type
74 public static interface EventRecorder<E> {
76 /**
78 * @return
79 * <br>Not null
80 * <br>Not shared
82 public abstract List<E> getEvents();
84 /**
86 * @param <T> the expected event type
87 * @param index
88 * <br>Range: {@code [0 .. this.getEvents().size() - 1]}
89 * @return
90 * <br>Not null
91 * <br>Shared
92 * @throws IndexOutOfBoundsException if {@code index} is out of range
94 public abstract <T extends E> T getEvent(int index);
98 /**
100 * @author codistmonk (creation 2010-06-18)
102 private static class RecorderInvocationHandler<E> extends AbstractInvocationHandler implements EventRecorder<E> {
104 private final List<E> events;
106 RecorderInvocationHandler() {
107 this.events = new ArrayList<E>();
110 @Override
111 @SuppressWarnings("unchecked")
112 public final Object invoke(final Object proxy, final Method method, final Object[] arguments)
113 throws Throwable {
114 if (method.getDeclaringClass().isAssignableFrom(EventRecorder.class)) {
115 return method.invoke(this, arguments);
118 if (arguments.length == 1) {
119 this.events.add((E) arguments[0]);
122 return null;
125 @Override
126 public final List<E> getEvents() {
127 return Collections.unmodifiableList(this.events);
130 @Override
131 @SuppressWarnings("unchecked")
132 public final <T extends E> T getEvent(final int index) {
133 return (T) this.getEvents().get(index);