/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2004 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: Florent BENOIT
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.deployment.common.lib;

import org.ow2.jonas.deployment.common.xml.JonasServiceRef;
import org.ow2.jonas.deployment.common.xml.ResourceRef;
import org.ow2.jonas.deployment.common.xml.ResourceEnvRef;
import org.ow2.jonas.deployment.common.xml.AbsEnvironmentElement;
import org.ow2.jonas.deployment.common.xml.JonasPortComponentRef;
import org.ow2.jonas.deployment.common.xml.JonasStubProperty;
import org.ow2.jonas.deployment.client.xml.ApplicationClient;
import org.ow2.util.ee.metadata.common.api.struct.IJaxwsWebServiceRef;
import org.ow2.util.ee.metadata.common.api.xml.struct.IPortComponentRef;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Iterator;

/**
 * Abstract class of DeploymentDesc manager. Use for common methods.
 * @author Florent Benoit
 */
public abstract class AbsDeploymentDescManager implements DeploymentDescManager {

    /**
     * Char separator in a link.
     */
    public static final String LINK_SEPARATOR = "#";

    /**
     * Utility class, no public constructor
     */
    protected AbsDeploymentDescManager() {

    }

    /**
     * Return the content of the inut stream
     * @param in the given input stream
     * @return the content of the inut stream
     * @throws IOException if the file can't be read
     */
    protected static String xmlContent(InputStream in) throws IOException {

        StringBuffer sb = new StringBuffer();
        String line;
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        // loop until the end
        while ((line = br.readLine()) != null) {
            sb.append(line);
            sb.append("\n");
        }
        return sb.toString();
    }

    /**
     * Find a jonas-service-ref element with a given name.
     * @param jonasServiceRefList the list of elements to search in
     * @param name the name
     * @return a jonas-service-ref element matching the given name or null if not found
     */
    protected static JonasServiceRef findJonasServiceRef(final List jonasServiceRefList,
                                                       final String name) {
        JonasServiceRef found = null;
        for (Iterator i = jonasServiceRefList.iterator(); i.hasNext() && found == null;) {
            JonasServiceRef element = (JonasServiceRef) i.next();
            if (name.equals(element.getServiceRefName())) {
                found = element;
            }
        }

        return found;
    }

    /**
      * @return true if the resource name is already present as a resource-ref or resource-env-ref
     */
    public static boolean containsResource(final String resourceName, final AbsEnvironmentElement env) {
        List<ResourceRef> resourceRefList = env.getResourceRefList();
        for (ResourceRef resourceRef : resourceRefList) {
            if (resourceName.equals(resourceRef.getResRefName())) {
                return true;
            }
        }

        List<ResourceEnvRef> resourceEnvRefList = env.getResourceEnvRefList();
        for (ResourceEnvRef resourceEnvRef : resourceEnvRefList) {
            if (resourceName.equals(resourceEnvRef.getResourceEnvRefName())) {
                return true;
            }
        }

        // not found
        return false;
    }

    /**
     * Merge into the Jax WS service ref some data from the jonas-xxx.xml files
     * @param jsr the XML struct of the JOnAS service ref
     * @param wsr the JAX WS metadata which has been merged
     */
    protected static void mergeWebServiceRef(JonasServiceRef jsr, IJaxwsWebServiceRef wsr) {
        // Override wsdl-location value if specified
        if (jsr.getAltWsdl() != null) {
            wsr.setWsdlLocation(jsr.getAltWsdl());
        }

        List<JonasPortComponentRef> portComponentRefList = jsr.getJonasPortComponentRefList();
        for (JonasPortComponentRef jonasPortComponentRef : portComponentRefList) {
            // Get SEI
            String serviceEndpointInterface = jonasPortComponentRef.getServiceEndpointInterface();

            // matching port component ?
            IPortComponentRef portComponentRef = wsr.getPortComponentRef(serviceEndpointInterface);
            if (portComponentRef == null) {
                // no, needs to add one
                portComponentRef = new org.ow2.util.ee.metadata.common.impl.xml.struct.PortComponentRef();
                portComponentRef.setServiceEndpointInterface(serviceEndpointInterface);
                List<IPortComponentRef> wsrPortcomponentRefs = wsr.getPortComponentRefs();
                wsrPortcomponentRefs.add(portComponentRef);
                wsr.setPortComponentRefs(wsrPortcomponentRefs);
            }
            // add stub properties
            List<JonasStubProperty> jonasStubProperties = jonasPortComponentRef.getJonasStubPropertyList();
            for (JonasStubProperty jonasStubProperty : jonasStubProperties) {
                portComponentRef.getStubProperties().put(jonasStubProperty.getParamName(), jonasStubProperty.getParamValue());
            }

        }
        
    }
}