/**
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 *
 * Copyright (C)
 * <a href="http://www.inab.org">Spanish National Institute of Bioinformatics (INB)</a>
 * <a href="http://www.bsc.es">Barcelona Supercomputing Center (BSC)</a>
 * <a href="http://inb.bsc.es">Computational Node 6</a>
 */

package org.inb.biomoby.shared.wsrf;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.dom.DOMResult;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;
import org.inb.biomoby.client.MobyDispatch;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * The class is used to extract "url" address and "ServiceInvocationId" parameter from W3CEndpointReference
 * 
 * @author Dmitry Repchevsky
 */

public class MobyEndpointReference 
{
    public final static String REF_PARAM_NAME = "ServiceInvocationId";
    public final static String XPATH_PARAM_NAME = "Expression";

    public final W3CEndpointReference ref;

    public final String url;
    public final String invocationId;
    public final String expression;

    public MobyEndpointReference(String url, String invocationId, String expression)
    {
        this.url = url;
        this.invocationId = invocationId;
        this.expression = expression;
        
        W3CEndpointReference ref;
        try
        {
            W3CEndpointReferenceBuilder wsaBuilder = new W3CEndpointReferenceBuilder();
            wsaBuilder.address(url);

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.newDocument();            

            Element invocationIdParam = doc.createElementNS(MobyDispatch.NAMESPACE, REF_PARAM_NAME);
            invocationIdParam.setTextContent(invocationId);

            wsaBuilder.referenceParameter(invocationIdParam);

            Element expressionParam = doc.createElementNS(MobyDispatch.NAMESPACE, XPATH_PARAM_NAME);
            expressionParam.setTextContent(expression);

            wsaBuilder.referenceParameter(expressionParam);

            ref = wsaBuilder.build();
        }
        catch(Exception ex)
        {
            ref = null;
        }
        
        this.ref = ref;
    }
    
    public MobyEndpointReference(W3CEndpointReference ref) throws ParserConfigurationException
    {
        this.ref = ref;

        String url = "";
        String invocationId = "";
        String expression = null;

        Document doc = getAsDocument(ref);
        NodeList nodes = doc.getDocumentElement().getChildNodes();

        for (int i = 0, n = nodes.getLength(); i < n; i++)
        {
            Node node = nodes.item(i);

            if ("Address".equals(node.getLocalName()))
            {
                url = node.getTextContent();
            }
            else if ("ReferenceParameters".equals(node.getLocalName()))
            {
                NodeList parameters = node.getChildNodes();

                for (int j = 0; j < parameters.getLength(); j++)
                {
                    Node parameter = parameters.item(j);

                    if (REF_PARAM_NAME.equals(parameter.getLocalName()))
                    {
                        invocationId = parameter.getTextContent();
                    }
                    else if (XPATH_PARAM_NAME.equals(parameter.getLocalName()))
                    {
                        expression = parameter.getTextContent();
                    }
                }
            }
        }

        this.url = url;
        this.invocationId = invocationId;
        this.expression = expression;
    }

    private static Document getAsDocument(W3CEndpointReference ref) throws ParserConfigurationException
    {
        DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
        Document doc = docBuilder.newDocument();

        DOMResult result = new DOMResult(doc);
        ref.writeTo(result);

        return doc;
    }
}
