4 * Copyright 2010 Codist Monk.
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
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
;
39 * @author codistmonk (creation 2010-07-04)
41 public final class EventsTestingTools
{
44 * @throws IllegalInstantiationException To prevent instantiation
46 private EventsTestingTools() {
47 throw new IllegalInstantiationException();
52 * @param <R> The (multi)listener recorder proxy type
53 * @param listenerTypes
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
>());
70 * @author codistmonk (creation 2010-06-18)
72 * @param <E> The base event type
74 public static interface EventRecorder
<E
> {
82 public abstract List
<E
> getEvents();
86 * @param <T> the expected event type
88 * <br>Range: {@code [0 .. this.getEvents().size() - 1]}
92 * @throws IndexOutOfBoundsException if {@code index} is out of range
94 public abstract <T
extends E
> T
getEvent(int index
);
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
>();
111 @SuppressWarnings("unchecked")
112 public final Object
invoke(final Object proxy
, final Method method
, final Object
[] arguments
)
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]);
126 public final List
<E
> getEvents() {
127 return Collections
.unmodifiableList(this.events
);
131 @SuppressWarnings("unchecked")
132 public final <T
extends E
> T
getEvent(final int index
) {
133 return (T
) this.getEvents().get(index
);