/*
 * 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 17 juin 2005
 *
 */
package org.eclipse.mddi.modelbus.adapter.infrastructure.registry;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import org.eclipse.mddi.modelbus.adapter.user.AdapterStub;
import org.eclipse.mddi.modelbus.adapter.user.consumer.ModelBusCommunicationException;
import org.eclipse.mddi.modelbus.adapter.user.consumer.ServiceUnknownException;
import org.eclipse.mddi.modelbus.description.concrete.Tool;

/**
 * RegistryClientManager is a container of all RegistryClients. It allows
 * several Adapters (of several tools) to share RegistryClients.
 * 
 * @author Prawee Sriplakich (LIP6)
 * 
 */
public class RegistryManager {

    static RegistryManager instance = new RegistryManager();

    public static RegistryManager getInstance() {
        return instance;
    }

    Map clientMap = new HashMap();

    public void registerTool(AdapterStub adapter)
            throws RegistryNotAvailableException {
        Tool toolDescription = adapter.getToolDescription();
        if (toolDescription == null) {
            // there is no tool description to register
            return;
        }
        String registry_location = adapter.getProperties().getProperty(
                AdapterStub.PROP_REGISTRY_LOCATION);
        if (registry_location == null) {
            throw new RegistryNotAvailableException(
                    "No registry_location specified");
        }
        RegistryClient registryClient = getRegistryClient(registry_location);

        String token = registryClient.registerTool(toolDescription);
        if (token == null)
            return; // comment this line in the release version. The token
        // cannot be null.
        adapter.getProperties().setProperty(
                AdapterStub.PROP_REGISTRATION_TOKEN, token);
    }

    public void deregisterTool(AdapterStub adapter)
            throws RegistryNotAvailableException {
        String token = adapter.getProperties().getProperty(
                AdapterStub.PROP_REGISTRATION_TOKEN);
        if (token == null) {
            // the tool has not been previously registerred.
            // so we return
            return;
        }
        String registry_location = adapter.getProperties().getProperty(
                AdapterStub.PROP_REGISTRY_LOCATION);
        RegistryClient registryClient = RegistryManager.getInstance()
                .getRegistryClient(registry_location);
        registryClient.deregisterTool(token);
    }
    
    /**
     * 
     * getToolDescription
     * 
     * @param serviceName the service name that can be qualified or not.  
     * (qualitied service name = [Interface].[service])
     * @param adapter the adapter that can uses a specific tool selector
     * @return
     * @throws ModelBusCommunicationException if fail to communicate with the registry.
     * @throws ServiceUnknownException
     * 
     *
     */
    public Tool getToolDescription(String serviceName, AdapterStub adapter) throws ModelBusCommunicationException, ServiceUnknownException {
        Tool toolDescription = null;
        
        try {
          RegistryClient c = RegistryManager.getInstance().getRegistryClient(
                adapter.getProperties().getProperty(AdapterStub.PROP_REGISTRY_LOCATION));
        
          toolDescription = c.lookupToolByModelingService(serviceName, adapter.getToolSelector()); 
          
        } catch(RegistryNotAvailableException e ) {
            
            throw new ModelBusCommunicationException(e.toString());
        }
        if(toolDescription==null) {
            throw new ServiceUnknownException(serviceName);
            
        }   
        return toolDescription;
    }
    

    public Collection getAllRegistryLocations() {
        return new HashSet(clientMap.keySet());
    }

    public Collection getAllRegistryClients() {
        return new HashSet(clientMap.values());
    }

    public RegistryClient getRegistryClient(String location)
            throws RegistryNotAvailableException {
        RegistryClient client;
        if (clientMap.containsKey(location)) {
            client = (RegistryClient) clientMap.get(location);
            return client;
        }
        client = new RegistryClient(location);
        clientMap.put(location, client);
        return client;
    }

    public void removeRegistryClient(String location) {
        if (clientMap.containsKey(location)) {
            clientMap.remove(location);
        }
    }

}
