/*
 * This file is covered by the terms of the Common Public License v1.0.
 *
 * Copyright (c) SZEDER Gábor
 *
 * Parts of this software were developed within the JEOPARD research
 * project, which received funding from the European Union's Seventh
 * Framework Programme under grant agreement No. 216682.
 */

package de.fzi.cjunit.jpf.inside;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import de.fzi.cjunit.jpf.inside.NotifierMethods;


public class TestWrapper {

	String testClassName;
	String testMethodName;
	String expectedExceptionName;

	Object target;
	Method method;

	public TestWrapper(String... args) {
		parseArgs(args);
	}

	public void parseArgs(String... args) {
		if (args == null) {
			throw new RuntimeException("no command line arguments");
		}

		for (String arg : args) {
			if (arg.startsWith("--testclass=")) {
				testClassName = getArgumentValue(arg);
			} else if (arg.startsWith("--testmethod=")) {
				testMethodName = getArgumentValue(arg);
			} else if (arg.startsWith("--expectedexception=")) {
				expectedExceptionName = getArgumentValue(arg);
			} else {
				throw new RuntimeException("wrong command " +
						"line parameter: " + arg);
			}
		}
	}

	String getArgumentValue(String arg) {
		String value = arg.substring(arg.indexOf('=')+1);
		if (value.length() == 0) {
			throw new RuntimeException(
					"wrong command line parameter: " +
					"option without value: " + arg);
		}
		return value;
	}

	public void run() {
		try {
			createTest();
			runTest();
		} catch (Throwable t) {
			NotifierMethods.testFailed();
		}
	}

	public void createTest() throws IllegalArgumentException,
			SecurityException, InstantiationException,
			IllegalAccessException, InvocationTargetException,
			NoSuchMethodException, ClassNotFoundException {
		// The testing framework calling this has already checked
		// that both the class and the method exists, so they won't
		// throw any exceptions
		createTestObject();
		createTestMethod();
	}

	public void runTest() throws IllegalArgumentException,
			IllegalAccessException, AssertionError, Throwable {
		try {
			invokeTestMethod();
			if (isExpectingException()) {
				throw new AssertionError(
						"Expected exception: " +
						expectedExceptionName);
			}
		} catch (InvocationTargetException e) {
			Throwable cause = e.getCause();
			if (!isExpectingException()) {
				throw cause;
			}
			if (!isExpectedException(cause)) {
				String message
					= "Unexpected exception, expected<"
					+ expectedExceptionName + "> but was<"
					+ cause.getClass().getName() + ">";
				throw new Exception(message, cause);
			}
		}
	}

	public void invokeTestMethod() throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		method.invoke(target);
	}

	public boolean isExpectingException() {
		return expectedExceptionName != null;
	}

	public boolean isExpectedException(Throwable t)
			throws ClassNotFoundException {
		return Class.forName(expectedExceptionName)
				.isAssignableFrom(t.getClass());
	}

	public void createTestObject() throws
			IllegalArgumentException, SecurityException,
			InstantiationException, IllegalAccessException,
			InvocationTargetException, NoSuchMethodException,
			ClassNotFoundException {
		target = Class.forName(testClassName)
				.getConstructor()
				.newInstance();
	}

	public void createTestMethod() throws SecurityException,
			NoSuchMethodException {
		method = createMethod(testMethodName);
	}

	public Method createMethod(String methodName) throws SecurityException,
			NoSuchMethodException {
		return target.getClass().getMethod(methodName);
	}

	public static void main(String... args) {
		new TestWrapper(args).run();
	}
}

@@ -505,16 +505,26 @@
 per %7B%0A%0A%09
+protected 
 String t
@@ -534,24 +534,34 @@
 ClassName;%0A%09
+protected 
 String testM
@@ -572,16 +572,26 @@
 dName;%0A%09
+protected 
 String e
@@ -614,16 +614,26 @@
 Name;%0A%0A%09
+protected 
 Object t
@@ -640,16 +640,26 @@
 arget;%0A%09
+protected 
 Method m
@@ -725,29 +725,32 @@
 rgs);%0A%09%7D%0A%0A%09p
-ublic
+rotected
  void parseA
@@ -1279,16 +1279,26 @@
 %09%7D%0A%09%7D%0A%0A%09
+protected 
 String g
@@ -1535,37 +1535,40 @@
 rn value;%0A%09%7D%0A%0A%09p
-ublic
+rotected
  void run() %7B%0A%09%09
@@ -1669,29 +1669,32 @@
 ;%0A%09%09%7D%0A%09%7D%0A%0A%09p
-ublic
+rotected
  void create
@@ -2078,29 +2078,32 @@
 od();%0A%09%7D%0A%0A%09p
-ublic
+rotected
  void runTes
@@ -2722,29 +2722,32 @@
 %7D%0A%09%09%7D%0A%09%7D%0A%0A%09p
-ublic
+rotected
  void invoke
@@ -2870,37 +2870,40 @@
 (target);%0A%09%7D%0A%0A%09p
-ublic
+rotected
  boolean isExpec
@@ -2966,21 +2966,24 @@
 ;%0A%09%7D%0A%0A%09p
-ublic
+rotected
  boolean
@@ -3132,37 +3132,40 @@
 Class());%0A%09%7D%0A%0A%09p
-ublic
+rotected
  void createTest
@@ -3448,21 +3448,24 @@
 ;%0A%09%7D%0A%0A%09p
-ublic
+rotected
  void cr
@@ -3581,21 +3581,24 @@
 ;%0A%09%7D%0A%0A%09p
-ublic
+rotected
  Method 

fix visibility