blob: b562de0defd3a3a4a607a21f42562efba6abd2ee [file] [log] [blame]
package org.testng.internal.invokers;
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.IInvokedMethodListener2;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.collections.Maps;
import java.util.Map;
import static org.testng.internal.invokers.InvokedMethodListenerMethod.AFTER_INVOCATION;
import static org.testng.internal.invokers.InvokedMethodListenerMethod.BEFORE_INVOCATION;
import static org.testng.internal.invokers.InvokedMethodListenerSubtype.EXTENDED_LISTENER;
import static org.testng.internal.invokers.InvokedMethodListenerSubtype.SIMPLE_LISTENER;
/**
* Hides complexity of calling methods of {@link IInvokedMethodListener} and
* {@link IInvokedMethodListener2}.
*
* @author Ansgar Konermann
*/
public class InvokedMethodListenerInvoker {
private InvokedMethodListenerMethod m_listenerMethod;
private ITestContext m_testContext;
private ITestResult m_testResult;
/**
* Creates a new invoker instance which can be used to call the specified {@code listenerMethod}
* on any number of {@link IInvokedMethodListener}s.
*
* @param listenerMethod method which should be called
* @param testResult test result which should be passed to the listener method upon invocation
* @param testContext test context which should be passed to the listener method upon invocation.
* This parameter is only used when calling methods on an {@link IInvokedMethodListener2}.
*/
public InvokedMethodListenerInvoker(InvokedMethodListenerMethod listenerMethod,
ITestResult testResult, ITestContext testContext) {
m_listenerMethod = listenerMethod;
m_testContext = testContext;
m_testResult = testResult;
}
/**
* Invoke the given {@code listenerInstance}, calling the method specified in the constructor of
* this {@link InvokedMethodListenerInvoker}.
*
* @param listenerInstance the listener instance which should be invoked.
* @param invokedMethod the {@link IInvokedMethod} instance which should be passed to the
* {@link IInvokedMethodListener#beforeInvocation(IInvokedMethod, ITestResult)},
* {@link IInvokedMethodListener#afterInvocation(IInvokedMethod, ITestResult)},
* {@link IInvokedMethodListener2#beforeInvocation(IInvokedMethod, ITestResult, ITestContext)}
* or {@link IInvokedMethodListener2#afterInvocation(IInvokedMethod, ITestResult, ITestContext)}
* method.
*/
@SuppressWarnings("unchecked")
public void invokeListener(IInvokedMethodListener listenerInstance,
IInvokedMethod invokedMethod) {
final InvocationStrategy strategy = obtainStrategyFor(listenerInstance, m_listenerMethod);
strategy.callMethod(listenerInstance, invokedMethod, m_testResult, m_testContext);
}
private InvocationStrategy obtainStrategyFor(IInvokedMethodListener listenerInstance,
InvokedMethodListenerMethod listenerMethod) {
InvokedMethodListenerSubtype invokedMethodListenerSubtype = InvokedMethodListenerSubtype
.fromListener(listenerInstance);
Map<InvokedMethodListenerMethod, InvocationStrategy> strategiesForListenerType = strategies
.get(invokedMethodListenerSubtype);
InvocationStrategy invocationStrategy = strategiesForListenerType.get(listenerMethod);
return invocationStrategy;
}
private static interface InvocationStrategy<LISTENER_TYPE extends IInvokedMethodListener> {
void callMethod(LISTENER_TYPE listener, IInvokedMethod invokedMethod, ITestResult testResult,
ITestContext testContext);
}
private static class InvokeBeforeInvocationWithoutContextStrategy implements
InvocationStrategy<IInvokedMethodListener> {
public void callMethod(IInvokedMethodListener listener, IInvokedMethod invokedMethod,
ITestResult testResult, ITestContext testContext) {
listener.beforeInvocation(invokedMethod, testResult);
}
}
private static class InvokeBeforeInvocationWithContextStrategy implements
InvocationStrategy<IInvokedMethodListener2> {
public void callMethod(IInvokedMethodListener2 listener, IInvokedMethod invokedMethod,
ITestResult testResult, ITestContext testContext) {
listener.beforeInvocation(invokedMethod, testResult, testContext);
}
}
private static class InvokeAfterInvocationWithoutContextStrategy implements
InvocationStrategy<IInvokedMethodListener> {
public void callMethod(IInvokedMethodListener listener, IInvokedMethod invokedMethod,
ITestResult testResult, ITestContext testContext) {
listener.afterInvocation(invokedMethod, testResult);
}
}
private static class InvokeAfterInvocationWithContextStrategy implements
InvocationStrategy<IInvokedMethodListener2> {
public void callMethod(IInvokedMethodListener2 listener, IInvokedMethod invokedMethod,
ITestResult testResult, ITestContext testContext) {
listener.afterInvocation(invokedMethod, testResult, testContext);
}
}
private static final Map<InvokedMethodListenerSubtype, Map<InvokedMethodListenerMethod,
InvocationStrategy>> strategies = Maps.newHashMap();
private static final Map<InvokedMethodListenerMethod, InvocationStrategy>
INVOKE_WITH_CONTEXT_STRATEGIES = Maps.newHashMap();
private static final Map<InvokedMethodListenerMethod, InvocationStrategy>
INVOKE_WITHOUT_CONTEXT_STRATEGIES = Maps.newHashMap();
static {
INVOKE_WITH_CONTEXT_STRATEGIES.put(BEFORE_INVOCATION,
new InvokeBeforeInvocationWithContextStrategy());
INVOKE_WITH_CONTEXT_STRATEGIES.put(AFTER_INVOCATION,
new InvokeAfterInvocationWithContextStrategy());
INVOKE_WITHOUT_CONTEXT_STRATEGIES.put(BEFORE_INVOCATION,
new InvokeBeforeInvocationWithoutContextStrategy());
INVOKE_WITHOUT_CONTEXT_STRATEGIES.put(AFTER_INVOCATION,
new InvokeAfterInvocationWithoutContextStrategy());
strategies.put(EXTENDED_LISTENER, INVOKE_WITH_CONTEXT_STRATEGIES);
strategies.put(SIMPLE_LISTENER, INVOKE_WITHOUT_CONTEXT_STRATEGIES);
}
}