(no commit message)
[utils] / support / test / org / wamblee / test / EventTracker.java
1 /*
2  * Copyright 2006 the original author or authors.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.wamblee.test;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27 /**
28  * Tracks the occurence of certain events in a test environment. Threads in a
29  * test environment tell the event tracker of the occurrence of certain events
30  * using {@link #eventOccurred(String)}. Test code inspects the events sent by
31  * a thread using {@link #isEventSent(Thread, String)}.
32  * 
33  * A record is kept of every event which is sent. Therefore, the occurence of a
34  * new event does not erase a previously sent event.
35  * 
36  * @param <Event> Type of event sent from test code. Usually String will be sufficient. 
37  *    The event type must provide a sensible implementation of {@link java.lang.Object#equals(java.lang.Object)}. 
38  */
39 public class EventTracker<Event> {
40
41     private static final Log LOG = LogFactory.getLog(EventTracker.class);
42
43     /**
44      * Map of Thread object to a list of events.
45      */
46     private Map<Thread, List<Event>> _events;
47
48     /**
49      * Constructs the event tracker.
50      * 
51      */
52     public EventTracker() {
53         _events = new HashMap<Thread, List<Event>>();
54     }
55
56     /**
57      * Called by a thread to inform that an event has occurred.
58      * 
59      * @param aEvent
60      *            Event that was sent.
61      */
62     public synchronized void eventOccurred(Event aEvent) {
63         LOG.info("Event '" + aEvent + "' sent.");
64         Thread current = Thread.currentThread();
65         List<Event> events = _events.get(current);
66         if (events == null) {
67             events = new ArrayList<Event>();
68             _events.put(current, events);
69         }
70         events.add(aEvent);
71     }
72
73     /**
74      * Checks if a specific event has happened in a specific thread.
75      * 
76      * @param aThread
77      *            Thread to check.
78      * @param aEvent
79      *            Event to check for.
80      * @return Whether or not the event was sent.
81      */
82     public synchronized boolean isEventSent(Thread aThread, Event aEvent) {
83         List<Event> events = _events.get(aThread);
84         if (events == null) {
85             return false;
86         }
87         return events.contains(aEvent);
88     }
89
90     /**
91      * Gets the events for a thread in the order they were sent
92      * 
93      * @param aThread
94      *            Thread to get events for.
95      * @return Events that were sent. A zero-sized array is returned if no
96      *         events were sent.
97      */
98     public synchronized List<Event> getEvents(Thread aThread) {
99         List<Event> events = _events.get(aThread);
100         if (events == null) {
101             events = Collections.emptyList();
102         }
103         return Collections.unmodifiableList(events);
104     }
105
106     /**
107      * Gets the number of times an event was sent.
108      * 
109      * @param aEvent
110      *            Event to check.
111      * @return Number of times it was reached.
112      */
113     public synchronized int getEventCount(Event aEvent) {
114         int count = 0;
115         for (Thread thread : _events.keySet()) {
116             List<Event> events = _events.get(thread);
117             for (Event event : events) {
118                 if (event.equals(aEvent)) {
119                     count++;
120                 }
121             }
122         }
123         return count;
124     }
125 }