| /* |
| * Copyright (c) 2011-2013, 2016 Eike Stepper (Berlin, Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Eike Stepper - initial API and implementation |
| */ |
| package org.eclipse.emf.cdo.tests.util; |
| |
| import org.eclipse.net4j.util.WrappedException; |
| import org.eclipse.net4j.util.event.IEvent; |
| import org.eclipse.net4j.util.event.IListener; |
| |
| import org.junit.Assert; |
| |
| import java.io.PrintStream; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Set; |
| |
| /** |
| * @author Caspar De Groot |
| */ |
| public class TestListener2 implements IListener |
| { |
| public static final int NO_TIME_STAMP = 0; |
| |
| private static final Set<Class<? extends IEvent>> NO_EVENT_CLASSES = Collections.emptySet(); |
| |
| private static final long DEFAULT_TIMEOUT = 3000; // 3 seconds |
| |
| private final Map<IEvent, Long> events = new LinkedHashMap<IEvent, Long>(); |
| |
| private final Collection<Class<? extends IEvent>> eventClasses; |
| |
| private long timeout; |
| |
| private String name; |
| |
| public TestListener2(Collection<Class<? extends IEvent>> eventClasses) |
| { |
| this(eventClasses, null); |
| } |
| |
| public TestListener2(Class<? extends IEvent> eventClass) |
| { |
| this(singleton(eventClass)); |
| } |
| |
| public TestListener2(Collection<Class<? extends IEvent>> eventClasses, String name) |
| { |
| this.eventClasses = eventClasses != null ? eventClasses : NO_EVENT_CLASSES; |
| this.name = name; |
| timeout = DEFAULT_TIMEOUT; |
| } |
| |
| public TestListener2(Class<? extends IEvent> eventClass, String name) |
| { |
| this(singleton(eventClass), name); |
| } |
| |
| public boolean isApplicable(IEvent event) |
| { |
| if (eventClasses.isEmpty()) |
| { |
| return true; |
| } |
| |
| Class<? extends IEvent> theClass = event.getClass(); |
| for (Class<? extends IEvent> eventClass : eventClasses) |
| { |
| if (eventClass.isAssignableFrom(theClass)) |
| { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| public void notifyEvent(IEvent event) |
| { |
| if (isApplicable(event)) |
| { |
| long timeStamp = System.currentTimeMillis(); |
| if (timeStamp == NO_TIME_STAMP) |
| { |
| throw new IllegalStateException("Regular time stamp is equal to NO_TIME_STAMP"); |
| } |
| |
| synchronized (this) |
| { |
| events.put(event, timeStamp); |
| notify(); |
| } |
| } |
| } |
| |
| public List<IEvent> getEvents() |
| { |
| synchronized (this) |
| { |
| return new ArrayList<IEvent>(events.keySet()); |
| } |
| } |
| |
| public long getTimeStamp(IEvent event) |
| { |
| Long timeStamp; |
| synchronized (this) |
| { |
| timeStamp = events.get(event); |
| } |
| |
| if (timeStamp == null) |
| { |
| return NO_TIME_STAMP; |
| } |
| |
| return timeStamp; |
| } |
| |
| public void setTimeout(long timeout) |
| { |
| this.timeout = timeout; |
| } |
| |
| public synchronized void waitFor(int n, long timeout) |
| { |
| long t = 0; |
| |
| synchronized (this) |
| { |
| while (events.size() < n) |
| { |
| if (timeout <= 0) |
| { |
| Assert.fail("Timed out"); |
| } |
| |
| try |
| { |
| t = System.currentTimeMillis(); |
| wait(timeout); |
| } |
| catch (InterruptedException ex) |
| { |
| throw WrappedException.wrap(ex); |
| } |
| |
| timeout -= System.currentTimeMillis() - t; |
| } |
| } |
| } |
| |
| public void waitFor(int i) |
| { |
| waitFor(i, timeout); |
| } |
| |
| public void clearEvents() |
| { |
| synchronized (this) |
| { |
| events.clear(); |
| } |
| } |
| |
| public String formatEvents(String prefix, String suffix) |
| { |
| StringBuilder builder = new StringBuilder(); |
| |
| synchronized (this) |
| { |
| for (Entry<IEvent, Long> entry : events.entrySet()) |
| { |
| builder.append(prefix + entry.getValue() + ": " + entry.getKey() + suffix); |
| } |
| } |
| |
| return builder.toString(); |
| } |
| |
| public void dump(PrintStream out) |
| { |
| out.println(this); |
| out.print(formatEvents(" ", "\n")); |
| } |
| |
| @Override |
| public String toString() |
| { |
| StringBuilder builder = new StringBuilder(TestListener2.class.getSimpleName()); |
| builder.append('['); |
| |
| if (name != null) |
| { |
| builder.append("name=\""); |
| builder.append(name); |
| builder.append('\"'); |
| } |
| |
| if (!eventClasses.isEmpty()) |
| { |
| if (name != null) |
| { |
| builder.append(", "); |
| } |
| |
| builder.append("eventClasses=["); |
| boolean first = true; |
| |
| for (Class<? extends IEvent> eventClass : eventClasses) |
| { |
| if (first) |
| { |
| first = false; |
| } |
| else |
| { |
| builder.append(", "); |
| } |
| |
| builder.append(eventClass.getSimpleName()); |
| } |
| |
| builder.append(']'); |
| } |
| |
| builder.append(']'); |
| return builder.toString(); |
| } |
| |
| private static Set<Class<? extends IEvent>> singleton(Class<? extends IEvent> eventClass) |
| { |
| Set<Class<? extends IEvent>> singleton = new HashSet<Class<? extends IEvent>>(); |
| singleton.add(eventClass); |
| return singleton; |
| } |
| } |