/*******************************************************************************
 * 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 int useCnt() {
			return useCnt;
		}
		
		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;
	}
}


