| 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); |
| } |
| } |