/*******************************************************************************
 * Copyright (c) 2001, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jem.internal.proxy.core;
/*
 *  $RCSfile: ProxyFactoryRegistry.java,v $
 *  $Revision: 1.14 $  $Date: 2005/08/24 20:39:06 $ 
 */


import java.util.Hashtable;
import java.util.Iterator;

import org.eclipse.jem.util.TimerTests;

/**
 * Registry of proxy factories on a per-VM basis.
 * There can be multiple VM's, this would be required by the
 * desktop because more than one project could be open, and each
 * would require their own VM because the classpaths would be different.
 * This class may be subclassed to provide more factories for a particular
 * VM. 
 * Creation date: (3/13/00 10:48:10 AM)
 * @author: Richard Lee Kulp
 */
public abstract class ProxyFactoryRegistry {
	
	protected boolean fIsValid = true;	// The registry is valid until terminated.
	protected ListenerList registryListeners = new ListenerList();
	
	/**
	 * IRegistryListener
	 * Listen for the registry being terminated.
	 */
	public interface IRegistryListener {
		/**
		 * Method registryTerminated.
		 * 
		 * The registry has been terminated. When this is called the registry
		 * is no longer valid. It should not be assumed any calls can be made
		 * to the registry.
		 * 
		 * @param registry
		 */
		public void registryTerminated(ProxyFactoryRegistry registry);
	}
		

	// Factory registration IS NOT a dynamic registration. Once registered for a VM or an instance
	// they should not be changed. This is because references are cached in other objects.
	// The VM associated with this Registry shouldn't exited and restarted because
	// the cached object will then have invalid references to no longer existing objects.
	// If the VM needs to be restarted, then all proxies need to be tossed.
	
	//
	// Individual ProxyFactoryRegistry, applies to a particular VM.
	//

	// ***************************
	//
	// IBeanProxyFactory Registry
	//
	
	// The standard bean  proxy factory, the one the desktop will use for packages that have not
	// been extended and registered by customization developers.
	protected IStandardBeanProxyFactory fCurrentStandardBeanProxyFactory;

	// The directory of registered extension factories, typically registered by package.
	final protected Hashtable fRegisteredExtensionBeanProxyFactories = new Hashtable();

	// ***************************
	//
	// IBeanTypeProxyFactory Registry
	//
	
	// The standard bean type proxy factory, the one the desktop will use for packages that have not
	// been extended and registered by customization developers.
	protected IStandardBeanTypeProxyFactory fCurrentStandardBeanTypeProxyFactory;

	// The directory of registered extension factories, typically registered by package.
	final protected Hashtable fRegisteredExtensionBeanTypeProxyFactories = new Hashtable();
	

	// ***************************
	//
	// Other factories
	//
		
	protected IMethodProxyFactory fMethodProxyFactory = null;	// Method Proxy Factory

	// ***************************
	//
	// Constants Registry. Different extensions can store
	// objects by key as a registry of constants.
	// For example, java.awt extension will store an object
	// which has some pre-fetched method proxies stored in it so
	// that they don't need to be continually recreated.
	//
	// This feature should be used with care, so that
	// only proxies that really need to be cached should
	// be cached.
	//
	// Don't store proxies to live beans in here because
	// those will be created and destroyed over and over,
	// and the instance in this cache will get stale.
	// Should only store things like often used method
	// proxies that once created are rarely changed.
	//
	// Since the proxies can be on any VM, you should have
	// an interface defining what's available in your
	// constants entry, and access it through that.

	protected final Hashtable fRegisteredConstants = new Hashtable();		

	/**
	 * ProxyFactoryRegistry constructor comment.
	 */
	public ProxyFactoryRegistry() {
		super();
	}
	
	/**
	 * Method addRegistryListener.
	 * @param listener
	 */
	public void addRegistryListener(IRegistryListener listener) {
		registryListeners.add(listener);
	}
	
	/**
	 * Method removeRegistryListener.
	 * @param listener
	 */
	public void removeRegistryListener(IRegistryListener listener) {
		registryListeners.remove(listener);
	}
	
	protected void fireRegistryTerminated() {
		if (!registryListeners.isEmpty()) {
			Object[] list = registryListeners.getListeners();
			for (int i = 0; i < list.length; i++) {
				((IRegistryListener) list[i]).registryTerminated(this);
			}
		}
	}
	
	/**
	 Return the current factory to be used for creating IBeanProxy instances
	 */
	public IStandardBeanProxyFactory getBeanProxyFactory() {
		if (fCurrentStandardBeanProxyFactory == null) {
			throw new RuntimeException(ProxyMessages.ProxyFactory_EXC__NoBeanProxyFactory);
		}
		return fCurrentStandardBeanProxyFactory;
	}
	/**
	 Return the current registered bean proxy factory to be used for creating IBeanProxy instances
	 */
	public IBeanProxyFactory getBeanProxyFactoryExtension(String packageName) {
		return (IBeanProxyFactory)fRegisteredExtensionBeanProxyFactories.get(packageName);
	}
	
	/**
	 Return the current factory to be used for creating IBeanTypeProxy instances
	 */
	public IStandardBeanTypeProxyFactory getBeanTypeProxyFactory() {
		if (fCurrentStandardBeanTypeProxyFactory == null) {
			throw new RuntimeException(ProxyMessages.ProxyFactory_EXC__NoBeanTypeProxyFactory);
		}
		return fCurrentStandardBeanTypeProxyFactory;
	}
	/**
	 Return the current registered bean type proxy factory to be used for creating IBeanTypeProxy instances
	 */
	public IBeanTypeProxyFactory getBeanTypeProxyFactoryExtension(String packageName) {
		return (IBeanTypeProxyFactory)fRegisteredExtensionBeanTypeProxyFactories.get(packageName);
	}
	/**
	 * Return the requested constants entry
	 */
	public Object getConstants(Object key) {
		return fRegisteredConstants.get(key);
	}
	/**
	 * Return the MethodProxyFactory for this VM.
	 * Creation date: (3/13/00 10:54:59 AM)
	 * @return org.eclipse.jem.internal.proxy.core.IMethodProxyFactory
	 */
	public IMethodProxyFactory getMethodProxyFactory() {
		return fMethodProxyFactory;
	}
	
	
	/**
	 * Set the requested constants entry for this VM.
	 */
	public void registerConstants(Object key, Object constant) {
		fRegisteredConstants.put(key, constant);
	}
    
    /**
     * Remove the constants for the given key.
     * @param key
     * 
     * @since 1.1.0
     */
    public void deregisterConstants(Object key) {
        fRegisteredConstants.remove(key);
    }
	/**
	 * Release the proxy, no longer needed.
	 * This is a helper method to easily access the release from the bean proxy factory.
	 */
	public void releaseProxy(IBeanProxy proxy) {
		// To simply things if release is called when the factory is down (invalid), then just
		// go on because the proxy is already released.
		if (fCurrentStandardBeanProxyFactory != null)
			fCurrentStandardBeanProxyFactory.releaseProxy(proxy);
	} 

	/**
	 * Is this a valid registry, i.e. is it not terminated.
	 */
	public boolean isValid() {
		return fIsValid;
	}
	
	/**
	 * Terminate the registry without waiting.
	 * <p>
	 * Terminate the registry, but don't necessarily wait for it.
	 *
	 * @see #terminateRegistry(boolean)
	 * @since 1.0.0
	 */
	public final void terminateRegistry() {
		terminateRegistry(false);
	}
		
	/**
	 * Terminate the registry.
	 * <p>
	 * This will go through each factory and terminate it, and
	 * let the subclass terminate. It will then remove all of the factories so that
	 * if there are any proxies still hanging around they won't hold onto everything,
	 * just the this registry will be held onto.
	 *<p>
	 * Note during termination, the factories should not reference any other factory.
	 * It can assume that the factories will take care of themselves and they should
	 * only release their resources.
	 * <p>
	 * The constants registry will not be terminated because they aren't factories.
	 * However, they will be cleared (no longer referenced) from here so that they
	 * can be GC'd.
	 * 
	 * @param wait <code>true</code> to wait for complete termination, <code>false</code> to kick off termination but return ASAP.
	 * @since 1.0.2
	 */
	public final void terminateRegistry(boolean wait) {
		if (!fIsValid)
			return;	// Already or are already terminating. Don't do it again and don't notify again.
		fIsValid = false;
		if (fCurrentStandardBeanTypeProxyFactory != null) {
//			TimerTests.basicTest.startStep("Terminate Bean Type Factory");
			fCurrentStandardBeanTypeProxyFactory.terminateFactory(wait);
//			TimerTests.basicTest.stopStep("Terminate Bean Type Factory");
			fCurrentStandardBeanTypeProxyFactory = null;
		}
		if (fCurrentStandardBeanProxyFactory != null) {
			fCurrentStandardBeanProxyFactory.terminateFactory(wait);
			fCurrentStandardBeanProxyFactory = null;
		}
		if (fMethodProxyFactory != null) {
			fMethodProxyFactory.terminateFactory(wait);
			fMethodProxyFactory = null;
		}
		
		Iterator itr = fRegisteredExtensionBeanTypeProxyFactories.values().iterator();
		while (itr.hasNext()) {
			((IBeanProxyFactory) itr.next()).terminateFactory(wait);
		}
		fRegisteredExtensionBeanTypeProxyFactories.clear();
		
		itr = fRegisteredExtensionBeanProxyFactories.values().iterator();
		while (itr.hasNext()) {
			((IBeanProxyFactory) itr.next()).terminateFactory(wait);
		}
		fRegisteredExtensionBeanProxyFactories.clear();
		
		fRegisteredConstants.clear();
		
		TimerTests.basicTest.startStep("Registry Terminated"); //$NON-NLS-1$
		registryTerminated(wait);
		TimerTests.basicTest.stopStep("Registry Terminated"); //$NON-NLS-1$
		
//		TimerTests.basicTest.startStep("Registry Terminated Notification");
		fireRegistryTerminated();	// Let everyone know that we are gone. This is fired even if wait is false because at this point in time the registry is invalid.
//		TimerTests.basicTest.stopStep("Registry Terminated Notification");
	}
	

	/**
	 * Terminate the Registry. 
	 * <p>
	 * It is up to each registry to determine what this means.
	 * <p>
	 * The wait parm is a suggestion if it is <code>false</code>, but it must be honoured if <code>true</code>
	 * 
	 * @param wait wait for registry to terminate flag.
	 * 
	 * @since 1.0.2
	 */
	protected abstract void registryTerminated(boolean wait);
	
	/**
	 * Get the callback registry.
	 */
	public abstract ICallbackRegistry getCallbackRegistry();
	
}
