/*******************************************************************************
* 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.util;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.beanutils.ConstructorUtils;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jubula.rc.common.exception.StepExecutionException;
import org.eclipse.jubula.rc.common.exception.StepVerifyFailedException;
import org.eclipse.jubula.rc.common.logger.AutServerLogger;
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;
/**
* Util class for Reflection calls
* @author Bredex GmbH
* @created 27.10.2015
*/
public class ReflectionUtil {
/**
* Defines which string should be replaced with null
*/
private static final String JUBULA_NULL = "jb_null"; //$NON-NLS-1$
/**
* The logging.
*/
private static AutServerLogger log =
new AutServerLogger(ReflectionUtil.class);
/**
* private constructor, because this is a util class
*/
private ReflectionUtil() {
//Util class
}
/**
* Get instances of the given arguments
* @param args the values for the arguments
* @param argsSplit the argument separator
* @param parameterClasses the classes for the arguments
* @return Object array containing the created objects with the specified value
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws InstantiationException
*/
public static Object[] getParameterValues(
String args,
@Nullable String argsSplit,
Class<?>[] parameterClasses)
throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException, InstantiationException {
String[] argValues;
if (!StringUtils.isEmpty(argsSplit)) {
argValues = StringUtils.splitPreserveAllTokens(args, argsSplit);
} else {
argValues = new String[] { args };
}
if (argValues.length != parameterClasses.length) {
throw new StepExecutionException("Invalid number of parameters", //$NON-NLS-1$
EventFactory
.createActionError(TestErrorEvent.INVALID_INPUT));
}
Object[] argObjects = new Object[argValues.length];
for (int i = 0; i < argValues.length; i++) {
if (JUBULA_NULL.equalsIgnoreCase(argValues[i])) {
argObjects[i] = null;
} else {
argObjects[i] = ConstructorUtils
.invokeExactConstructor(parameterClasses[i], argValues[i]);
}
}
return argObjects;
}
/**
* Get class instances for a given list of fully qualified class names separated by ","
* @param signatureList the list of fqcn's
* @param classLoader the class loader which will be used to load the classes
* @return Array containing the class objects
* @throws ClassNotFoundException
*/
public static Class<?>[] getParameterClasses(String signatureList,
ClassLoader classLoader) throws ClassNotFoundException {
String[] sign = signatureList.split(StringConstants.COMMA);
Class<?>[] parameterClasses = new Class[sign.length];
for (int i = 0; i < sign.length; i++) {
parameterClasses[i] = Class.forName(sign[i], true, classLoader);
}
return parameterClasses;
}
/**
* invokes the specified method
* @param fqcn fully qualified class name
* @param name method name
* @param signature method signature
* @param args argument values
* @param argsSplit argument separator
* @param uiClassLoader class loader
* @return return value of the invoked method
* @throws Throwable
* @throws StepVerifyFailedException
*/
public static Object invokeMethod(
final String fqcn,
final String name,
@Nullable final String signature,
@Nullable final String args,
@Nullable final String argsSplit,
ClassLoader uiClassLoader)
throws Throwable, StepVerifyFailedException {
Class<?> clazz = Class.forName(fqcn, true, uiClassLoader);
Class[] parameterClasses = {};
Object[] argObjects = {};
if (!StringUtils.isEmpty(signature) && !StringUtils.isEmpty(args)) {
parameterClasses = ReflectionUtil
.getParameterClasses(signature, uiClassLoader);
argObjects = ReflectionUtil.getParameterValues(args, argsSplit,
parameterClasses);
}
return MethodUtils.invokeStaticMethod(clazz, name, argObjects,
parameterClasses);
}
/**
* invokes the specified method
* @param fqcn fully qualified class name
* @param name method name
* @param uiClassloader class loader
* @return return value of the invoked method
* @throws Throwable
* @throws StepVerifyFailedException
*/
public static Object invokeMethod(String fqcn, String name,
ClassLoader uiClassloader)
throws Throwable, StepVerifyFailedException {
Class<?> clazz = Class.forName(fqcn, true, uiClassloader);
return MethodUtils.invokeStaticMethod(clazz, name, null, null);
}
/**
* Throws the appropriate StepExecutionException for a given exception which
* occurred during the method invocation
*
* @param e the occurred exception
*/
public static void handleException(Throwable e) {
if (e instanceof InvocationTargetException) {
Throwable cause = e.getCause();
if (cause instanceof IllegalStateException) {
throw new StepExecutionException(e.toString(),
EventFactory.createVerifyFailed("", //$NON-NLS-1$
cause.toString()));
}
throw new StepExecutionException(cause.toString(),
EventFactory.createActionError(
TestErrorEvent.EXECUTION_ERROR,
new String[] {cause.toString()}));
}
if (e instanceof NullPointerException) {
log.warn("Nullpointer occured trying to invoke a method", e); //$NON-NLS-1$
throw new StepExecutionException(e.toString(),
EventFactory.createActionError(
TestErrorEvent.EXECUTION_ERROR,
new String[] {"Invoke method failed. The method might not be static"})); //$NON-NLS-1$
}
throw new StepExecutionException(e.toString(),
EventFactory.createActionError(
TestErrorEvent.EXECUTION_ERROR,
new String[] {e.toString()}));
}
}