/*
 * Copyright (c) 2002-2003 IST-2004-2006-511731 ModelWare - ModelBus.
 * All rights reserved.
 *
 * This software is published under the terms of the ModelBus Software License
 * 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.
 * A copy of ModelBus Software License is provided with this distribution in
 * doc/LICENSE.txt file.
 */

/*
 * Created on 24 mai 2005
 *
 */
package org.eclipse.mddi.modelbus.adapter.infrastructure;

import java.net.MalformedURLException;
import java.util.Collection;
import java.util.Iterator;

import org.apache.log4j.Logger;
import org.eclipse.mddi.modelbus.adapter.infrastructure.model_manipulation.DescriptionUtil;
import org.eclipse.mddi.modelbus.adapter.infrastructure.notification.NotifServiceManager;
import org.eclipse.mddi.modelbus.adapter.infrastructure.notification.NotifServiceNotAvailableException;
import org.eclipse.mddi.modelbus.adapter.infrastructure.registry.RegistryManager;
import org.eclipse.mddi.modelbus.adapter.infrastructure.registry.RegistryNotAvailableException;
import org.eclipse.mddi.modelbus.adapter.infrastructure.transport.server.ws.ProviderEndPoint;
import org.eclipse.mddi.modelbus.adapter.user.AdapterStub;
import org.eclipse.mddi.modelbus.description.concrete.Tool;

/**
 * @author Prawee Sriplakich, Andrey Sadovykh (LIP6)
 * 
 */
public class AdapterContainerImpl implements AdapterContainer {

    /**
     * A unique instance of this class
     */
    private static AdapterContainerImpl instance = new AdapterContainerImpl();

    public static Logger logger = Logger.getLogger(AdapterContainerImpl.class);

    /**
     * Obtains a unique instance of this class
     * 
     * @return an instance of this class
     */
    public static AdapterContainer getInstance() {
        LoggerConfigurator.configure();
        return instance;
    }

    /**
     * Not used yet. Wait for implementation of local transport
     */

    ProviderEndPoint msProviderEndPoint = new ProviderEndPoint();

    Collection adapters = msProviderEndPoint.getAdapters();

    private AdapterContainerImpl() {

    }

    /**
     * Deploys an Adapter to this server, so 1) it begins accepting service
     * invocation, and 2) receiving notifications.
     * 
     * 
     * @param adapter
     *            the Adapter object
     * @throws DeploymentException
     */
    public void deployAdapter(AdapterStub adapter) throws DeploymentException {
        DeploymentException exception = new DeploymentException();

        try {
            if (adapter.getToolDescription() != null) {
                // get server
                // bind adapter to server
                msProviderEndPoint.manageAdapter(adapter);
            }
        } catch (MalformedURLException e) {
            exception.addProblem("Bad tool URL in tool description", e);
        } catch (Exception e) {
            exception.addProblem("Could not deploy Tool to Server", e);
        }

        try {
            if (adapter.getToolDescription() != null) {
                logger.debug("Registering Tool: ");
                RegistryManager.getInstance().registerTool(adapter);
            }
        } catch (RegistryNotAvailableException e) {
            exception.addProblem("Could not register tool", e);
        }
        try {
            NotifServiceManager.getInstance().subscribeNotificationConsumer(
                    adapter);
        } catch (NotifServiceNotAvailableException e) {
            exception.addProblem("Could not subscribe NotificationConsumer", e);
        }
        if (exception.hasProblems()) {
            logger.debug("Deploy Adapter Error: ", exception);
            throw exception;
        }
    }

    /**
     * Undeploys an Adapter to this server. The result is 1) it will not accept
     * invocation anymore, and 2) it will not accept notifications anymore.
     * 
     * @param adapter
     *            the Adapter object
     * @throws DeploymentException
     */
    public void undeployAdapter(AdapterStub adapter) throws DeploymentException {
        DeploymentException exception = new DeploymentException();
        try {
            msProviderEndPoint.removeAdapter(adapter);
        } catch (Exception e) {
            exception.addProblem("Could not unbind tool", e);
        }

        try {
            RegistryManager.getInstance().deregisterTool(adapter);
        } catch (RegistryNotAvailableException e) {
            exception.addProblem("Could not register tool", e);
        }
        try {
            NotifServiceManager.getInstance().unsubscribeNotificationConsumer(
                    adapter);
        } catch (NotifServiceNotAvailableException e) {
            exception.addProblem("Could not unsubscribe NotificationConsumer",
                    e);
        }
        if (exception.hasProblems()) {
            throw exception;
        }
    }

public boolean containTool(Tool toolDesc) {
        Iterator it = adapters.iterator();
        while (it.hasNext()){
            AdapterStub adapter = (AdapterStub)it.next();
            Tool testTool = adapter.getToolDescription();
            if (DescriptionUtil.isToolEqual(testTool,toolDesc))return true;
        }        
        return false;
    }}