/*
 *  CorbaObjectPool.java v0.10 20-DEC-1999
 *  Copyright (c) TKK/TLM/Calypso
 *  Author: Alexey Mednonogov
 */

package codec;

import java.io.*;
import java.util.*;

import codec.*;
import codec.adapt.*;
import codec.convert.*;
import codec.debug.*;
import codec.dyntree.*;
import codec.export.*;
import codec.orb.*;
import codec.pco.*;
import codec.server.*;
import codec.client.*;
import codec.visit.*;
import codec.build.*;

/** Class taking care of the consistency of the CORBA objects collection. */
final public class CorbaObjectPool {

    private Map pcoMap;
	private Map objectMap;

    public CorbaObjectPool() {
        pcoMap = Collections.synchronizedMap(new HashMap());
        objectMap = Collections.synchronizedMap(new HashMap());
    }

    /** Retrieve index of CORBA object identified by "pcoName" from pool. 
     *  @return <code>null</code> in case no such "pcoName" is registered. */
    public CorbaObject getObject(String pcoName) {

        CorbaObject corbaObject = null;
        synchronized (pcoMap) { 
            corbaObject = (CorbaObject) pcoMap.get(pcoName);
        }
        return corbaObject;
    }

    /** Retrieve index of CORBA object identified by "object" from pool. 
     *  @return <code>null</code> in case no such "object" is registered. */
    public CorbaObject getObject(org.omg.CORBA.Object object) {

        CorbaObject corbaObject = null;
        synchronized (objectMap) { 
            corbaObject = (CorbaObject) objectMap.get(object);
        }
        return corbaObject;
    }

    /** Perform thread-safe registration of the CORBA object. In case
     *  association "object <-> PCO name" already exists, old object is
     *  deregistered, warning message is displayed and a new object is
     *  registered. */
    public void register(org.omg.CORBA.Object object, String pcoName,
                         int pcoType) {

        synchronized (objectMap) {
			synchronized (pcoMap) {

				CorbaObject corbaObject =
					new CorbaObject(object, pcoName, pcoType);

				// Old pair "pcoName <-> CorbaObject" will be replaced with
				// a new pair "pcoName <-> CorbaObject" automatically:
				pcoMap.put(pcoName, corbaObject);

				// Old pair "object <-> CorbaObject" will be replaced with
				// a new pair "object <-> CorbaObject" automatically:
				objectMap.put(object, corbaObject);
			}
		}
    }

    /** Deregister CORBA object identified by PCO name. */
    public void deregister(String pcoName) {

        CorbaObject corbaObject = null;

        synchronized (objectMap) {
            synchronized (pcoMap) {

                corbaObject = getObject(pcoName);
                org.omg.CORBA.Object object = null;
                if (corbaObject != null) 
                    { object = corbaObject.getObject(); }

                // Map will gracefully tolerate situation when there is
                // no mapping for key "pcoName" or for key "object":
                pcoMap.remove(pcoName);
                objectMap.remove(object);
            }
		}
        if (corbaObject != null) {
            if (corbaObject.getPcoType() == CorbaObject.PCO_TYPE_CLIENT)
                { ClientPool.removeServant(corbaObject); }
		}
    }
}
