/*******************************************************************************
 * 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.remote;
/*


 */


import java.text.MessageFormat;
import java.util.*;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jem.internal.proxy.core.*;
import org.eclipse.jem.internal.proxy.common.CommandException;
import org.eclipse.jem.internal.proxy.common.remote.CommandErrorException;
import org.eclipse.jem.internal.proxy.common.remote.Commands;

/**
 * The Remote VM Standard Bean Proxy Factory.
 * Creation date: (12/3/99 12:01:45 PM)
 * @author: Joe Winchester
 */
public final class REMStandardBeanProxyFactory implements IStandardBeanProxyFactory {
	protected final REMProxyFactoryRegistry fRegistry;
	protected final REMStandardBeanTypeProxyFactory fBeanTypeProxyFactory;	// Convenience field.
	protected final IREMBeanProxy vmServerProxy;

	
	// We need a map for mapping object id's to the proxy. The entry will actually be
	// a REMStandardBeanProxyFactory.WeakProxyReference. This is so that the
	// proxy will not be held tightly by this map and can be GC'd if not referenced.
	// Periodically, the reference queue will be processed to remove any of the
	// entries that have been GC'd and the server will be told that it can release
	// the ID on its side.
	//
	// This map will be used as synchronize object also for access to it.
	//
	// There will be a low priority job that will occasionally process the GC'd objects
	// and remove them from the queue and the remote vm. It will not remove during lockedTransactions.
	//
	// NOTE: Certain proxies never get added to the map. They are the
	// standard types/class (i.e. null, byte, int, long, short, double, float, byte, string). These
	// always have the value saved in the proxy so that it can be retrieved without going back
	// to the server. 
	private final HashMap fIDToProxiesMap = new HashMap(1000);	// Map ID's to proxies. The proxies have their id's so we don't need a reverse map
	private int transactionLockCount = 0;	// Count of transactions that have locked access. It is changed under sync control of fIDToProxies map.
	
	/**
	 * The Weak reference used for the id to proxies map for the proxy
	 * so that we can clean it up when the proxy has been garbage collected.
	 *
	 * It is important that all changes to the ProxyRef are done through sync on fIDToProxiesMap.
	 */
	private static class ProxyRef extends java.lang.ref.WeakReference {
		private Integer id;	// We need the id because this reference will be on the value side
					// and not the key side of the map, so we need to know the key
					// so that the object can be removed from the map.
					//
					// If the ID is null, then this means this entry has been processed
					// in some way and should not be released or removed from the table.
		private int useCnt = 1;	// Usage/Ref count. Needed so that we don't get rid of too soon. Since we don't
					// create a ProxyRef without a usage, we start it off with one. It will be incremented
					// then on retrievals when needed by users outside of the remote factories themselves.
					// It won't be physically released until either GC got rid of it, or it goes to 0 or less
					// on a release request.
					
		public ProxyRef(Integer anID, Object proxy, java.lang.ref.ReferenceQueue q) {
			super(proxy, q);
			id = anID;
		}
		
		public Integer getID() {
			return id;
		}
		
		public void clear() {
			super.clear();
			id = null;
		}
		
		public synchronized void incrUseCnt() {
			useCnt++;
		}
		
		public synchronized int decrUseCnt() {
			if (--useCnt < 0)
				useCnt = 0;
			return useCnt;
		}
	}
	
	/* Reference queue for cleared Proxies */
	private java.lang.ref.ReferenceQueue queue = new java.lang.ref.ReferenceQueue();	
	
	/**
	 * Process the entries on the id to proxies map that have been garbage collected.
	 * It is package-protected because only REMRegistryController should call it.
	 */
	void processQueue() {
		ProxyRef pr;	
		while (true) {
			if (Thread.interrupted())
				return;	// Maybe going down.	(This actually a kludge because the thread happens to be the master thread from the registry controller).
				
			synchronized (fIDToProxiesMap) {
				if (queue == null || transactionLockCount > 0)
					break;	// Either no queue (we are cleaning up) or in a transaction, stop processing and retry on next time slice.
				if ((pr = (ProxyRef) queue.poll()) != null) {				
					if (pr.getID() != null) {
						// It hasn't been processed by some other means.				
						fIDToProxiesMap.remove(pr.getID());						
						releaseID(pr.getID().intValue());
					}
				} else
					break;	// There are no more waiting, so leave.
			}
		}
	}
	
	
/**
 * REMBeanProxyFactory constructor comment.
 *
 * Note: It assumes the beantype factory has already been registered.
 */
REMStandardBeanProxyFactory(REMProxyFactoryRegistry aRegistry) {
	fRegistry = aRegistry;
	aRegistry.registerBeanProxyFactory(this);
	fBeanTypeProxyFactory = (REMStandardBeanTypeProxyFactory) aRegistry.getBeanTypeProxyFactory();
	fBeanTypeProxyFactory.initialize(this);	// Now we're ready for the beantype factory to be initialized.
	
	IREMBeanTypeProxy serverType = fBeanTypeProxyFactory.objectClass.newBeanTypeForClass(new Integer(Commands.REMOTEVMSERVER_CLASS), "org.eclipse.jem.internal.proxy.vm.remote.RemoteVMServerThread", false); //$NON-NLS-1$
	fBeanTypeProxyFactory.registerBeanTypeProxy(serverType, true);
	vmServerProxy = serverType.newBeanProxy(new Integer(Commands.REMOTESERVER_ID));
	registerProxy(vmServerProxy);
}


/**
 * Register a collection of Proxies
 */
public void registerProxies(Collection proxies) {
	synchronized(fIDToProxiesMap) {
		Iterator itr = proxies.iterator();
		while (itr.hasNext()) {
			IREMBeanProxy proxy = (IREMBeanProxy) itr.next();
			if (proxy instanceof IBeanTypeProxy || !(proxy.getTypeProxy() instanceof IREMConstantBeanTypeProxy)) {
				ProxyRef oldRef = (ProxyRef) fIDToProxiesMap.put(proxy.getID(), new ProxyRef(proxy.getID(), proxy, queue));
				if (oldRef != null) {
					// We've replaced it with a new one, so we will clear out the ref so that it won't later try to remove itself
					oldRef.clear();
				}
			}
		}		
	}
}

/**
 * Register a single proxy
 */
public void registerProxy(IREMBeanProxy proxy) {
	if (proxy instanceof IBeanTypeProxy || !(proxy.getTypeProxy() instanceof IREMConstantBeanTypeProxy))
		synchronized(fIDToProxiesMap) {
			ProxyRef oldRef = (ProxyRef) fIDToProxiesMap.put(proxy.getID(), new ProxyRef(proxy.getID(), proxy, queue));
			if (oldRef != null) {
				// We've replaced it with a new one, so we will clear out the ref so that it won't later try to remove itself
				oldRef.clear();
			}							
		}
}

/**
 * Release a proxy because no longer needed.
 */
public void releaseProxy(IBeanProxy proxy) {
	if (!proxy.isValid())
		return;
	if (proxy instanceof IBeanTypeProxy && !fBeanTypeProxyFactory.releaseProxy((IBeanTypeProxy) proxy))
		return;	// BeanType and type factory won't allow release of it.
	Integer id = ((IREMBeanProxy) proxy).getID();
	synchronized(fIDToProxiesMap) {			
		// Synced in here so that we will remove it before some one else from a different thread may try
		// to access it again.
		if (id.intValue() != Commands.NOT_AN_ID) {
			ProxyRef ref = (ProxyRef) fIDToProxiesMap.get(id);
			if (ref == null || ref.decrUseCnt() <= 0) {
				// No usage, so do actual release.
				fIDToProxiesMap.remove(id);
				((IREMBeanProxy) proxy).release();
				if (ref != null)
					ref.enqueue();	// Queue it up so that on next release cycle it will go away.
			} 
		} else {
			((IREMBeanProxy) proxy).release();			
		}
	}
}

/**
 * Release a specific ID. This is used in case an ID has been sent
 * but we couldn't proxy it. In that case we only have an ID. It is
 * also used when a proxy has been released explicitly or through GC.
 * In that case it has already been de-registered.
 */
private void releaseID(int anID) {
	try {
		IREMConnection connect = fRegistry.getFreeConnection();
		try {
			connect.releaseID(anID);
		} finally {
			fRegistry.returnConnection(connect);
		}
	} catch (IllegalStateException e) {
		// Couldn't get connection, don't bother with a release.
	}
}

/**
 * For the Remote Factory we will create an REMBeanProxy using the null constructor
 * Package protected so only REMBeanTypeProxies can create instances.
 */
 
IBeanProxy createBeanProxy(IREMBeanTypeProxy aTypeProxy) throws ThrowableProxy {
	return REMStandardBeanProxyConstants.getConstants(fRegistry).getClassNewInstance().invoke(null, aTypeProxy);
}

/**
 * For the Remote Factory we will create a REMBeanProxy using the initializationString.
 * Package protected so only REMBeanTypeProxies can create instances. 
 */
IBeanProxy createBeanProxy(IREMBeanTypeProxy aTypeProxy, String initializationString)
	throws ThrowableProxy, CommandException, ClassCastException, InstantiationException, IllegalStateException {
	IREMConnection connect = fRegistry.getFreeConnection();
	startTransaction();
	// Starting a transaction, we will be getting id's back and need to get data in a separate step, so we need to group it in a transaction.
	try {
		Commands.ValueObject newInstanceData = null;
		try {
			newInstanceData = getNewInstanceData(aTypeProxy, initializationString, connect);
		} catch (CommandErrorException e) {
			switch (e.getErrorCode()) {
				case Commands.CLASS_CAST_EXCEPTION:
					// The result was not of the correct type.
					throw new ClassCastException(
						MessageFormat.format(ProxyRemoteMessages.Classcast_EXC_, new Object[] {extractFirstLine(initializationString), aTypeProxy.getTypeName()})); 
				case Commands.CANNOT_EVALUATE_STRING:
					// Want to log the exception that caused it to not evaluate.
					// Don't need to log this side, just log the RemoteVM side of the trace.
					java.io.StringWriter s = new java.io.StringWriter();
					java.io.PrintWriter w = new java.io.PrintWriter(s);
					((ThrowableProxy) e.getErrorObject()).printProxyStackTrace(w);
					ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, s.toString(), null));
					throw new InstantiationException(
						MessageFormat.format(ProxyRemoteMessages.Instantiate_EXC_, new Object[] {extractFirstLine(initializationString)})); 
				default:
					throw e; //$NON-NLS-1$
			}
		} catch (CommandException e) {
			if (e.isRecoverable()) {
				ProxyPlugin.getPlugin().getLogger().log( 
					new Status(
						IStatus.WARNING,
						ProxyPlugin.getPlugin().getBundle().getSymbolicName(),
						0,
						"", //$NON-NLS-1$
						e));
			} else {
				// It failed in the command, try again.
				fRegistry.closeConnection(connect);
				connect = null;
				connect = fRegistry.getFreeConnection();
				try {
					newInstanceData = getNewInstanceData(aTypeProxy, initializationString, connect);
				} catch (CommandException eAgain) {
					// It failed again. Close this connection and don't let it be returned.
					fRegistry.closeConnection(connect);
					connect = null; // This is so that it won't be returned.
				}
			}
		} finally {
			if (connect != null)
				fRegistry.returnConnection(connect);
		}

		if (newInstanceData != null)
			return getBeanProxy(newInstanceData); // Turn it into a proxy
	} finally {
		stopTransaction();	// Now we can release the transaction.
	}

return null;
}

private String extractFirstLine(String initString) {
	// Need to extract the first line for the messageFormat not to barf.
	int cr = initString.indexOf('\r');
	int lf = initString.indexOf('\n');	
	if (cr != -1 || lf != -1) {
		if (cr == -1 || (lf != -1 && lf < cr))
			return initString.substring(0, lf);
		else
			return initString.substring(0, cr);
	} else
		return initString;
}
	
	
/**
 * actually create it using a passed in connection. This allows retry capability.
 *
 * This will send the request over to the connection.
 *
 * If we get an OBJECT back, then the beantypeproxy that the classID in the
 * value points to must be of type IREMConstantBeanTypeProxy so that we can
 * send this new object to the correct beantype to create the correct proxy.
 *
 * If we get an OBJECT_ID back, then the beantypeproxy that the classID in
 * the value points to must be able to handle creating a proxy of that type. 
 */
private Commands.ValueObject getNewInstanceData(IREMBeanTypeProxy aTypeProxy, String initializationString, IREMConnection connect) throws ThrowableProxy, CommandException {	
	try {
		Commands.ValueObject newInstanceData = new Commands.ValueObject();
		connect.getNewInstance(aTypeProxy.getID().intValue(), initializationString, newInstanceData);
		return newInstanceData;
	} catch (CommandErrorException e) {
		// TBD - Needs to handle error of not evaluatable and send over to the compilor.
		processErrorReturn(e);	// Process this
	}
	return null;
}

/**
 * actually create it using a passed in connection. This allows retry capability.
 */
private void getObjectInstanceData(IREMConnection connect, int objectID, Commands.ValueObject valueReturn) throws ThrowableProxy, CommandException {	
	try {
		connect.getObjectData(objectID, valueReturn);
	} catch (CommandErrorException e) {
		processErrorReturn(e);	// Process this
	}
}

/**
 * Get a bean proxy from the value object passed in. If not yet created, create one.
 * NOTE: NULL type actually returns a true null. This is so that if people are casting
 * the returned proxy to a specific type (e.g IIntegerBeanProxy), then they won't get
 * a ClassCastException, they will get a null. This is easier for them to handle.
 * 
 * NOTE: This is public ONLY so that extension factories can create correct types of
 * proxies in consistent manner from a value object. 
 * 
 * It is important that this is called
 * from within a transaction only because otherwise the value could have invalid data
 * by the time we try to get the data out of it.
 */
public IBeanProxy getBeanProxy(Commands.ValueObject value) throws ThrowableProxy, CommandException {
	switch (value.type) {
		// Null result.
		case (byte) Commands.VOID_TYPE:
			return null;
		// A constant object was received.
		case Commands.OBJECT:
			IREMConstantBeanTypeProxy constantBeanType = null;
			try {
				constantBeanType = (IREMConstantBeanTypeProxy) getBeanType(value.classID);
				if (constantBeanType == null)
					return null;	// Cannot find the type to create it.
			} catch (ClassCastException e) {
				// It wasn't a constant type, so we can't create it. Return null.
				ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$
				return null;
			}
			
			return constantBeanType.newBeanProxy(value);
		
		// An existing object_id was returned, the object should exist. If it doesn't
		// then submit the info command to try to recreate it correctly.
		case Commands.OBJECT_ID:
			Integer objectID = new Integer(value.objectID);
			IBeanProxy proxy = retrieveProxy(objectID, true);
			if (proxy != null)
				return proxy;

			// Not found, need to try to recreate it.
			IREMConnection connect = fRegistry.getFreeConnection();
			try {
				getObjectInstanceData(connect, value.objectID, value); // Go and get the data
			} catch (CommandErrorException e) {
				if (e.isRecoverable()) {
					ProxyPlugin.getPlugin().getLogger().log(
						new Status(
							IStatus.WARNING,
							ProxyPlugin.getPlugin().getBundle().getSymbolicName(),
							0,
							"", //$NON-NLS-1$
							e));
					return null;
				} else {
					// Try one more time.
					fRegistry.closeConnection(connect);
					connect = null;
					connect = fRegistry.getFreeConnection();
					try {
						getObjectInstanceData(connect, value.objectID, value); // Go and get the data
					} catch (CommandErrorException eAgain) {
						fRegistry.closeConnection(connect);
						connect = null;
						throw eAgain;
					}
				}
			} finally {
				if (connect != null)
					fRegistry.returnConnection(connect);
			}

			return getBeanProxy(value); // Now process it to create the new data.
			
		// An new object id. Need to get the class type and let it create it.
		case Commands.NEW_OBJECT_ID:
			try {
				IREMBeanTypeProxy newBeanType = getBeanType(value.classID);
				IREMBeanProxy newProxy = newBeanType.newBeanProxy(new Integer(value.objectID));
				if (newProxy != null)
					registerProxy(newProxy);
				return newProxy;
			} catch (CommandException e) {
				// The server has created a new object, but we couldn't create/register a proxy for it.
				// We need to release it so that the server can get rid of it. Otherwise it would hang
				// around over there forever.
				releaseID(value.objectID);
				throw e;				
			} catch (RuntimeException e) {
				// The server has created a new object, but we couldn't create/register a proxy for it.
				// We need to release it so that the server can get rid of it. Otherwise it would hang
				// around over there forever.
				releaseID(value.objectID);
				throw e;
			}			
			
		// An exception was thrown, create the ThrowableProxy and then throw it.
		case Commands.THROW:
			IREMBeanProxy newThrowProxy	= null;
			try {
				IREMBeanTypeProxy newThrowType =  getBeanType(value.classID);
				newThrowProxy = newThrowType.newBeanProxy(new Integer(value.objectID));
				if (newThrowProxy != null)
					registerProxy(newThrowProxy);
			} catch (CommandException e) {
				// The server has created a new object, but we couldn't create/register a proxy for it.
				// We need to release it so that the server can get rid of it. Otherwise it would hang
				// around over there forever.
				releaseID(value.objectID);
				throw e;				
			} catch (RuntimeException e) {
				// The server has created a new object, but we couldn't create/register a proxy for it.
				// We need to release it so that the server can get rid of it. Otherwise it would hang
				// around over there forever.
				releaseID(value.objectID);
				throw e;
			}				
			// It really should be a throwable, but if not, just return it.
			if (newThrowProxy instanceof ThrowableProxy)
				throw (ThrowableProxy) newThrowProxy;
			else
				return newThrowProxy;		
		
		// It is one of the standard kinds, which are Constant types
		default:
			IREMConstantBeanTypeProxy standardBeanType = null;
			try {
				standardBeanType = (IREMConstantBeanTypeProxy) getBeanType(value.type);
				if (standardBeanType == null)
					return null;	// Cannot find the type to create it.
			} catch (ClassCastException e) {
				// It wasn't a standard type, so we can't create it. Return null.
				ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$
				return null;
			}
			return standardBeanType.newBeanProxy(value);
	}						
}

/**
 * Process the error exception. Get the data from it and turn it into proxy data.
 * If it is a THROW, then it will throw the Throwable instead. 
 *
 * NOTE: It is public ONLY so that extension factories can process errors in
 * an consistent manner. 
 * 
 * It is important that this be called only within a transaction.
 */
public void processErrorReturn(CommandErrorException e) throws CommandException, ThrowableProxy {
	int code = e.getErrorCode();
	Object data = null;
	if (code == Commands.THROWABLE_SENT)
		data = getBeanProxy(e.getValue());	// It is Throw sent, so let the throw from getBeanProxy continue on out. (But as a safety, we still try to get the data.
	else {
		try {
			data = getBeanProxy(e.getValue());
		} catch (ThrowableProxy t) {
			// But we want to keep throwables in this case. They are just data for the command error.
			data = t;
		}
	}
	throw new CommandErrorException(MessageFormat.format(ProxyRemoteMessages.RemoteCmd_EXC_, new Object[] {new Integer(code)}), code, e.getValue(), data);	// Create a new one and throw it containing the proxied data. //$NON-NLS-1$
}
	 

/**
 * Get a beantype where the id passed in is the classID of the beantype.
 * If not found, then go get it loaded. If it can't be found, then we will
 * release the id because it means we have an id from the server, but we
 * can't create a proxy for it, so don't keep the server holding it.
 * NOTE: This is public ONLY so that extension factories can create correct types
 * in a consistent manner from the id.
 * 
 * It is important that this be called only from within a transaction. 
 */
public IREMBeanTypeProxy getBeanType(int id) throws CommandException {
	IREMBeanTypeProxy beanType = null;
	try {
		Integer classID = new Integer(id);
		beanType = (IREMBeanTypeProxy) retrieveProxy(classID, false);
		if (beanType == null)
			beanType = fBeanTypeProxyFactory.createBeanTypeProxy(classID);	// We don't have it, need to go to the factory so that it can go query what it needs
		if (beanType == null)
			return null;	// Cannot find the type to create it.
	} catch (ClassCastException e) {
		// It wasn't a bean type, so we can't create it. Return null.
		ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$
	} finally {
		if (beanType == null)
			releaseID(id);	// Couldn't create a proxy, so release the id.
	}
	return beanType;
}


/**
 * Return a proxy wrapping the primitive integer
 */
public IIntegerBeanProxy createBeanProxyWith(int aPrimitiveInteger) {

	return fBeanTypeProxyFactory.intType.createIntegerBeanProxy(aPrimitiveInteger);
}

/**
 * Return a proxy wrapping the primitive byte
 */
public INumberBeanProxy createBeanProxyWith(byte aPrimitiveByte) {

	return fBeanTypeProxyFactory.byteType.createByteBeanProxy(aPrimitiveByte);
}

/**
 * Return a proxy wrapping the primitive char
 */
public ICharacterBeanProxy createBeanProxyWith(char aPrimitiveChar) {

	return fBeanTypeProxyFactory.charType.createCharacterBeanProxy(aPrimitiveChar);
}

/**
 * Return a proxy wrapping the primitive short
 */
public INumberBeanProxy createBeanProxyWith(short aPrimitiveShort) {

	return fBeanTypeProxyFactory.shortType.createShortBeanProxy(aPrimitiveShort);
}

/**
 * Return a proxy wrapping the primitive long
 */
public INumberBeanProxy createBeanProxyWith(long aPrimitiveLong) {

	return fBeanTypeProxyFactory.longType.createLongBeanProxy(aPrimitiveLong);
}
/**
 * Return a proxy wrapping the primitive double
 */
public INumberBeanProxy createBeanProxyWith(double aPrimitiveDouble) {

	return fBeanTypeProxyFactory.doubleType.createDoubleBeanProxy(aPrimitiveDouble);
}
/**
 * Return a proxy wrapping the primitive float
 */
public INumberBeanProxy createBeanProxyWith(float aPrimitiveFloat) {

	return fBeanTypeProxyFactory.floatType.createFloatBeanProxy(aPrimitiveFloat);
}

/**
 * createBeanProxyWith method comment.
 */
public IBooleanBeanProxy createBeanProxyWith(Boolean aBoolean) {
	return fBeanTypeProxyFactory.booleanClass.createBooleanBeanProxy(aBoolean);
}
/**
 * Return a proxy that wraps the Integer argument
 */
public IIntegerBeanProxy createBeanProxyWith(Integer anInteger) {

	return fBeanTypeProxyFactory.integerClass.createIntegerBeanProxy(anInteger);
}
/**
 * createBeanProxyWith method comment.
 */
public INumberBeanProxy createBeanProxyWith(Number aNumber) {
	REMAbstractNumberBeanTypeProxy type = (REMAbstractNumberBeanTypeProxy) fBeanTypeProxyFactory.getBeanTypeProxy(aNumber.getClass().getName());
	return type.createNumberBeanProxy(aNumber);
}
/**
 * Return a proxy for the argument
 */
public IStringBeanProxy createBeanProxyWith(String aString) {

	return fBeanTypeProxyFactory.stringClass.createStringBeanProxy(aString);

}
/**
 * Return a proxy for the argument
 */
public ICharacterBeanProxy createBeanProxyWith(Character aCharacter) {

	return fBeanTypeProxyFactory.characterClass.createCharacterBeanProxy(aCharacter);

}
/**
 * createBeanProxyWith method comment.
 */
public IBooleanBeanProxy createBeanProxyWith(boolean aPrimitiveBoolean) {
	return fBeanTypeProxyFactory.booleanType.createBooleanBeanProxy(aPrimitiveBoolean);
}

/**
 * Create an array bean proxy.
 *
 *   - (int, new int[2] {3, 4}) will create:
 *      int [3] [4]
 *
 *   - (int[], new int[1] {1})
 *      int [1]
 *
 *   - (int[], new int[2] {2,3})
 *      int [2] [3]
 * 
 *
 *   - (int[], null) or (int[], new int[0]) or (int, null) or (int, new int[0])
 *      int [0]...
 *     or
 *     (int[][]..., null) or (int[][]..., new int[0])
 *      int[0][]...
 *     This is because an array instance with no specified dimensions is not valid. 
 *
 *   - (int[][], new int[1] {3})
 *      int[3][]
 */
public IArrayBeanProxy createBeanProxyWith(IBeanTypeProxy type, int[] dimensions) throws ThrowableProxy {
	if (type.isArray())
		return ((REMArrayBeanTypeProxy) type).createBeanProxyWith(dimensions);	// Already an array type, just pass it on.
	else {
		// It is not an array type, so we need to get an array of this type and dimensions.
		REMArrayBeanTypeProxy arrayType = (REMArrayBeanTypeProxy) fBeanTypeProxyFactory.getBeanTypeProxy(type.getTypeName(), dimensions.length);
		return arrayType.createBeanProxyWith(dimensions);
	}
}
/**
 * Create a one-dimensional array. 
 * The result will be the same as calling 
 *   createBeanProxyWith(IBeanTypeProxy type, new int[1] {x})
 * where 'x' is the value passed in as the dimension.
 */
public IArrayBeanProxy createBeanProxyWith(IBeanTypeProxy type, int dimension) throws ThrowableProxy {
	return createBeanProxyWith(type, new int[] {dimension});
}

/**
 * Retrieve the proxy from the mapping table. Handle already GC'd.
 * If this returns null, it is important that the caller tries to recreate
 * it since the id is still valid on the server.
 */
private IBeanProxy retrieveProxy(Integer objectID, boolean incrementUseCnt) {
	synchronized (fIDToProxiesMap) {
		ProxyRef ref = (ProxyRef) fIDToProxiesMap.get(objectID);
		if (ref != null) {
			Object bp = ref.get();			
			if (ref.isEnqueued() || bp == null) {
				// It's waiting to be removed, or has been removed. i.e. GC'd, so just remove it from the map, next processQueue will remove it from the queue.
				fIDToProxiesMap.remove(objectID);
				ref.clear();		// This is so that when the processQueue see's it, 
							// it won't send a release request to the server 
							// since it will be recreated when this method returns.
				return null;
			} else {
				if (incrementUseCnt)
					ref.incrUseCnt();
				return (IBeanProxy) bp;
			}	
		} else
			return null;
	}
}

/**
 * Start Transaction: During the time between start/stop transaction,
 * proxies will not be cleaned up. This prevents the case of a two step
 * transaction where the returned ID from the remote vm is for a proxy
 * that is about to be cleaned up, and then having that proxy disappear
 * when going for the data for it.
 * 
 * Note: It is IMPERITIVE that the start/stop is used in the following way:
 *     factory.startTransaction();
 *     try {
 *         do your stuff...
 *     } finally {
 *         factory.stopTransaction();
 *     }
 * 
 * This way it can never accidently leave it in a locked state.
 */
public	void startTransaction()  {
	synchronized (fIDToProxiesMap) {
		transactionLockCount++;
	}
}

public boolean inTransaction() {
	synchronized (fIDToProxiesMap) {
		return transactionLockCount != 0;
	}
}

/**
 * Stop Transaction: During the time between start/stop transaction,
 * proxies will not be cleaned up. This prevents the case of a two step
 * transaction where the returned ID from the remote vm is for a proxy
 * that is about to be cleaned up, and then having that proxy disappear
 * when going for the data for it.
 * 
 * Note: It is IMPERITIVE that the start/stop is used in the following way:
 *     factory.startTransaction();
 *     try {
 *         do your stuff...
 *     } finally {
 *         factory.stopTransaction();
 *     }
 * 
 * This way it can never accidently leave it in a locked state.
 */
public	void stopTransaction()  {
	synchronized (fIDToProxiesMap) {
		if (--transactionLockCount < 0)
			transactionLockCount = 0;	// Shouldn't occur, but just in case.
	}
}

/**
 * Terminate the factory. If this is being terminated, then the server is being terminated too.
 * So just go through all of the proxies and release them, but don't send any notification to
 * the server since the server is subsequently just going to throw them away when it terminates.
 * <p>
 * This can't run async, so wait is a suggestion here.
 */
public void terminateFactory(boolean wait) {
	synchronized (fIDToProxiesMap) {
		Iterator itr = fIDToProxiesMap.values().iterator();
		while (itr.hasNext()) {
			ProxyRef ref = (ProxyRef) itr.next();
			if (ref != null) {
				Object bp = ref.get();
				// If not cleaned up and not enqueued, release it.
				if (bp != null && !ref.isEnqueued())
					((IREMBeanProxy) bp).release();
			}
		}
		
		fIDToProxiesMap.clear();
		queue = null;	// Don't bother processing the queue, don't need to now.
	}
}
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanProxyFactory#createExpression()
	 */
	public IExpression createExpression() {
		return new REMExpression(this.fRegistry);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanProxyFactory#createBeanProxyFrom(java.lang.String)
	 */
	public IBeanProxy createBeanProxyFrom(String initializationString) throws ThrowableProxy, ClassCastException, InstantiationException {
		try {
			return createBeanProxy(fBeanTypeProxyFactory.voidType, initializationString);
		} catch (CommandException e) {
			ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$		}
		}
		return null;
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanProxyFactory#convertToPrimitiveBeanProxy(org.eclipse.jem.internal.proxy.core.IBeanProxy)
	 */
	public IBeanProxy convertToPrimitiveBeanProxy(IBeanProxy nonPrimitiveProxy) {
		if (nonPrimitiveProxy == null)
			return null;
		if (!nonPrimitiveProxy.isValid())
			return nonPrimitiveProxy;
		IREMBeanTypeProxy type = (IREMBeanTypeProxy) nonPrimitiveProxy.getTypeProxy();
		// Step into the internals. The ID is a constant int, so we can use a switch stmt.
		switch (type.getID().intValue()) {
			case Commands.BOOLEAN_CLASS:
				return this.createBeanProxyWith(((IBooleanBeanProxy) nonPrimitiveProxy).booleanValue());
			case Commands.BYTE_CLASS:
				return this.createBeanProxyWith(((INumberBeanProxy) nonPrimitiveProxy).byteValue());
			case Commands.CHARACTER_CLASS:
				return this.createBeanProxyWith(((ICharacterBeanProxy) nonPrimitiveProxy).charValue());
			case Commands.DOUBLE_CLASS:
				return this.createBeanProxyWith(((INumberBeanProxy) nonPrimitiveProxy).doubleValue());
			case Commands.FLOAT_CLASS:
				return this.createBeanProxyWith(((INumberBeanProxy) nonPrimitiveProxy).floatValue());
			case Commands.INTEGER_CLASS:
				return this.createBeanProxyWith(((INumberBeanProxy) nonPrimitiveProxy).intValue());
			case Commands.LONG_CLASS:
				return this.createBeanProxyWith(((INumberBeanProxy) nonPrimitiveProxy).longValue());
			case Commands.SHORT_CLASS:
				return this.createBeanProxyWith(((INumberBeanProxy) nonPrimitiveProxy).shortValue());
			default:
				return nonPrimitiveProxy;
		}
	}


	public IBeanProxy getIVMServerProxy() {
		return vmServerProxy;
	}
}


