package m05bClasses.m05bDokusi.ws;

import java.util.Iterator;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;

public class M05BWSInvoker {

	/**
	 * Realiza la invocación a un servicio web dada la url, el método los nombres
	 * de los parámetros y sus valores
	 *
	 * @param url
	 *           La URL donde se encuentra el servicio web
	 * @param method
	 *           Método del servicio web que se va a invocar
	 * @param paramNames
	 *           Array de nombres de los parámetros
	 * @param paramValues
	 *           Array de valores de los parámetros
	 * @return String con la respuesta del servicio web
	 * @throws Exception
	 */
	 protected static String invoke(String url, String method, String[] paramNames, String[] paramValues) {
		String rtdo = "";
//		long initTime = 0;
//		long finishTime = 0;
		SOAPConnection con = null;
		try {
			MessageFactory mfactory = MessageFactory.newInstance();
			SOAPMessage message = mfactory.createMessage();
			SOAPPart soapPart = message.getSOAPPart();
			SOAPEnvelope envelope = soapPart.getEnvelope();
			SOAPBody body = envelope.getBody();
			Name name = envelope.createName(method, "", "http://www.openuri.org/");
			SOAPBodyElement element = body.addBodyElement(name);
			for (int i = 0; i < paramNames.length && i < paramValues.length; i++) {
				SOAPElement param = element.addChildElement(envelope.createName(paramNames[i]));
				param.addTextNode(paramValues[i]);
			}
			SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
			con = factory.createConnection();
//			initTime = Calendar.getInstance().getTimeInMillis();
			SOAPMessage response = con.call(message, url);
//			finishTime = Calendar.getInstance().getTimeInMillis();
//			logger.info("Total time (in seconds) for " + method + ": " + (finishTime -initTime));

			rtdo = getResult(response);
		} catch (NullPointerException e1) {
			rtdo = "ERROR invoking web service: " + e1.getMessage();
		} catch (Exception e) {
			rtdo = "ERROR invoking web service: " + e.getMessage();
		} finally {
			if (con != null) {
				try {
					con.close();
				} catch (Exception e) {
					// dummie
				}
			}
		}
		return rtdo;
	}

	/**
	 * Devuelve un String dado un mensaje SOAP y reemplaza los tags para capturar
	 * la respuesta
	 *
	 * @param response
	 *           Mensaje SOAP de respuesta
	 * @return String Mensaje como String
	 * @throws Exception
	 */
	protected static String getResult(SOAPMessage response) throws SOAPException {
		String rtdo = null;
		SOAPBodyElement soapBodyElement = getSOAPBodyElement(response);

		if (soapBodyElement instanceof SOAPFault) {
			SOAPFault faultElement = (SOAPFault) soapBodyElement;
			rtdo = "ERROR! :" + faultElement.toString();
		} else {
			Iterator iterator = soapBodyElement.getChildElements();
			while (iterator.hasNext()) {
				Object objElement = iterator.next();
				if (objElement instanceof SOAPElement) {
					SOAPElement element = (SOAPElement) objElement;
					// String elementName = element.getElementName().toString();
					rtdo = element.getValue();
					break;
				}/*
					 * else if (objElement instanceof
					 * weblogic.webservice.core.soap.SOAPElementImpl) {
					 * weblogic.webservice.core.soap.SOAPElementImpl element =
					 * (weblogic.webservice.core.soap.SOAPElementImpl) objElement;
					 * //String elementName = element.getElementName().toString();
					 * rtdo.append(element.getValue()); break; }
					 */
			}
		}
		return rtdo;
	}

	/**
	 * Devuelve un objeto SOAPBodyElement dado un mensaje SOAP
	 *
	 * @param response
	 *           Mensaje SOAP de respuesta
	 * @return SOAPBodyElement Mensaje como objeto SOAPBodyElement
	 * @throws Exception
	 */
	protected static SOAPBodyElement getSOAPBodyElement(SOAPMessage response) throws SOAPException {
		SOAPBodyElement rtdo = null;
		Iterator iterator = response.getSOAPPart().getEnvelope().getBody().getChildElements();
		while (iterator.hasNext()) {
			Object oUndefined = iterator.next();
			if (oUndefined instanceof SOAPBodyElement) {
				rtdo = (SOAPBodyElement) oUndefined;
				break;
			}
		}
		return rtdo;
	}// Fin getSOAPBodyElement
}