333da1e78748e36510fd3985535c47caea65ae7a
[utils] /
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(Event)}. Test code inspects the events sent by a
31  * thread using {@link #isEventSent(Thread, Event)}.
32  * 
33  * A record is kept of every event which is sent. Therefore, the occurrence of a
34  * new event does not erase a previously sent event.
35  * 
36  * @param <Event>
37  *            Type of event sent from test code. Usually String will be
38  *            sufficient. The event type must provide a sensible implementation
39  *            of {@link java.lang.Object#equals(java.lang.Object)}.
40  *
41  * @author Erik Brakkee
42  */
43 public class EventTracker<Event> {
44
45     private static final Log LOG = LogFactory.getLog(EventTracker.class);
46
47     /**
48      * Map of Thread object to a list of events.
49      */
50     private Map<Thread, List<Event>> _events;
51
52     /**
53      * Constructs the event tracker.
54      * 
55      */
56     public EventTracker() {
57         clear();
58     }
59
60         public void clear() {
61                 _events = new HashMap<Thread, List<Event>>();
62         }
63
64     /**
65      * Called by a thread to inform that an event has occurred.
66      * 
67      * @param aEvent
68      *            Event that was sent.
69      */
70     public synchronized void eventOccurred(Event aEvent) {
71         LOG.info("Event '" + aEvent + "' sent.");
72         Thread current = Thread.currentThread();
73         List<Event> events = _events.get(current);
74         if (events == null) {
75             events = new ArrayList<Event>();
76             _events.put(current, events);
77         }
78         events.add(aEvent);
79     }
80
81     /**
82      * Checks if a specific event has happened in a specific thread.
83      * 
84      * @param aThread
85      *            Thread to check.
86      * @param aEvent
87      *            Event to check for.
88      * @return Whether or not the event was sent.
89      */
90     public synchronized boolean isEventSent(Thread aThread, Event aEvent) {
91         List<Event> events = _events.get(aThread);
92         if (events == null) {
93             return false;
94         }
95         return events.contains(aEvent);
96     }
97
98     /**
99      * Gets the events for a thread in the order they were sent
100      * 
101      * @param aThread
102      *            Thread to get events for.
103      * @return Events that were sent. A zero-sized array is returned if no
104      *         events were sent.
105      */
106     public synchronized List<Event> getEvents(Thread aThread) {
107         List<Event> events = _events.get(aThread);
108         if (events == null) {
109             events = Collections.emptyList();
110         }
111         return Collections.unmodifiableList(events);
112     }
113
114     /**
115      * Gets the number of times an event was sent summed up
116      * over all threads. 
117      * 
118      * @param aEvent
119      *            Event to check.
120      * @return Number of times it was reached.
121      */
122     public synchronized int getEventCount(Event aEvent) {
123         int count = 0;
124         for (Thread thread : _events.keySet()) {
125             List<Event> events = _events.get(thread);
126             for (Event event : events) {
127                 if (event.equals(aEvent)) {
128                     count++;
129                 }
130             }
131         }
132         return count;
133     }
134     
135     /**
136      * Gets the total event count over all threads. 
137      * @return
138      */
139     public synchronized int getEventCount() { 
140         int count = 0; 
141         for (Thread thread: _events.keySet()) { 
142                 count += _events.get(thread).size();
143         }
144         return count; 
145     }
146 }