/*******************************************************************************
* Copyright (c) 2015 BREDEX GmbH.
* 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:
* BREDEX GmbH - initial API and implementation
*******************************************************************************/
package org.eclipse.jubula.rc.common.tester;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jubula.rc.common.AUTServer;
import org.eclipse.jubula.rc.common.driver.IEventThreadQueuer;
import org.eclipse.jubula.rc.common.exception.StepExecutionException;
import org.eclipse.jubula.rc.common.tester.interfaces.ITester;
import org.eclipse.jubula.rc.common.util.ReflectionUtil;
import org.eclipse.jubula.tools.internal.constants.StringConstants;
import org.eclipse.jubula.tools.internal.objects.event.EventFactory;
import org.eclipse.jubula.tools.internal.objects.event.TestErrorEvent;
/**
* Tester class for the Reflection Component
*
* @author Bredex GmbH
* @created 27.10.2015
*/
public abstract class JavaReflectionTester implements ITester {
/**
* Queuer for executing the methods in the UI-Thread of the AUT
*/
private IEventThreadQueuer m_threadQueuer;
/**
* Constructor
*/
public JavaReflectionTester() {
m_threadQueuer = getEventThreadQueuer();
}
/**
* This is used to get the toolkit dependent Thread Queuer
* @return the UI-Thread queuer
*/
protected abstract IEventThreadQueuer getEventThreadQueuer();
/**
* Invokes the specified Method
*
* @param fqcn Fully qualified class name
* @param name name of the Method
* @param signature signature of the method
* @param args arguments for the method
* @param argsSplit separator for the Arguments
* @param timeout the timeout
*/
public void rcInvokeMethod(
final String fqcn,
final String name,
@Nullable final String signature,
@Nullable final String args,
@Nullable final String argsSplit,
int timeout) {
invokeMethod(fqcn, name, signature, args, argsSplit, false, timeout);
}
/**
* Invokes the specified Method
*
* @param fqcn Fully qualified class name
* @param name name of the Method
* @param signature signature of the method
* @param args arguments for the method
* @param argsSplit separator for the Arguments
* @param timeout the timeout
*/
public void rcInvokeExternalMethod(
final String fqcn,
final String name,
@Nullable final String signature,
@Nullable final String args,
@Nullable final String argsSplit,
int timeout) {
invokeMethod(fqcn, name, signature, args, argsSplit, true, timeout);
}
/**
* Invokes the specified Method
*
* @param fqcn Fully qualified class name
* @param name name of the Method
* @param signature signature of the method
* @param args arguments for the method
* @param argsSplit separator for the Arguments
* @param external whether the method comes
* from an external jar
* @param timeout the timeout
*/
private void invokeMethod(
final String fqcn,
final String name,
@Nullable final String signature,
@Nullable final String args,
@Nullable final String argsSplit,
boolean external,
int timeout) {
try {
Object result = m_threadQueuer.invokeAndWait("invokeMethod", //$NON-NLS-1$
createCallable(fqcn, name, signature, args,
argsSplit, external),
timeout);
} catch (TimeoutException e) {
throw new StepExecutionException(e.toString(), EventFactory
.createActionError(TestErrorEvent.CONFIRMATION_TIMEOUT));
}
}
/**
* Invokes the specified Method
*
* @param variableName name of the variable of the cap. This isn't used.
* @param fqcn Fully qualified class name
* @param name name of the Method
* @param signature signature of the method
* @param args arguments for the method
* @param argsSplit separator for the Arguments
* @param timeout the timeout
* @return returns the string representation of the return value of the
* invoked method
*/
public String rcInvokeMethodStoreReturn(
final String variableName,
final String fqcn,
final String name,
@Nullable final String signature,
@Nullable final String args,
@Nullable final String argsSplit,
int timeout) {
return invokeMethodStoreReturn(variableName, fqcn, name, signature,
args, argsSplit, false, timeout);
}
/**
* Invokes the specified Method
*
* @param fqcn Fully qualified class name
* @param name name of the Method
* @param signature signature of the method
* @param args arguments for the method
* @param argsSplit separator for the Arguments
* @param timeout the timeout
* @return returns the string representation of the return value of the
* invoked method
*/
public String rcInvokeMethodStoreReturnApi(
final String fqcn,
final String name,
@Nullable final String signature,
@Nullable final String args,
@Nullable final String argsSplit,
int timeout) {
return invokeMethodStoreReturn("PLACEHOLDER", fqcn, name, signature, //$NON-NLS-1$
args, argsSplit, false, timeout);
}
/**
* Invokes the specified external Method
*
* @param variableName name of the variable of the cap. This isn't used.
* @param fqcn Fully qualified class name
* @param name name of the Method
* @param signature signature of the method
* @param args arguments for the method
* @param argsSplit separator for the Arguments
* @param timeout the timeout
* @return returns the string representation of the return value of the
* invoked method
*/
public String rcInvokeExternalMethodStoreReturn(
final String variableName,
final String fqcn,
final String name,
@Nullable final String signature,
@Nullable final String args,
@Nullable final String argsSplit,
int timeout) {
return invokeMethodStoreReturn(variableName, fqcn, name, signature,
args, argsSplit, true, timeout);
}
/**
* Invokes the specified external Method
*
* @param fqcn Fully qualified class name
* @param name name of the Method
* @param signature signature of the method
* @param args arguments for the method
* @param argsSplit separator for the Arguments
* @param timeout the timeout
* @return returns the string representation of the return value of the
* invoked method
*/
public String rcInvokeExternalMethodStoreReturnApi(
final String fqcn,
final String name,
@Nullable final String signature,
@Nullable final String args,
@Nullable final String argsSplit,
int timeout) {
return invokeMethodStoreReturn("PLACEHOLDER", fqcn, name, signature, //$NON-NLS-1$
args, argsSplit, true, timeout);
}
/**
* Invokes the specified Method
*
* @param variableName name of the variable of the cap. This isn't used.
* @param fqcn Fully qualified class name
* @param name name of the Method
* @param signature signature of the method
* @param args arguments for the method
* @param argsSplit separator for the Arguments
* @param external whether the class is from an
* external jar
* @param timeout the timeout
* @return returns the string representation of the return value of the
* invoked method
*/
private String invokeMethodStoreReturn(
final String variableName,
final String fqcn,
final String name,
@Nullable final String signature,
@Nullable final String args,
@Nullable final String argsSplit,
boolean external,
int timeout) {
try {
Object result = m_threadQueuer.invokeAndWait("invokeMethod", //$NON-NLS-1$
createCallable(fqcn, name, signature, args,
argsSplit, external),
timeout);
return result == null ? StringConstants.NULL : result.toString();
} catch (TimeoutException e) {
throw new StepExecutionException(e.toString(), EventFactory
.createActionError(TestErrorEvent.CONFIRMATION_TIMEOUT));
}
}
/**
* Creates the runnable object which will invoke the specified Method
* @param fqcn fully qualified class name
* @param name method name
* @param signature method signature
* @param args method arguments
* @param argsSplit separator for the arguments
* @param external whether the method comes
* from an external jar
* @return the IRunnable object
*/
private Callable<Object> createCallable(
final String fqcn,
final String name,
@Nullable final String signature,
@Nullable final String args,
@Nullable final String argsSplit,
boolean external) {
final boolean isExternal = external;
return new Callable<Object>() {
public Object call() {
try {
ClassLoader uiClassloader;
if (isExternal) {
uiClassloader = AUTServer.getInstance().
getExternalLoader();
if (uiClassloader == null) {
throw new ClassNotFoundException("External jars could not be loaded."); //$NON-NLS-1$
}
} else {
uiClassloader = Thread.currentThread()
.getContextClassLoader();
}
return ReflectionUtil.invokeMethod(fqcn, name,
signature, args, argsSplit, uiClassloader);
} catch (Throwable e) {
ReflectionUtil.handleException(e);
}
return null;
}
};
}
/**
* Invokes the specified Method
*
* @param fqcn Fully qualified class name
* @param name name of the Method
* @param timeout the timeout
*/
public void rcInvokeMethod(
final String fqcn,
final String name,
int timeout) {
try {
Object result = m_threadQueuer.invokeAndWait("invokeMethod", //$NON-NLS-1$
createCallable(fqcn, name), timeout);
} catch (TimeoutException e) {
throw new StepExecutionException(e.toString(), EventFactory
.createActionError(TestErrorEvent.CONFIRMATION_TIMEOUT));
}
}
/**
* Invokes the specified Method
*
* @param variableName name of the variable of the cap. This isn't used.
* @param fqcn Fully qualified class name
* @param name name of the Method
* @param timeout the timeout
* @return returns the string representation of the return value of the
* invoked method
*/
public String rcInvokeMethodStoreReturn(
final String variableName,
final String fqcn,
final String name,
int timeout) {
try {
Object result = m_threadQueuer.invokeAndWait("invokeMethod", //$NON-NLS-1$
createCallable(fqcn, name), timeout);
return result == null ? StringConstants.NULL : result.toString();
} catch (TimeoutException e) {
throw new StepExecutionException(e.toString(), EventFactory
.createActionError(TestErrorEvent.CONFIRMATION_TIMEOUT));
}
}
/**
* Creates the runnable object which will invoke the specified Method
* @param fqcn fully qualified class name
* @param name method name
* @return the IRunnable object
*/
private Callable<Object> createCallable(final String fqcn,
final String name) {
return new Callable<Object>() {
public Object call() {
ClassLoader uiClassloader = Thread.currentThread()
.getContextClassLoader();
try {
return ReflectionUtil.invokeMethod(fqcn, name,
uiClassloader);
} catch (Throwable e) {
ReflectionUtil.handleException(e);
}
return null;
}
};
}
/**
* Not used because of default mapping
* @param graphicsComponent not used
*/
public void setComponent(Object graphicsComponent) {
// Nothing here.
}
/**
* Not used because of default mapping
* @return null
*/
public String[] getTextArrayFromComponent() {
// Nothing here.
return null;
}
}