/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2008 Bull S.A.S.
 * 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
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.ws.jaxws.client.naming;

import org.ow2.jonas.lib.util.JNDIUtils;
import org.ow2.jonas.ws.jaxws.IServiceReferenceBuilder;
import org.ow2.jonas.ws.jaxws.client.JOnASGenericService;

import javax.naming.Reference;
import javax.xml.namespace.QName;

/**
 * Builds a {@link Reference} that may be bound in JNDI, and used to
 * reconstruct the Service object.<br/>
 * This abstract class is used factorize all common stuff that a valid
 * JAX-WS Service Reference may need, anyway, subclasses are free to add
 * any values of interest in the Reference.<br/>
 * Notice that the subclasses SHOULD NOT insert specific values using the
 * keys defined in this class! BTW, if they do do, these values will be
 * overridden afterwards. 
 * @author Guillaume Sauthier
 */
public abstract class ServiceReferenceBuilder implements IServiceReferenceBuilder {

    /**
     * The classname of the Generic Service interface.
     */
    private static final String GENERIC_SERVICE_CLASSNAME = JOnASGenericService.class.getName();

    /**
     * The class implementing {@link javax.xml.ws.Service}.
     */
    private String serviceClass = GENERIC_SERVICE_CLASSNAME;

    /**
     * The XML serialized form of the HandlerChain declaration.
     */
    private String serializedHandlerChainXML = null;

    /**
     * The WSDL location. (as it appears in the metadatas)
     */
    private String wsdlLocation = null;

    /**
     * wsdl:service QName.
     */
    private QName serviceName = null;

    /**
     * Service Endpoint Interface classname (if any).
     */
    private String seiClassname = null;

    public String getSerializedHandlerChainXML() {
        return serializedHandlerChainXML;
    }

    public void setSerializedHandlerChainXML(String serializedHandlerChainXML) {
        this.serializedHandlerChainXML = serializedHandlerChainXML;
    }

    public String getServiceClass() {
        return serviceClass;
    }

    public void setServiceClass(String serviceClass) {
        this.serviceClass = serviceClass;
    }

    public String getSeiClassname() {
        return seiClassname;
    }

    public void setSeiClassname(String seiClassname) {
        this.seiClassname = seiClassname;
    }

    public QName getServiceName() {
        return serviceName;
    }

    public void setServiceName(QName serviceName) {
        this.serviceName = serviceName;
    }

    public String getWsdlLocation() {
        return wsdlLocation;
    }

    public void setWsdlLocation(String wsdlLocation) {
        this.wsdlLocation = wsdlLocation;
    }

    /**
     * Build a JNDI Reference instance that will be capable of returning
     * a valid WebService client view (Service class).
     * The created Reference must contains (in a serialized or String form)
     * anything that is required to re-create the Service instance.
     *
     * @return a Reference that will be used to re-create a JAX-WS Service.
     */
    public Reference buildReference() {

        // Let a chance for WS provider to specify its own ObjectFactory
        Reference ref = createReference(serviceClass);

        JNDIUtils.insertInto(ref, Constants.SERVICE_CLASS, serviceClass);
        JNDIUtils.insertInto(ref, Constants.SERVICE_ENDPOINT_INTERFACE, seiClassname);
        JNDIUtils.insertInto(ref, Constants.SERVICE_QNAME, serviceName);
        JNDIUtils.insertInto(ref, Constants.WSDL_LOCATION, wsdlLocation);
        JNDIUtils.insertInto(ref, Constants.HANDLER_CHAIN, serializedHandlerChainXML);

        return ref;
    }

    /**
     * Creates a new Reference instance customized by the WS provider.
     * @param className the class about to be referenced by the Reference
     * @return a new Reference
     */
    protected abstract Reference createReference(final String className);
}
