/*******************************************************************************
 * Copyright (c) 2001, 2004 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;
/*
 *  $RCSfile: REMStandardBeanTypeProxyFactory.java,v $
 *  $Revision: 1.9 $  $Date: 2005/02/15 22:56:10 $ 
 */


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.MapTypes;
import org.eclipse.jem.internal.proxy.common.remote.CommandErrorException;
import org.eclipse.jem.internal.proxy.common.remote.Commands;

/**
 * We are a beanTypeProxyFactory for creating REMBeanTypeProxy objects
 * Primitive types as well as common types like String are cached for speed
 * of lookup.
 * We are the standard one that the VCE uses.
 * Creation date: (12/3/99 2:32:48 PM)
 * @author: Joe Winchester
 */
public final class REMStandardBeanTypeProxyFactory implements IStandardBeanTypeProxyFactory {
	
	protected final REMProxyFactoryRegistry fFactoryRegistry;
	protected REMStandardBeanProxyFactory fBeanFactory;
	
	
	// Hashtable to cache proxies for classes so they are found on second and subsequent lookups
	protected Map fBeanProxies = new HashMap(1000);
	
	// A Cache of bean type proxies that should not ever be released.	These are the standard ones
	// that we create here. They are never released because they wouldn't be correctly re-created
	// if they were. Also they are standard ones with standard ID's that don't change so they
	// don't need to be re-created later.
	protected Set fPermanentProxies = new HashSet(30);
	
	// Cache of requested but not found bean types. If not maintaining the list, this variable will be null.
	// The values are strings (classnames in JNI format).
	protected Set fNotFoundTypes = null; 

	// Cached copy of a few typical bean type proxies.
	REMBeanTypeProxy objectClass;
	REMClassBeanTypeProxy classClass;	
	REMVoidBeanTypeProxy voidType;
	REMBooleanTypeBeanTypeProxy booleanType;
	REMBooleanClassBeanTypeProxy booleanClass;
	REMIntegerTypeBeanTypeProxy intType;
	REMIntegerClassBeanTypeProxy integerClass;
	REMByteTypeBeanTypeProxy byteType;
	REMByteClassBeanTypeProxy byteClass;		
	REMShortClassBeanTypeProxy shortClass;	
	REMShortTypeBeanTypeProxy shortType;
	REMLongClassBeanTypeProxy longClass;	
	REMLongTypeBeanTypeProxy longType;	
	REMDoubleClassBeanTypeProxy doubleClass;	
	REMDoubleTypeBeanTypeProxy doubleType;	
	REMFloatClassBeanTypeProxy floatClass;	
	REMFloatTypeBeanTypeProxy floatType;	
	REMBigDecimalBeanTypeProxy bigDecimalClass;		
	REMBigIntegerBeanTypeProxy bigIntegerClass;		
	REMCharacterTypeBeanTypeProxy charType;
	REMCharacterClassBeanTypeProxy characterClass;	
	REMStringBeanTypeProxy stringClass;
	
	/**
	 * Available to all REM beantypes.
	 */
	public REMProxyConstants proxyConstants;

/**
 * IDEBeanTypeProxyFactory constructor comment.
 */
REMStandardBeanTypeProxyFactory(REMProxyFactoryRegistry aRegistry) {
	fFactoryRegistry = aRegistry;
	aRegistry.registerBeanTypeProxyFactory(this);
	
	proxyConstants = new REMProxyConstants();

	// Now initialize the cache.
	objectClass = new REMBeanTypeProxy(fFactoryRegistry, new Integer(Commands.OBJECT_CLASS), Object.class.getName(), null);
	classClass = new REMClassBeanTypeProxy(fFactoryRegistry, objectClass);		
	voidType = new REMVoidBeanTypeProxy(fFactoryRegistry);
	booleanType = new REMBooleanTypeBeanTypeProxy(fFactoryRegistry);
	booleanClass = new REMBooleanClassBeanTypeProxy(fFactoryRegistry, objectClass);
	IBeanTypeProxy numberClass = objectClass.newBeanTypeForClass(new Integer(Commands.NUMBER_CLASS), Number.class.getName(), true);
	intType = new REMIntegerTypeBeanTypeProxy(fFactoryRegistry);
	integerClass = new REMIntegerClassBeanTypeProxy(fFactoryRegistry, numberClass);
	byteType = new REMByteTypeBeanTypeProxy(fFactoryRegistry);
	byteClass = new REMByteClassBeanTypeProxy(fFactoryRegistry, numberClass);	
	shortType = new REMShortTypeBeanTypeProxy(fFactoryRegistry);
	shortClass = new REMShortClassBeanTypeProxy(fFactoryRegistry, numberClass);
	longType = new REMLongTypeBeanTypeProxy(fFactoryRegistry);
	longClass = new REMLongClassBeanTypeProxy(fFactoryRegistry, numberClass);
	doubleType = new REMDoubleTypeBeanTypeProxy(fFactoryRegistry);
	doubleClass = new REMDoubleClassBeanTypeProxy(fFactoryRegistry, numberClass);
	floatType = new REMFloatTypeBeanTypeProxy(fFactoryRegistry);
	floatClass = new REMFloatClassBeanTypeProxy(fFactoryRegistry, numberClass);					
	bigDecimalClass = new REMBigDecimalBeanTypeProxy(fFactoryRegistry, numberClass);	
	bigIntegerClass = new REMBigIntegerBeanTypeProxy(fFactoryRegistry, numberClass);		
	charType = new REMCharacterTypeBeanTypeProxy(fFactoryRegistry);	
	characterClass = new REMCharacterClassBeanTypeProxy(fFactoryRegistry, objectClass);
	stringClass = new REMStringBeanTypeProxy(fFactoryRegistry, objectClass);
	IBeanTypeProxy throwableClass = new REMThrowableBeanTypeProxy(fFactoryRegistry, new Integer(Commands.THROWABLE_CLASS), Throwable.class.getName(), objectClass);
	IBeanTypeProxy threadClass = objectClass.newBeanTypeForClass(new Integer(Commands.THREAD_CLASS), Thread.class.getName(), false);

	// Initialize the hashtable with the primitives, their lang equivalents, and also common classes like String

	// Primitives
	fBeanProxies.put(voidType.getTypeName(), voidType);
	fBeanProxies.put(intType.getTypeName(), intType);
	fBeanProxies.put(booleanType.getTypeName(), booleanType);
	fBeanProxies.put(charType.getTypeName(), charType);
	fBeanProxies.put(byteType.getTypeName(), byteType);
	fBeanProxies.put(shortType.getTypeName(), shortType);
	fBeanProxies.put(longType.getTypeName(), longType);
	fBeanProxies.put(floatType.getTypeName(), floatType);
	fBeanProxies.put(doubleType.getTypeName(), doubleType);

	// java.lang primitive peers
	// Note that special classes are used for some of these which allow the IDE to get the
	// lang objects from the objects that are holding proxies
	fBeanProxies.put(integerClass.getTypeName(), integerClass);
	fBeanProxies.put(booleanClass.getTypeName(), booleanClass);
	fBeanProxies.put(characterClass.getTypeName(), characterClass);
	fBeanProxies.put(byteClass.getTypeName(), byteClass);
	fBeanProxies.put(shortClass.getTypeName(), shortClass);
	fBeanProxies.put(longClass.getTypeName(), longClass);
	fBeanProxies.put(floatClass.getTypeName(), floatClass);
	fBeanProxies.put(doubleClass.getTypeName(), doubleClass);
	fBeanProxies.put(bigDecimalClass.getTypeName(), bigDecimalClass);
	fBeanProxies.put(bigIntegerClass.getTypeName(), bigIntegerClass);
	fBeanProxies.put(stringClass.getTypeName(), stringClass);
	fBeanProxies.put(throwableClass.getTypeName(), throwableClass);
	fBeanProxies.put(objectClass.getTypeName(), objectClass);
	fBeanProxies.put(classClass.getTypeName(), classClass);
	fBeanProxies.put(numberClass.getTypeName(), numberClass);	
	fBeanProxies.put(threadClass.getTypeName(), threadClass);
	
	// Mark these as permanent.
	fPermanentProxies.addAll(fBeanProxies.values());
}

/**
 * Initialize AFTER BeanProxyFactory has been created. This is REQUIRED!
 * NOTE: It is package protected so that only REMStandardBeanProxyFactory can call it when ready.
 */
synchronized void initialize(REMStandardBeanProxyFactory proxyFactory) {
	fBeanFactory = proxyFactory;
	fBeanFactory.registerProxies(fBeanProxies.values());
}
	
	
/*
 * This is called when we know we don't have the class registered, so
 * we need to create the proxy. We have a connection passed in and will reuse it as necessary
 * 
 * It is important that this be called only from within a transaction.
 */
private synchronized IREMBeanTypeProxy createBeanTypeProxy(String typeName, IREMConnection connection) throws CommandException {
	
	// We don't have the beantype proxy, so create it.	
	IREMBeanTypeProxy beanTypeProxy = null;
	Commands.GetClassReturn ret = null;
	try {
		ret = getClassReturn(connection, typeName);
	} catch (ThrowableProxy ep) {
		// Print out the trace and return proxy with init error.
		ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", ep)); //$NON-NLS-1$
		IREMBeanTypeProxy proxy = new REMInitErrorBeanTypeProxy(fFactoryRegistry, MessageFormat.format(ProxyRemoteMessages.getString("ExceptionErrorMsg_EXC_"), new Object[] {ep.getTypeProxy().getTypeName(), ep.getProxyLocalizedMessage()}), typeName); //$NON-NLS-1$
		registerBeanTypeProxy(proxy, false);
		return proxy;
	}
	if (ret == null) {
		if (fNotFoundTypes != null)
			fNotFoundTypes.add(typeName);
		return null;	// The class doesn't even exist on the server.
	}

	if (typeName.charAt(0) != '[') {
		// It is not an array.
		IREMBeanTypeProxy superTypeProxy = null;
		if (!ret.isInterface && ret.superClassname.length() != 0) {
			// Get the beantype proxy of the superclass.
			superTypeProxy = getBeanTypeProxy(ret.superClassname, connection);
		}
			
		// First check with the factory for the package of the class.
		// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
		// the package ended and the class started. This check is here in case the
		// extension factory can handle this class but needs the id from the server to
		// create it.
		int packageIndex = typeName.lastIndexOf('.');
		if (packageIndex != -1) {
			String packageName = typeName.substring(0, packageIndex);
			IREMBeanTypeProxyFactory packageFactory = (IREMBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
			if (packageFactory != null) {
				beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(typeName, new Integer(ret.classID), superTypeProxy);
				if (beanTypeProxy != null) {
					registerBeanTypeProxy(beanTypeProxy, false);
					return beanTypeProxy;
				}
			}
		}							
		
		if (ret.isInterface) {
			// Interface never have a super type, so we will create a specific type.
			beanTypeProxy = new REMInterfaceBeanTypeProxy(fFactoryRegistry, new Integer(ret.classID), typeName);
		} else {		
			// Ask the supertype
			// to create a beantype proxy of the same beantype proxy class.
			// This is so that any subclasses will get the same beantype proxy class
			// for it if it is special.			
			if (superTypeProxy != null)
				beanTypeProxy = superTypeProxy.newBeanTypeForClass(new Integer(ret.classID), typeName, ret.isAbstract);
		}
	} else
		beanTypeProxy = new REMArrayBeanTypeProxy(fFactoryRegistry, new Integer(ret.classID), typeName, objectClass);
	 	
	// Cache the instance so we can re-use it again
	if (beanTypeProxy != null) 		
		registerBeanTypeProxy(beanTypeProxy, false);
	return beanTypeProxy;
}
/**
 * Using the helper class to find a class by name, then create the proxy.
 */
public IBeanTypeProxy getBeanTypeProxy(String typeName) {
	try {
		return getBeanTypeProxy(MapTypes.getJNIFormatName(typeName), (IREMConnection) null);
	} catch (CommandException e) {
		// Try once more (we won't have received recoverable exceptions here, they were already caught and handled)
		try {
			return getBeanTypeProxy(typeName, (IREMConnection) null);
		} catch (CommandException eAgain) {
			// Failed again.
			ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", eAgain)); //$NON-NLS-1$
		}
	}
	return null;
}
	
/**
 * One that internally allows that we already have a connection to work with.
 * If the connection is null, then one will be created.
 * 
 * It is important that if the connection is not null, then we are in a transaction.
 */
private synchronized IREMBeanTypeProxy getBeanTypeProxy(String typeName, IREMConnection inConnect) throws CommandException {	

	// See whether we already have the proxy for the argument name
	IREMBeanTypeProxy beanTypeProxy = (IREMBeanTypeProxy) fBeanProxies.get(typeName);
	if (beanTypeProxy != null) {
		return beanTypeProxy;
	}

	// If not an array, then see if the package extension mechanism can find it.
	// Do this here so that if it is found in the package extension we won't necessarily create an
	// extra connection when not needed.
	if (typeName.charAt(0) != '[') {
		// It is not an array
		// First check with the factory for the package of the class.
		// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
		// the package ended and the class started.
		int packageIndex = typeName.lastIndexOf('.');
		if (packageIndex != -1) {
			String packageName = typeName.substring(0, packageIndex);
			IREMBeanTypeProxyFactory packageFactory = (IREMBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
			if (packageFactory != null) {
				beanTypeProxy = (IREMBeanTypeProxy) packageFactory.getExtensionBeanTypeProxy(typeName);
				if (beanTypeProxy != null) {
					registerBeanTypeProxy(beanTypeProxy, false);
					return beanTypeProxy;
				}
			}
		}
	}
	
	IREMConnection connect = inConnect != null ? inConnect : fFactoryRegistry.getFreeConnection();
	if (inConnect == null)
		fBeanFactory.startTransaction();	// Start a transation.
	try {
		return createBeanTypeProxy(typeName, connect);
	} catch (CommandException e) {
		if (inConnect == null) {
			// Need to close the connection, not return it.
			fFactoryRegistry.closeConnection(connect);
			connect = null;	// So that it won't be returned.
		}
		throw e;	// Pass it on up
	} finally {
		if (inConnect == null)
			fBeanFactory.stopTransaction();
		if (inConnect == null && connect != null)
			fFactoryRegistry.returnConnection(connect);
	}
}

/*
 * It is important this be called only from within a transaction.
 */
private Commands.GetClassReturn getClassReturn(IREMConnection connection, String className) throws CommandException, ThrowableProxy {
	try {
		return connection.getClass(className);
	} catch (CommandErrorException e) {
		fBeanFactory.processErrorReturn(e);	// Let proxy factory handle the error return
	}
	return null;
}

/**
 * Return an Array type proxy for the given class name of
 * the specified dimensions. This is a helper method. The
 * same result can be gotton from getBeanTypeProxy.
 * e.g.
 *      getBeanTypeProxy("java.lang.Object", 3)
 *    is the same as:
 *      getBeanTypeProxy("[[[Ljava.lang.Object;")
 *
 *    They both result in a type of:
 *      Object [][][]
 *
 *    or
 *      getBeanTypeProxy("[Ljava.langObject;", 3)
 *    becomes
 *      Object [][][][]
 */
public IBeanTypeProxy getBeanTypeProxy(String componentClassName, int dimensions) {
	String jniComponentClassName = MapTypes.getJNIFormatName(componentClassName);
	String compType = jniComponentClassName;
	if (jniComponentClassName.charAt(0) != '[') {
		// We're not already an array, so create correct template.
		compType = (String) MapTypes.MAP_TYPENAME_TO_SHORTSIG.get(jniComponentClassName);
		if (compType == null) {
			// It is a class, and not a type.
			compType = "L"+jniComponentClassName+";"; //$NON-NLS-1$ //$NON-NLS-2$
		}
	}
	
	// Now create it with the appropriate number of '[' in front.
	StringBuffer buffer = new StringBuffer(dimensions+compType.length());
	for (int i=0; i<dimensions; i++)
		buffer.append('[');
	buffer.append(compType);
	return getBeanTypeProxy(buffer.toString());
}

/**
 * Get the bean type proxy from a class id. This means that a new class id
 * was sent back from the server that we don't have yet. We need to go ask
 * the server for information on this type so that we can create it.
 *
 * NOTE: This is package protected so that only the standard bean proxy factory
 * can call it. 
 * 
 * It is important that this has been called within a transaction.
 */
IREMBeanTypeProxy createBeanTypeProxy(Integer classID) {
	IREMConnection connect = fFactoryRegistry.getFreeConnection();	
	try {
		return createBeanTypeProxy(classID, connect);
	} catch (CommandException e) {
		if (e.isRecoverable()) {
			// It is recoverable, print message, keep connection live and return it.
			ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$
		} else {
			// Try again, close connection, get a new one.
			fFactoryRegistry.closeConnection(connect);
			connect = null;
			connect = fFactoryRegistry.getFreeConnection();
			try {
				return createBeanTypeProxy(classID, connect);
			} catch (CommandException eAgain) {
				// Failed again. Close connection, don't return it.
				ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", eAgain)); //$NON-NLS-1$
				fFactoryRegistry.closeConnection(connect);
				connect = null;
			}
		}
	} finally {
		if (connect != null)
			fFactoryRegistry.returnConnection(connect);
	}
	return null;
}

/*
 * One that internally allows that we already have a connection to work with.
 * If the connection is null, then one will be created.
 * 
 * It is important this be called only from within a transaction.
 */
private synchronized IREMBeanTypeProxy createBeanTypeProxy(Integer classID, IREMConnection connect) throws CommandException {	
	// We don't have the beantype proxy, so create it.
	IREMBeanTypeProxy beanTypeProxy = null;

	Commands.GetClassIDReturn ret = null;
	try {
		ret = getClassIDReturn(connect, classID);
	} catch (ThrowableProxy ep) {
		// Just print out the trace and return proxy not found.
		ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", ep)); //$NON-NLS-1$
		return null;
	}
	
	// If the signature is that of a class.
	if (ret.className.charAt(0) != '[') {
		// It is not an array.
		IREMBeanTypeProxy superTypeProxy = null;
		if (!ret.isInterface && ret.superClassname.length() != 0) {
			// Get the beantype proxy of the superclass.
			superTypeProxy = getBeanTypeProxy(ret.superClassname, connect);
		}
		
		// First check with the factory for the package of the class.
		// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
		// the package ended and the class started.
		int packageIndex = ret.className.lastIndexOf('.');
		if (packageIndex != -1) {
			String packageName = ret.className.substring(0, packageIndex);
			IREMBeanTypeProxyFactory packageFactory = (IREMBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
			if (packageFactory != null) {
				beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(ret.className, classID, superTypeProxy);
				if (beanTypeProxy != null) {
					registerBeanTypeProxy(beanTypeProxy, false);
					return beanTypeProxy;
				}
			}
		}	
			
		if (ret.isInterface) {
			// Interface never have a super type, so we will let the object class do it for us.
			beanTypeProxy = new REMInterfaceBeanTypeProxy(fFactoryRegistry, classID, ret.className);	
		} else {		
			// Ask the beantype proxy of the superclass 
			// to create a beantype proxy of the same beantype proxy class.
			// This is so that any subclasses will get the same beantype proxy class
			// for it if it is special.			
			if (superTypeProxy != null)
				beanTypeProxy = superTypeProxy.newBeanTypeForClass(classID, ret.className, ret.isAbstract);
		}
 
		// Cache the instance so we can re-use it again
		if (beanTypeProxy != null)		
			registerBeanTypeProxy(beanTypeProxy, false);
		return beanTypeProxy;
	} else {		
		// It is an array.
		beanTypeProxy = new REMArrayBeanTypeProxy(fFactoryRegistry, classID, ret.className, objectClass );
		registerBeanTypeProxy(beanTypeProxy, false);
		return beanTypeProxy;
	}	
}

/*
 * It is important that this be called only from within a transaction.
 */
private Commands.GetClassIDReturn getClassIDReturn(IREMConnection connection, Integer classID) throws CommandException, ThrowableProxy {
	try {
		return connection.getClassFromID(classID.intValue());
	} catch (CommandErrorException e) {
		fBeanFactory.processErrorReturn(e);	// Let proxy factory handle the error return
	}
	return null;
}



/**
 * registerBeanTypeProxy.
 * Register this bean type proxy on behalf of the
 * custom factory. This is so that during initializations,
 * the custom factory can cache specific bean type proxies
 * ahead of time. 
 *
 * The permanent flag indicates whether this bean type should never be
 * released (i.e. not even explicitly released).
 */
public synchronized void registerBeanTypeProxy(IBeanTypeProxy aBeanTypeProxy, boolean permanent) {
	fBeanProxies.put(aBeanTypeProxy.getTypeName(), aBeanTypeProxy);
	fBeanFactory.registerProxy((IREMBeanProxy) aBeanTypeProxy);
	if (permanent)
		fPermanentProxies.add(aBeanTypeProxy);
}

/**
 * A beantype proxy is asked to be released. We can only
 * release ones that were not in the permanent set that we 
 * initialized with. Those in the permanent set can't be changed
 * so we can't release them. 
 *
 * Answer whether it can be released from the server
 * too.
 *
 * NOTE: Package protected since only REMStandardBeanProxyFactory should call it.
 */
boolean releaseProxy(IBeanTypeProxy proxy) {
/** Currently we won't allow any bean type proxies to be released. We don't have a good
 *  strategy for handling that there may be hard refs from subtypes. One thought is that
 *  beanproxies table should store SoftReferences so that only when space is needed, 
 *  that any beantype that doesn't have a subtype (since subtypes hold a strong ref) or,
 *  is in the permanent table (since that is hardref) could be GC'd. Then what would happen
 *  is on releaseProxy we don't actually release, we change it to a WeakRef so that it would
 *  definitely be released on a GC. These are complicated arch. and we're not sure if it
 *  should be allowed or not. So for now, we don't allow them to be released.
	if (!fPermanentProxies.contains(proxy)) {
		// We can release it. It is not one of the permanent ones.
		synchronized(this) {
			fBeanProxies.remove(proxy.getTypeName());
			return true;
		}
	}
*/	
	return false;
}

/*
 * Terminate this factory. Since all of the proxies are registered in the
 * proxy factory, there is no need to release them here. There is no
 * need to clear out any fields since this factory will not be held onto
 * by anything and so it will be GC'd.
 */
public void terminateFactory(boolean wait) {
}

/* (non-Javadoc)
 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isBeanTypeRegistered(String)
 */
public synchronized boolean isBeanTypeRegistered(String className) {
	return fBeanProxies.containsKey(MapTypes.getJNIFormatName(className));
}

/* (non-Javadoc)
 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registeredTypes()
 */
public Set registeredTypes() {
	return fBeanProxies.keySet();
}

/* (non-Javadoc)
 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isBeanTypeNotFound(String)
 */
public synchronized boolean isBeanTypeNotFound(String className) {
	return fNotFoundTypes != null && fNotFoundTypes.contains(MapTypes.getJNIFormatName(className));
}

/* (non-Javadoc)
 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isMaintainNotFoundTypes()
 */
public synchronized boolean isMaintainNotFoundTypes() {
	return fNotFoundTypes != null;
}

/* (non-Javadoc)
 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#setMaintainNotFoundTypes(boolean)
 */
public synchronized void setMaintainNotFoundTypes(boolean maintain) {
	if (maintain) {
		if (fNotFoundTypes == null)
			fNotFoundTypes = new HashSet();
	} else
		fNotFoundTypes = null;
}

}


