/*
 * Copyright (c) 2002, 2003, 2004 Active Endpoints, Inc.
 *
 * This program is licensed under the terms of the GNU General Public License
 * Version 2 (the "License") as published by the Free Software Foundation, and
 * the ActiveBPEL Licensing Policies (the "Policies").  A copy of the License
 * and the Policies were distributed with this program.
 *
 * The License is available at:
 * http://www.gnu.org/copyleft/gpl.html
 *
 * The Policies are available at:
 * http://www.activebpel.org/licensing/index.html
 *
 * Unless required by applicable law or agreed to in writing, this program is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License and the Policies for
 * specific language governing the use of this program.
 */
package org.activebpel.demo.client;
import org.activebpel.demo.Constants;
import org.activebpel.demo.loanProcessFault;
import org.activebpel.demo.util.RuntimeParams;
import java.math.BigInteger;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.AxisFault;
import javax.xml.rpc.ParameterMode;

/**
 * A client that calls both the assessor and approver Web services directly
 * and compares the returned values to the expected values defined in the
 * config file.
 *
 * @author Jim Menard, <a href="mailto:jimm@activebpel.org">jimm@activebpel.org</a>
 */
public class WebServicesTestClient {

protected int numTests;
protected int numErrors;

/**
 * Creates and runs a Web service test client that prints out a JUnit-like
 * result message.
 */
public static void main(String[] args) {
    try {
	new WebServicesTestClient().run();
    }
    catch (Exception e) {
	e.printStackTrace();
    }
}

/**
 * Calls two Web services and prints out a JUnit-like result message.
 */
public void run() throws Exception {
    RuntimeParams rp = new RuntimeParams();

    numTests = numErrors = 0;

    testWebService(rp, "assessor");
    testWebService(rp, "approver");

    System.out.println();
    System.out.println((numErrors == 0 ? "OK " : "ERRORS ")
		       + numTests + " test" + (numTests == 1 ? "" : "s") + "; "
		       + numErrors + " error" + (numErrors == 1 ? "" : "s"));
}

/**
 * Calls a Web service and compares the returned result with the expected
 * value found in the config file. If they are different, increments the
 * error count and prints "E". If they are the same, prints ".".
 *
 * @param rp retrieves values from the config file
 * @param serviceName the WSDL Web service name
 * @param expectedAnswerXpathFragment the expected answer is found in
 * the config file at /rundata/<var>expectedAnswerXpathFragment</var>
 */
protected void testWebService(RuntimeParams rp, String serviceName)
    throws Exception
{
    ++numTests;

    // Call Web service using RPC
    Call call = createCall(rp, serviceName);
    String result = null;
    try {
	result = (String)call.invoke(new Object[] {
	    rp.getText("/rundata/" + serviceName + "-test-client/firstName"),
	    rp.getText("/rundata/" + serviceName + "-test-client/name"),
	    new BigInteger(rp.getText("/rundata/" + serviceName
				      + "-test-client/amount"))
	});
    }
    catch (AxisFault af) {
	if (loanProcessFault.hasMagicFaultErrorCode(af))
	    result = Constants.MAGIC_FAULT_STRING;
	else
	    result = af.toString();
    }
    catch (Exception e) {
	result = "unexpected exception seen: " + e.toString();
    }

    System.out.println(serviceName + ": result = " + result);
}

/**
 * Creates and returns an RPC SOAP call. The call's parameter values are taken
 * from the config file.
 *
 * @param rp retrieves values from the config file
 * @param serviceName the WSDL Web service name
 * @return an RPC SOAP call
 */
protected Call createCall(RuntimeParams rp, String serviceName)
    throws Exception
{
    Service service = new Service();
    Call call = (Call)service.createCall();

    String urlString = rp.getAttr("/rundata/" + serviceName + "-test-client",
				  "url");
    call.setTargetEndpointAddress(new java.net.URL(urlString));
    call.setOperationName(rp.getAttr("/rundata/" + serviceName + "-test-client",
				     "operation"));

    call.addParameter("firstName", org.apache.axis.Constants.XSD_STRING,
		      ParameterMode.IN);
    call.addParameter("name", org.apache.axis.Constants.XSD_STRING,
		      ParameterMode.IN);
    call.addParameter("amount", org.apache.axis.Constants.XSD_INTEGER,
		      ParameterMode.IN);
    call.setReturnType(org.apache.axis.Constants.XSD_STRING);

    return call;
}

}
