/*
 * The contents of this file are subject to the terms 
 * of the Common Development and Distribution License 
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at 
 * https://glassfish.dev.java.net/public/CDDLv1.0.html or
 * glassfish/bootstrap/legal/CDDLv1.0.txt.
 * See the License for the specific language governing 
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL 
 * Header Notice in each file and include the License file 
 * at glassfish/bootstrap/legal/CDDLv1.0.txt.  
 * If applicable, add the following below the CDDL Header, 
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information: 
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 */
package com.sun.enterprise.jbi.serviceengine.core;

import org.w3c.dom.*;

import javax.xml.namespace.QName;
import java.util.StringTokenizer;


/**
 * This class reads the SU jbi.xml and loads up the values.
 *
 * @author Sun Microsystems
 */
public class JBIDescriptorReader {
    /**
     * Document object of the XML config file.
     */
    private Document mDoc;

    /**
     * List of endpoints in the SU jbi.xml.
     */
    private DescriptorEndpointInfo [] mEPList;

    /**
     * Number of consumers.
     */
    private int mNoOfConsumers;

    /**
     * Number of providers.
     */
    private int mNoOfProviders;

    /**
     * Type of deployment, WSDL, XML or WSDL11
     */
    private String mType;
    private String mSu_Name;

    /**
     * Creates a new ConfigReader object.
     */
    JBIDescriptorReader(String su_Name) {
        mSu_Name = su_Name;
    }


    DescriptorEndpointInfo[] getEndpoints() {
        return mEPList;
    }

    /**
     * Returns the number of consumer endpoints.
     *
     * @return consumer endpoint count.
     */
    int getConsumerCount() {
        return mNoOfConsumers;
    }

    /**
     * Sets the endpoitn attributes.
     *
     * @param node provider/consumer node.
     * @param ep   endpoint information.
     */
    private void setEndpoint(Node node, DescriptorEndpointInfo ep) {
        NamedNodeMap map = node.getAttributes();

        String epname = map.getNamedItem("endpoint-name").getNodeValue();
        String sername = map.getNamedItem("service-name").getNodeValue();
        String intername = map.getNamedItem("interface-name").getNodeValue();
        ep.setServiceName(new QName(getNamespace(sername), getLocalName(sername)));
        ep.setInterfaceName(new QName(getNamespace(intername), getLocalName(intername)));
        ep.setEndpointName(epname);
    }

    /**
     * Sets the type of artifact.
     */
    private void setType(String type) {
        mType = type;
    }

    /**
     * Gets the type of artifact
     */

    String getType() {
        return mType;
    }

    private void setArtifacts() {
        NodeList namelist = mDoc.getElementsByTagNameNS("*", "artifactstype");

        if (namelist == null) {
            /* This means the tag is not present. default type is WSDL20
             */
            setType("WSDL20");
            return;
        }

        Element name = (Element) namelist.item(0);
        String sValue;

        try {
            sValue = (name.getChildNodes().item(0)).getNodeValue().trim();
        } catch (NullPointerException ne) {
            setType("WSDL20");
            return;
        }

        setType(sValue);
    }

    /**
     * Returns the number of provider endpoints.
     *
     * @return provider endpoint count.
     */
    int getProviderCount() {
        return mNoOfProviders;
    }

    /**
     * Initializes the config file and loads services.
     *
     * @param doc Name of the config file.
     */
    void init(Document doc) {
        mDoc = doc;
        mDoc.getDocumentElement().normalize();
        load();
    }

    /**
     * Loads the data.
     */
    void load() {
        NodeList providers = mDoc.getElementsByTagName("provides");
        mNoOfProviders = providers.getLength();

        NodeList consumers = mDoc.getElementsByTagName("consumes");
        mNoOfConsumers = consumers.getLength();
        mEPList = new DescriptorEndpointInfo[mNoOfConsumers + mNoOfProviders];
        setArtifacts();
        for (int i = 0; i < mNoOfProviders; i++) {
            Node node = providers.item(i);
            DescriptorEndpointInfo sb = new DescriptorEndpointInfo(mSu_Name);
            setEndpoint(node, sb);
            sb.setProvider();
            mEPList[i] = sb;
        }

        for (int i = 0; i < mNoOfConsumers; i++) {
            Node node = consumers.item(i);
            DescriptorEndpointInfo sb = new DescriptorEndpointInfo(mSu_Name);
            setEndpoint(node, sb);
            mEPList[i + mNoOfProviders] = sb;
        }
    }

    /**
     * Gets the local name from the quname.
     *
     * @param qname Qualified name of service.
     * @return String local name
     */
    private String getLocalName(String qname) {
        StringTokenizer tok = new StringTokenizer(qname, ":");

        if (tok.countTokens() == 1) {
            return qname;
        }
        tok.nextToken();

        return tok.nextToken();
    }

    /**
     * Gets the namespace from the qname.
     *
     * @param qname Qname of service
     * @return namespace namespace of service
     */
    private String getNamespace(String qname) {
        StringTokenizer tok = new StringTokenizer(qname, ":");
        String prefix;

        if (tok.countTokens() == 1) {
            return "";
        }
        prefix = tok.nextToken();

        NamedNodeMap map = mDoc.getDocumentElement().getAttributes();
        for (int j = 0; j < map.getLength(); j++) {
            Node n = map.item(j);

            if (n.getLocalName().trim().equals(prefix.trim())) {
                return n.getNodeValue();
            }
        }

        return "";
    }

}
