/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * Initial Developer : Delplanque Xavier & Sauthier Guillaume
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.deployment.ws;

import java.util.Iterator;
import java.util.Properties;

import javax.xml.namespace.QName;

import org.ow2.jonas.deployment.common.xml.JonasCallProperty;
import org.ow2.jonas.deployment.common.xml.JonasPortComponentRef;
import org.ow2.jonas.deployment.common.xml.JonasStubProperty;
import org.ow2.jonas.deployment.common.xml.PortComponentRef;
import org.ow2.jonas.lib.util.I18n;



/**
 * The PortComponentRefDesc associate a service-endpoint-interface with a
 * port-component in the same application unit.
 * @author Guillaume Sauthier
 * @author Xavier Delplanque
 */
public class PortComponentRefDesc {

    /** The service-endpoint-interface matching the WSDL port */
    private Class sei;

    /** The PortComponent link Name */
    private String pcLink = null;

    /** The PortComponent link */
    private PortComponentDesc pcDesc = null;

    /**
     * Stub properties
     */
    private Properties stubProperties = null;

    /**
     * Call properties
     */
    private Properties callProperties = null;

    /**
     * wsdl:port to be used when invoking Service.getPort(Class sei)
     */
    private QName wsdlPort = null;

    /**
     * Internationalization
     */
    private static I18n i18n = I18n.getInstance(PortComponentRefDesc.class);

    /**
     * Creates a new PortComponentRefDesc object.
     * @param classLoader module class loader (web or ejb)
     * @param pcr port component ref generate by Zeus, defined in web deployment
     *        desc
     * @param jpcr jonas port component ref generate by Zeus, defined in web deployment
     *        desc
     * @throws WSDeploymentDescException if service endpoint class doesn't exist
     */
    public PortComponentRefDesc(ClassLoader classLoader, PortComponentRef pcr, JonasPortComponentRef jpcr) throws WSDeploymentDescException {

        String className = null;
        stubProperties = new Properties();
        callProperties = new Properties();

        try {
            // load service endpoint interface
            className = pcr.getServiceEndpointInterface().trim();
            sei = classLoader.loadClass(className);

            // get port link if any
            if (pcr.getPortComponentLink() != null) {
                pcLink = pcr.getPortComponentLink().trim();
            }

            // load properties
            if (jpcr != null) {
                for (Iterator i = jpcr.getJonasCallPropertyList().iterator(); i.hasNext();) {
                    JonasCallProperty jp = (JonasCallProperty) i.next();
                    callProperties.setProperty(jp.getParamName(), jp.getParamValue());
                }
                for (Iterator i = jpcr.getJonasStubPropertyList().iterator(); i.hasNext();) {
                    JonasStubProperty jp = (JonasStubProperty) i.next();
                    stubProperties.setProperty(jp.getParamName(), jp.getParamValue());
                }
                if (jpcr.getWsdlPort() != null) {
                    wsdlPort = jpcr.getWsdlPort().getQName();
                }
            }
        } catch (ClassNotFoundException e) {
            throw new WSDeploymentDescException(getI18n().getMessage("PortComponentRefDesc.seiNotFound", className), e); //$NON-NLS-1$
        }
    }

    /**
     * Return the port Component Link Object. May be null if not defined
     * @return the port Component Link Object.
     */
    public String getPortComponentLink() {
        return pcLink;
    }

    /**
     * Set the pcLink port component desc
     * @param pcd the portComponentDesc linked with this PortcompRef.
     */
    public void setPortComponentDesc(PortComponentDesc pcd) {
        pcDesc = pcd;
    }

    /**
     * Return the linked port component desc (can be null if no pcLink).
     * @return the linked port component desc. (null if no pcLink)
     */
    public PortComponentDesc getPortComponentDesc() {
        return pcDesc;
    }

    /**
     * Return the Service Endpoint Interface of the Port Component.
     * @return the Service Endpoint Interface of the Port Component.
     */
    public Class getSEI() {
        return sei;
    }

    /**
     * @see java.lang.String#hashCode()
     */
    public int hashCode() {
        return sei.getName().hashCode();
    }

    /**
     * Return true if the 2 objects are equals in value.
     * @param other the object to compare.
     * @return true if the 2 objects are equals in value, else false.
     */
    public boolean equals(Object other) {
        if (other == null) {
            return false;
        }

        if (!(other instanceof PortComponentRefDesc)) {
            return false;
        }

        PortComponentRefDesc ref = (PortComponentRefDesc) other;

        if (!sei.getName().equals(ref.getSEI().getName())) {
            return false;
        }

        if (!pcLink.equals(ref.getPortComponentLink())) {
            return false;
        }

        // After all theses tests, the 2 objects are equals in value
        return true;
    }

    /**
     * @return Returns the i18n.
     */
    protected static I18n getI18n() {
        return i18n;
    }

    /**
     * @return Returns the callProperties.
     */
    public Properties getCallProperties() {
        return callProperties;
    }

    /**
     * @return Returns the stubProperties.
     */
    public Properties getStubProperties() {
        return stubProperties;
    }

    /**
     * @return Returns the wsdlPort.
     */
    public QName getWsdlPort() {
        return wsdlPort;
    }
}