/*******************************************************************************
 * 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.beaninfo.adapters;
/*
 *  $RCSfile: BeaninfoNature.java,v $
 *  $Revision: 1.30 $  $Date: 2005/05/18 20:59:17 $ 
 */

import java.io.*;
import java.text.MessageFormat;
import java.util.*;
import java.util.logging.Level;

import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.jdt.core.*;
import org.osgi.framework.Bundle;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;

import org.eclipse.jem.internal.beaninfo.core.*;
import org.eclipse.jem.internal.java.adapters.JavaXMIFactoryImpl;
import org.eclipse.jem.internal.java.beaninfo.IIntrospectionAdapter;
import org.eclipse.jem.internal.java.init.JavaInit;
import org.eclipse.jem.internal.plugin.JavaEMFNature;
import org.eclipse.jem.internal.proxy.core.*;
import org.eclipse.jem.util.emf.workbench.ResourceHandler;


/**
 * The beaninfo nature. It is created for a project and holds the
 * necessary info for beaninfo to be performed on a project.
 */

public class BeaninfoNature implements IProjectNature {

	public static final String NATURE_ID = BeaninfoPlugin.PI_BEANINFO_PLUGINID + ".BeanInfoNature"; //$NON-NLS-1$
	public static final String P_BEANINFO_SEARCH_PATH = ".beaninfoConfig"; //$NON-NLS-1$
	
	public static final QualifiedName CONFIG_INFO_SESSION_KEY = new QualifiedName(BeaninfoPlugin.PI_BEANINFO_PLUGINID, "CONFIG_INFO"); //$NON-NLS-1$
	public static final QualifiedName BEANINFO_CONTRIBUTORS_SESSION_KEY = new QualifiedName(BeaninfoPlugin.PI_BEANINFO_PLUGINID, "BEANINFO_CONTRIBUTORS"); //$NON-NLS-1$

	private ResourceTracker resourceTracker;
	// This class listens for changes to the beaninfo paths file, and if changed it marks all stale
	// so the next time anything is needed it will recycle the vm. It will also listen about to close or
	// about to delete of the project so that it can cleanup.
	private class ResourceTracker implements IResourceChangeListener{
		public void resourceChanged(IResourceChangeEvent e) {
			// About to close or delete the project and it is ours, so we need to cleanup.
			// Performance: It has been noted that dres.equals(...) can be slow with the number
			// of visits done. Checking just the last segment (getName()) first before checking
			// the entire resource provides faster testing. If the last segment is not equal,
			// then the entire resource could not be equal.
			IResource eventResource = e.getResource();
			if (eventResource.getName().equals(getProject().getName()) && eventResource.equals(getProject())) {
				cleanup(false, true);	// No need to clean up resources (false parm) because in this case Java EMF Model will always be going away.
				return;
			}
			// Note: the BeaninfoModelSynchronizer takes care of both .classpath and .beaninfoconfig changes
			// in this project and any required projects.
		}
	}

	private ProxyFactoryRegistry.IRegistryListener registryListener = new ProxyFactoryRegistry.IRegistryListener() {
		/**
		 * @see org.eclipse.jem.internal.proxy.core.ProxyFactoryRegistry.IRegistryListener#registryTerminated(ProxyFactoryRegistry)
		 */
		public void registryTerminated(ProxyFactoryRegistry registry) {
			markAllStale();
		};
	};

	/**
	 * Get the runtime nature for the project, create it if necessary.
	 */
	public static BeaninfoNature getRuntime(IProject project) throws CoreException {
		JavaEMFNature.createRuntime(project);	// Must force JAVAEMFNature creation first before we try to get ours. There is a chicken/egg problem if we let our nature try to get JavaEMFNature during setProject.
		if (project.hasNature(NATURE_ID))
			return (BeaninfoNature) project.getNature(NATURE_ID);
		else
			return createRuntime(project);
	}
	
	/**
	 * Return whether this project has a BeanInfo runtime turned on.
	 * 
	 * @param project
	 * @return <code>true</code> if it has the a BeanInfo runtime.
	 * @throws CoreException
	 * 
	 * @since 1.0.0
	 */
	public static boolean hasRuntime(IProject project) throws CoreException {
		return project.hasNature(NATURE_ID);
	}

	/**
	 * Test if this is a valid project for a Beaninfo Nature. It must be
	 * a JavaProject.
	 */
	public static boolean isValidProject(IProject project) {
		try {
			return project.hasNature(JavaCore.NATURE_ID);
		} catch (CoreException e) {
			return false;
		}
	}

	/**
	 * Create the runtime.
	 */
	private static BeaninfoNature createRuntime(IProject project) throws CoreException {
		if (!isValidProject(project))
			throw new CoreException(
				new Status(
					IStatus.ERROR,
					BeaninfoPlugin.PI_BEANINFO_PLUGINID,
					0,
					MessageFormat.format(
						BeanInfoAdapterMessages.getString(BeanInfoAdapterMessages.INTROSPECTFAILED),
						new Object[] { project.getName(), BeanInfoAdapterMessages.getString("BeaninfoNature.InvalidProject")}), //$NON-NLS-1$
					null));

		addNatureToProject(project, NATURE_ID);
		return (BeaninfoNature) project.getNature(NATURE_ID);
	}

	private static void addNatureToProject(IProject proj, String natureId) throws CoreException {
		IProjectDescription description = proj.getDescription();
		String[] prevNatures = description.getNatureIds();
		String[] newNatures = new String[prevNatures.length + 1];
		System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
		newNatures[prevNatures.length] = natureId;
		description.setNatureIds(newNatures);
		proj.setDescription(description, null);
	}

	private IProject fProject;
	protected ProxyFactoryRegistry fRegistry;
	protected ResourceSet javaRSet;
	protected BeaninfoModelSynchronizer fSynchronizer;
	protected static BeaninfoJavaReflectionKeyExtension fReflectionKeyExtension;

	/** 
	 * Configures the project with this nature.
	 * This is called by <code>IProject.getNature</code> and should not
	 * be called directly by clients.
	 * The nature extension id is added to the list of natures on the project by
	 * <code>IProject.getNature</code>, and need not be added here.
	 *
	 * @exception CoreException if this method fails.
	 */
	public void configure() throws CoreException {
	}

	/** 
	 * Removes this nature from the project, performing any required deconfiguration.
	 * This is called by <code>IProject.removeNature</code> and should not
	 * be called directly by clients.
	 * The nature id is removed from the list of natures on the project by
	 * <code>IProject.removeNature</code>, and need not be removed here.
	 *
	 * @exception CoreException if this method fails. 
	 */
	public void deconfigure() throws CoreException {
		removeSharedProperty(P_BEANINFO_SEARCH_PATH, null);
		cleanup(true, true);
	}
	
	/**
	 * Shutdown the nature. Called by BeanInfoPlugin to tell the nature that the plugin is being shutdown.
	 * It needs to cleanup.
	 * TODO <package-protected> because only BeanInfoPlugin should call it. (public for now but when we make
	 * BeanInfoNature an API it will be moved into the same package as BeanInfoPlugin).
	 * 
	 * @since 1.0.0
	 */
	public void shutdown() {
		cleanup(true, false);
	}


	/**
	 * Return a new ResourceSet that is linked correctly to this Beaninfo Nature.
	 * <p>
	 * This links up a ResourceSet so that it will work correctly with this nature.
	 * It makes sure that going through the ResourceSet that any "java:/..."
	 * classes can be found and it makes sure that any new classes are placed into the
	 * nature's resource set and not resource set doing the calling.
	 * <p>
	 * This should be used any time a resource set is needed that is not the
	 * project wide resource set associated with beaninfos, but will reference
	 * Java Model classes or instantiate.
	 * <p>
	 * An additional change is made too. The ResourceFactoryRegistry's extensionToResourceFactory map is modified
	 * to have an "java"->XMIResourceFactory entry added to it if EMF Examples is loaded. EMF Examples add
	 * the "java" extension and sets it to their own special JavaResourceFactory. 
	 * If EMF Examples is not loaded, then it falls back to the default "*" mapping, which is to XMIResourceFactory.
	 * This normally causes problems for many
	 * customers. If users of this resource set really want the EMF examples entry instead, after they retrieve the
	 * new resource set they can do this:
	 * <p>
	 * <pre><code>
	 * 	rset = beaninfoNature.newResourceSet();
	 * 	rset.getResourceFactoryRegistry().getExtensionToFactoryMap().remove("java");
	 * </code></pre>
	 * 
	 * @return a ResourceSet that is specially connected to the JEM java model.
	 * 
	 * @since 1.0.0
	 */
	public ResourceSet newResourceSet() {
		SpecialResourceSet rset = new SpecialResourceSet();
		rset.add(new ResourceHandler() {
			public EObject getEObjectFailed(ResourceSet originatingResourceSet, URI uri, boolean loadOnDemand) {
				return null; // We don't have any special things we can do in this case.
			}

			public Resource getResource(ResourceSet originatingResourceSet, URI uri) {
				// Always try to get it out of the nature's resource set because it may of been loaded there either as 
				// the "java:..." type or it could of been an override extra file (such as an override EMF package, for
				// example jcf has a side package containing the definition of the new attribute type. That file
				// will also be loaded into this resourceset. So to find it we need to go in here and try.
				//
				// However, if not found we won't go and try to load the resource. That could load in the wrong place.
				// Kludge: Because of a bug (feature :-)) in XMLHandler.getPackageFromURI(), it doesn't use getResource(...,true) and it tries instead
				// to use uri inputstream to load the package when not found. This bypasses our special create resource and so
				// packages are not automatically created. So we need to do load on demand here instead if it is a java protocol.
				// EMF will not be fixing this. It is working as designed.
				return getResourceSet().getResource(uri, JavaXMIFactoryImpl.SCHEME.equals(uri.scheme()));
			}

			public Resource createResource(ResourceSet originatingResourceSet, URI uri) {
				// This is the one. It has got here because it couldn't find a resource already loaded.
				// If it is a "java:/..." protocol resource, then we want to make sure it is loaded at the BeaninfoNature context
				// instead of the lower one.
				if (JavaXMIFactoryImpl.SCHEME.equals(uri.scheme()))
					return getResourceSet().getResource(uri, true);
				else
					return null;
			}
		});
		// [71473] Restore "*.java" to be an XMIResource. If EMF Examples are loaded they overload this and load their special resource for "*.java" which we don't want.
		// If some user really wants that, they grab the resource resource set and remove our override.
		if (Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().containsKey("java")) { //$NON-NLS-1$
			// Need to add an override to go to XMI instead.
			rset.getResourceFactoryRegistry().getExtensionToFactoryMap().put("java", new XMIResourceFactoryImpl()); //$NON-NLS-1$
		}
		return rset;
	}
	/**
	 * Clean up, this means either the project is being closed, deleted, or it means that
	 * the nature is being removed from the project. Either way that means to
	 * terminate the VM and remove what we added to the context if the flag says clear it.
	 * <p>
	 * This should be called ONLY when this instance of the nature is no longer needed. It
	 * will be recreated for any new uses. That is because we will be removing ourselves
	 * from the list of active natures in the BeanInfoPlugin.
	 * 
	 * @param clearResults clear the results such that any JEM model objects have no BeanInfo
	 * adapters attached to them. This allows BeanInfo to be GC'd without being hung onto.
	 *  
	 * @param deregister Deregister from the BeanInfoPlugin. Normally this will always be true, but it
	 * will be called with false when BeanInfoPlugin is calling back to shutdown.
	 */
	protected void cleanup(boolean clearResults, boolean deregister) {
		if (deregister)
			BeaninfoPlugin.getPlugin().removeBeanInfoNature(this);
		getProject().getWorkspace().removeResourceChangeListener(resourceTracker);
		resourceTracker = null;
		fSynchronizer.stopSynchronizer(clearResults);
		Init.cleanup(javaRSet, clearResults);
		if (fRegistry != null)
			fRegistry.terminateRegistry();

		javaRSet = null;
		fRegistry = null;
		fProject = null;
		fSynchronizer = null;
	}

	/** 
	 * Returns the project to which this project nature applies.
	 *
	 * @return the project handle
	 */
	public IProject getProject() {
		return fProject;
	}

	/**
	 * Sets the project to which this nature applies.
	 * Used when instantiating this project nature runtime.
	 * This is called by <code>IProject.addNature</code>
	 * and should not be called directly by clients.
	 *
	 * @param project the project to which this nature applies
	 */
	public void setProject(IProject project) {
		fProject = project;
		BeaninfoPlugin.getPlugin().addBeanInfoNature(this);

		try {
			// The nature has been started for this project, need to setup the introspection process now.
			JavaEMFNature javaNature = JavaEMFNature.createRuntime(fProject);
			JavaInit.init();
			if (fReflectionKeyExtension == null) {
				// Register the reflection key extension.
				fReflectionKeyExtension = new BeaninfoJavaReflectionKeyExtension();
				JavaXMIFactoryImpl.INSTANCE.registerReflectionKeyExtension(fReflectionKeyExtension);
			}

			javaRSet = javaNature.getResourceSet();
			Init.initialize(javaRSet, new IBeaninfoSupplier() {
				public ProxyFactoryRegistry getRegistry() {
					return BeaninfoNature.this.getRegistry();
				}

				public boolean isRegistryCreated() {
					return BeaninfoNature.this.isRegistryCreated();
				}
				
				public void closeRegistry() {
					BeaninfoNature.this.closeRegistry();
				}
				
				public IProject getProject() {
					return BeaninfoNature.this.getProject();
				}
			});
			fSynchronizer =
				new BeaninfoModelSynchronizer(
					(BeaninfoAdapterFactory) EcoreUtil.getAdapterFactory(javaRSet.getAdapterFactories(), IIntrospectionAdapter.ADAPTER_KEY),
					JavaCore.create(javaNature.getProject()));
			resourceTracker = new ResourceTracker();
			project.getWorkspace().addResourceChangeListener(resourceTracker, IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.PRE_DELETE);
		} catch (CoreException e) {
			BeaninfoPlugin.getPlugin().getLogger().log(e.getStatus());
		}
	}

	/**
	 * Close the registry. It needs to be recycled because a class has changed
	 * and now the new class needs to be accessed.
	 */
	protected void closeRegistry() {
		ProxyFactoryRegistry reg = null;
		synchronized (this) {
			reg = fRegistry;
			fRegistry = null;
			try {
				// Wipe out the Session properties so that they are recomputed.
				getProject().setSessionProperty(CONFIG_INFO_SESSION_KEY, null);
				getProject().setSessionProperty(BEANINFO_CONTRIBUTORS_SESSION_KEY, null);			
			} catch (CoreException e) {
				BeaninfoPlugin.getPlugin().getLogger().log(e, Level.INFO);
			}
		}
		if (reg != null) {
			reg.removeRegistryListener(registryListener);
			reg.terminateRegistry();
		}
	}

	private static final String PI_CLASS = "class"; //$NON-NLS-1$
	
	/**
	 * Using the given configuration info, compute the BeanInfo config info needed. This sets the
	 * session properties BEANINFO_CONTRIBUTORS_SESSION_KEY and CONFIG_INFO_SESSION_KEY.
	 * 
	 * @param info
	 * @throws CoreException
	 * 
	 * @since 1.1.0
	 */
	public static void computeBeanInfoConfigInfo(IConfigurationContributionInfo info) throws CoreException {
		// First time for this nature, or first time after registry reset. Need to compute the info.
		// It is possible for this to be called BEFORE the first usage of BeanInfo. The editor usually
		// brings up the editor's registry before it gets anything from BeanInfo.
		List contributorsList = new ArrayList(10);
		if (!info.getContainerIds().isEmpty()) {
			// Run through all of the visible container ids that are applicable and get BeanInfo contributors.
			Iterator containerIdItr = info.getContainerIds().entrySet().iterator();
			while (containerIdItr.hasNext()) {
				Map.Entry entry = (Map.Entry) containerIdItr.next();
				if (((Boolean) entry.getValue()).booleanValue()) {
					IConfigurationElement[] contributors = BeaninfoPlugin.getPlugin().getContainerIdContributors(
							(String) entry.getKey());
					if (contributors != null) {
						for (int i = 0; i < contributors.length; i++) {
							try {
								Object contributor = contributors[i].createExecutableExtension(PI_CLASS);
								if (contributor instanceof IBeanInfoContributor)
									contributorsList.add(contributor);
							} catch (CoreException e) {
								BeaninfoPlugin.getPlugin().getLogger().log(e, Level.WARNING);
							}
						}
					}
				}
			}						
		}
		
		if (!info.getPluginIds().isEmpty()) {
			// Run through all of the visible plugin ids that are applicable and get BeanInfo contributors.
				Iterator pluginIdItr = info.getPluginIds().entrySet().iterator();
				while (pluginIdItr.hasNext()) {
					Map.Entry entry = (Map.Entry) pluginIdItr.next();
					if (((Boolean) entry.getValue()).booleanValue()) {
						IConfigurationElement[] contributors = BeaninfoPlugin.getPlugin().getPluginContributors(
								(String) entry.getKey());
						if (contributors != null) {
							for (int i = 0; i < contributors.length; i++) {
							try {
								Object contributor = contributors[i].createExecutableExtension(PI_CLASS);
								if (contributor instanceof IBeanInfoContributor)
									contributorsList.add(contributor);
							} catch (CoreException e) {
								BeaninfoPlugin.getPlugin().getLogger().log(e, Level.WARNING);
							}
						}
					}
				}
			}
		}
			
			// Save it for all beaninfo processing (and configuration processing if they implement proxy configuration contributor).
		IBeanInfoContributor[] explicitContributors = (IBeanInfoContributor[]) contributorsList.toArray(new IBeanInfoContributor[contributorsList.size()]);
		info.getJavaProject().getProject().setSessionProperty(BEANINFO_CONTRIBUTORS_SESSION_KEY, explicitContributors);
		// Save it for override processing. That happens over and over later after all config processing is done.
		// Do it last so that if there is a race condition, since this property is a flag to indicate we have data,
		// we need to make sure the Beaninfo data is already set at the point we set this.
		// We could actually set it twice because of this, but it is the same data, so, so what.
		info.getJavaProject().getProject().setSessionProperty(CONFIG_INFO_SESSION_KEY, info);
	}

	/**
	 * Get registry, creating it if necessary.
	 * @return the registry.
	 * 
	 * @since 1.0.0
	 */
	public ProxyFactoryRegistry getRegistry() {
		synchronized (this) {
			if (fRegistry != null)
				return fRegistry;
		}
		// Now need to start the appropriate job. In another class so that it can handle dynamically checking if 
		// UI is available to even do this (it maybe not in a UI mode, so then just do it.
		CreateRegistryJobHandler.createRegistry(this);
		return fRegistry;
	}
	
	/*
	 * This is <package-protected> so that only the appropriate create job in this
	 * package can call it. This is because this must be controlled to only be
	 * done when build not in progress and serial access.
	 */
	void createRegistry(IProgressMonitor pm) {
		pm.beginTask(BeanInfoAdapterMessages.getString("UICreateRegistryJobHandler.StartBeaninfoRegistry"), 100); //$NON-NLS-1$		
		if (isRegistryCreated()) {
			pm.done();
			return; // It had already been created. Could of been because threads were racing to do the creation, and one got there first.
		}

		try {
			ConfigurationContributor configurationContributor = (ConfigurationContributor) getConfigurationContributor();
			configurationContributor.setNature(this);
			ProxyFactoryRegistry registry = ProxyLaunchSupport.startImplementation(fProject, "Beaninfo", //$NON-NLS-1$
					new IConfigurationContributor[] { configurationContributor}, false, new SubProgressMonitor(pm, 100));
			registry.addRegistryListener(registryListener);
			synchronized(this) {
				fRegistry = registry;
			}
		} catch (CoreException e) {
			BeaninfoPlugin.getPlugin().getLogger().log(e.getStatus());
		} finally {
			pm.done();
		}
	}
	
	public synchronized boolean isRegistryCreated() {
		return fRegistry != null;
	}
	
	/**
	 * Check to see if the nature is still valid. If the project has been
	 * renamed, the nature is still around, but the project has been closed.
	 * So the nature is now invalid.
	 * 
	 * @return Is this a valid nature. I.e. is the project still open.
	 */
	public boolean isValidNature() {
		return fProject != null;
	}

	/**
	 * Set the search path onto the registry.
	 */
	protected void setProxySearchPath(ProxyFactoryRegistry registry, List searchPaths) {
		if (searchPaths != null) {
			String[] stringSearchPath = (String[]) searchPaths.toArray(new String[searchPaths.size()]);
			Utilities.setBeanInfoSearchPath(registry, stringSearchPath);
		} else
			Utilities.setBeanInfoSearchPath(registry, null);
	}

	private static final String ENCODING = "UTF-8"; //$NON-NLS-1$
	static final String sBeaninfos = "beaninfos"; // Root element name //$NON-NLS-1$
	/**
	 * Get the persistent search path. It is copy.
	 */
	public BeaninfosDoc getSearchPath() {
		BeaninfosDoc bdoc = null;
		try {
			InputStream property = getSharedProperty(P_BEANINFO_SEARCH_PATH);
			if (property != null) {
				try {
					// Need to reconstruct from the XML format.
					Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new InputStreamReader(property, ENCODING)));
					Element root = doc.getDocumentElement();
					if (root != null && root.getNodeName().equalsIgnoreCase(sBeaninfos)) {
						bdoc = BeaninfosDoc.readEntry(new DOMReader(), root, getProject());
					}
				} finally {
					try {
						property.close();
					} catch (IOException e) {
					}
				}
			}
		} catch (CoreException e) {
			BeaninfoPlugin.getPlugin().getLogger().log(e.getStatus());
		} catch (Exception e) {
			BeaninfoPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, BeaninfoPlugin.PI_BEANINFO_PLUGINID, 0, "", e)); //$NON-NLS-1$
		}
		return bdoc;
	}

	/**
	 * Set the persistent search path. No progress monitor.
	 */
	public void setSearchPath(BeaninfosDoc searchPath) throws CoreException {
		setSearchPath(searchPath, null);
	}

	/**
	 * Set the persistent search path with a progress monitor
	 */
	public void setSearchPath(BeaninfosDoc searchPath, IProgressMonitor monitor) throws CoreException {
		String property = null;
		if (searchPath != null && searchPath.getSearchpath().length > 0) {
			try {
				Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
				Element root = doc.createElement(sBeaninfos); // Create Root Element
				IBeaninfosDocEntry[] entries = searchPath.getSearchpath();
				for (int i = 0; i < entries.length; i++)
					root.appendChild(entries[i].writeEntry(doc, getProject())); // Add to the search path
				doc.appendChild(root); // Add Root to Document
				StringWriter strWriter = new StringWriter();

				Result result = new StreamResult(strWriter);
				Source source = new DOMSource(doc);
				Transformer transformer = TransformerFactory.newInstance().newTransformer();
				transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
				transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
				transformer.transform(source, result);
				property = strWriter.toString();
			} catch (TransformerConfigurationException e) {
				BeaninfoPlugin.getPlugin().getLogger().log(e, Level.WARNING);
			} catch (TransformerException e) {
				BeaninfoPlugin.getPlugin().getLogger().log(e, Level.WARNING);
			} catch (ParserConfigurationException e) {
				BeaninfoPlugin.getPlugin().getLogger().log(e, Level.WARNING);
			} catch (FactoryConfigurationError e) {
				BeaninfoPlugin.getPlugin().getLogger().log(e, Level.WARNING);
			}
		}

		if (property != null) {
			// If it hasn't changed, don't write it back out. This is so that if the file hasn't
			// been checked out and it is the same, we don't want to bother the user. This is because
			// we don't know if the user had simply browsed the search path or had actually changed and
			// set it back to what it was. In either of those cases it would be a bother to ask the
			// user to checkout the file.
			InputStream is = getSharedProperty(P_BEANINFO_SEARCH_PATH);
			if (is != null) {
				try {
					try {
						InputStreamReader reader = new InputStreamReader(is, ENCODING);
						char[] chars = new char[1000];
						StringBuffer oldProperty = new StringBuffer(1000);
						int read = reader.read(chars);
						while (read != -1) {
							oldProperty.append(chars, 0, read);
							read = reader.read(chars);
						}
						if (oldProperty.toString().equals(property))
							return;
					} catch (IOException e) {
					} // Didn't change.
				} finally {
					try {
						is.close();
					} catch (IOException e) {
					}
				}
			}
			setSharedProperty(P_BEANINFO_SEARCH_PATH, property, monitor);
		} else
			removeSharedProperty(P_BEANINFO_SEARCH_PATH, monitor);
	}

	/**
	 * Return the resource set for all java packages in this nature.
	 */
	public ResourceSet getResourceSet() {
		return javaRSet;
	}

	protected void markAllStale() {
		// Mark all stale so that the registry will be recycled.
		if (fRegistry != null) {
			// We have a registry running, we need to indicate recycle is needed.
			fSynchronizer.getAdapterFactory().markAllStale();
			// Mark all stale. Next time we need anything it will be recycled.
		}
	}

	/**
	 * Compute the file name to use for a given shared property
	 */
	protected String computeSharedPropertyFileName(QualifiedName qName) {
		return qName.getLocalName();
	}

	/**
	 * Retrieve a shared property on a project. If the property is not defined, answers null.
	 * Note that it is orthogonal to IResource persistent properties, and client code has to decide
	 * which form of storage to use appropriately. Shared properties produce real resource files which
	 * can be shared through a VCM onto a server. Persistent properties are not shareable.
	 *
	 */
	protected InputStream getSharedProperty(String propertyFileName) throws CoreException {
		IFile rscFile = getProject().getFile(propertyFileName);
		if (rscFile.exists())
			return rscFile.getContents(true);
		else
			return null;
	}

	/**
	 * Record a shared persistent property onto a project.
	 * Note that it is orthogonal to IResource persistent properties, and client code has to decide
	 * which form of storage to use appropriately. Shared properties produce real resource files which
	 * can be shared through a VCM onto a server. Persistent properties are not shareable.
	 * 
	 * shared properties end up in resource files, and thus cannot be modified during
	 * delta notifications (a CoreException would then be thrown).
	 * 
	 */
	protected void setSharedProperty(String propertyName, String value, IProgressMonitor monitor) throws CoreException {

		try {
			IFile rscFile = getProject().getFile(propertyName);
			InputStream input = new ByteArrayInputStream(value.getBytes(ENCODING));
			// update the resource content
			if (rscFile.exists()) {
				rscFile.setContents(input, true, false, null);
			} else {
				rscFile.create(input, true, monitor);
			}
		} catch (UnsupportedEncodingException e) {
		}
	}

	/**
	 * Remove a shared persistent property onto a project.
	 * Note that it is orthogonal to IResource persistent properties, and client code has to decide
	 * which form of storage to use appropriately. Shared properties produce real resource files which
	 * can be shared through a VCM onto a server. Persistent properties are not shareable.
	 * 
	 * shared properties end up in resource files, and thus cannot be modified during
	 * delta notifications (a CoreException would then be thrown).
	 * 
	 */
	protected void removeSharedProperty(String propertyName, IProgressMonitor monitor) throws CoreException {

		IFile rscFile = getProject().getFile(propertyName);
		rscFile.delete(true, true, monitor);
	}

	/**
	 * Return a configuration contributor that sets up a vm to allow
	 * introspection. This will make sure the appropriate paths
	 * are in the classpath to allow access to the beaninfos, and
	 * it will setup the beaninfo search path for this project.
	 */
	public IConfigurationContributor getConfigurationContributor() {
		return new ConfigurationContributor(getSearchPath());
	}

	private static class ConfigurationContributor extends ConfigurationContributorAdapter {

		private BeaninfosDoc doc;
		List computedSearchPath;
				
		// The nature. If the nature is not set then this contributor is one
		// used by some other later proxy registry to get the beaninfo classes into their paths. In that case
		// we can expect the config info to be in the session variable for our use. Otherwise we will need to
		// add it here. Also don't set searchpath stuff if not nature because only the beaninfo one will do introspection.
		private BeaninfoNature nature;	
		
		private IConfigurationContributionInfo info;
		private IBeanInfoContributor[] explicitContributors;

		public ConfigurationContributor(BeaninfosDoc doc) {
			this.doc = doc;
		}

		/*
		 * Set that this is the nature contributor. Not null, means that this is the contributor being
		 * used to setup the registry for the project's beaninfo nature. null (default) means that this
		 * is one created to add to some editor's registry.
		 * 
		 * Note: This MUST be set before initialize is called or it will not work correctly. If not set, it 
		 * will be considered not for BeanInfo nature directly.
		 */
		public void setNature(BeaninfoNature nature) {
			this.nature = nature;
			if (nature != null)
				computedSearchPath = new ArrayList(3);	// We will be gathering this info.
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.jem.internal.proxy.core.IConfigurationContributor#initialize(org.eclipse.jem.internal.proxy.core.IConfigurationContributionInfo)
		 */
		public void initialize(IConfigurationContributionInfo info) {
			this.info = info;
			try {
				if (info.getJavaProject().getProject().getSessionProperty(CONFIG_INFO_SESSION_KEY) == null) {
					// TODO For now we will rebuild for each time we open a registry, but it actually is only needed if a classpath
					// changes for some reason. At that point we can get it out of here.
					
					computeBeanInfoConfigInfo(info);					
				} 
				explicitContributors = (IBeanInfoContributor[]) info.getJavaProject().getProject().getSessionProperty(BEANINFO_CONTRIBUTORS_SESSION_KEY);
			} catch (CoreException e) {
				BeaninfoPlugin.getPlugin().getLogger().log(e);
			}
		}
		
		public void contributeClasspaths(final IConfigurationContributionController controller) throws CoreException {
			// Contribute for this project
			contributeClasspathsForProject(controller, info.getJavaProject().getProject(), doc, true);
						
			if (!info.getProjectPaths().isEmpty()) {
				// Run through all of the visible projects and contribute the classpaths (which come from the BeanInfo docs, if they have any).
				IWorkspaceRoot root = info.getJavaProject().getProject().getWorkspace().getRoot();
				Iterator projIter = info.getProjectPaths().entrySet().iterator();
				while (projIter.hasNext()) {
					Map.Entry entry = (Map.Entry) projIter.next();
					if (((Boolean) entry.getValue()).booleanValue()) {
						IResource res = root.findMember((IPath) entry.getKey());
						if (res instanceof IProject && ((IProject) res).isOpen() && BeaninfoNature.hasRuntime((IProject) res))
							contributeClasspathsForProject(controller, (IProject) res, BeaninfoNature.getRuntime((IProject) res)
									.getSearchPath(), false);
					}
				}
			}			
			
			if (!info.getContainerIds().isEmpty()) {
				// Run through all of the visible container ids that are applicable.
				Iterator containerIdItr = info.getContainerIds().entrySet().iterator();
				while (containerIdItr.hasNext()) {
					Map.Entry entry = (Map.Entry) containerIdItr.next();
					if (((Boolean) entry.getValue()).booleanValue()) {
						processBeaninfoEntries(BeaninfoPlugin.getPlugin().getContainerIdBeanInfos((String) entry.getKey()),
								controller, info.getJavaProject());
					}
				}
				
			}
			
			if (!info.getPluginIds().isEmpty()) {
				// Run through all of the visible plugin ids that are applicable.
				Iterator pluginIdItr = info.getPluginIds().entrySet().iterator();
				while (pluginIdItr.hasNext()) {
					Map.Entry entry = (Map.Entry) pluginIdItr.next();
					if (((Boolean) entry.getValue()).booleanValue()) {
						processBeaninfoEntries(BeaninfoPlugin.getPlugin().getPluginBeanInfos((String) entry.getKey()), controller, info.getJavaProject());
					}
				}
				
			}
			
			if (!info.getContainers().isEmpty()) {
				// Run through all of the visible containers that implement IBeanInfoContributor and ask them for the contributions.
				Iterator containerItr = info.getContainers().entrySet().iterator();
				while (containerItr.hasNext()) {
					Map.Entry entry = (Map.Entry) containerItr.next();
					if (((Boolean) entry.getValue()).booleanValue()) {
						if (entry.getKey() instanceof IBeanInfoContributor)
							processBeaninfoEntries(((IBeanInfoContributor) entry.getKey()).getBeanInfoEntryContributions(info),
									controller, info.getJavaProject());
					}
				}
				
			}			
				
			// And finally run through the explicit contributors.				
			for (int i = 0; i < explicitContributors.length; i++) {
				final IBeanInfoContributor contributor = explicitContributors[i];
				processBeaninfoEntries(contributor.getBeanInfoEntryContributions(info), controller, info.getJavaProject());
				if (contributor instanceof IConfigurationContributor) {
					Platform.run(new ISafeRunnable() {
						public void handleException(Throwable exception) {
							// do nothing. by default platform logs.
						}

						public void run() throws Exception {;
							if (contributor instanceof IConfigurationContributor)
								((IConfigurationContributor) contributor).contributeClasspaths(controller);
						}
					});
				}
			}
			
			// Add the common and beaninfovm.jar and any nls to the end of the classpath.
			controller.contributeClasspath(BeaninfoPlugin.getPlugin().getBundle(), "beaninfocommon.jar", IConfigurationContributionController.APPEND_USER_CLASSPATH, true); //$NON-NLS-1$
			
			// Add the beaninfovm.jar and any nls to the end of the classpath.
			controller.contributeClasspath(BeaninfoPlugin.getPlugin().getBundle(), "vm/beaninfovm.jar", IConfigurationContributionController.APPEND_USER_CLASSPATH, true); //$NON-NLS-1$
		}

		private IClasspathEntry get(IClasspathEntry[] array, SearchpathEntry se) {
			for (int i = 0; i < array.length; i++) {
				if (array[i].getEntryKind() == se.getKind() && array[i].getPath().equals(se.getPath()))
					return array[i];
			}
			return null;
		}

		private static final IBeaninfosDocEntry[] EMPTY_ENTRIES = new IBeaninfosDocEntry[0];
		
		/*
		 * Contribute classpaths for the specified project. If doc is passed in, then this is the top level and
		 * all should be added. If no doc, then this is pre-req'd project, and then we will handle exported entries only.
		 */
		protected void contributeClasspathsForProject(
			IConfigurationContributionController controller,
			IProject project,
			BeaninfosDoc doc,
			boolean toplevelProject)
			throws CoreException {
			
			IJavaProject jProject = JavaCore.create(project);
			IClasspathEntry[] rawPath = jProject.getRawClasspath();

			// Search path of this project
			IBeaninfosDocEntry[] entries = (doc != null) ? doc.getSearchpath() : EMPTY_ENTRIES;

			for (int i = 0; i < entries.length; i++) {
				IBeaninfosDocEntry entry = entries[i];
				if (entry instanceof BeaninfoEntry) {
					BeaninfoEntry be = (BeaninfoEntry) entry;
					if (toplevelProject || be.isExported()) {
						// First project or this is an exported beaninfo, so we process it.
						processBeaninfoEntry(be, controller, jProject);
					}
				} else if (nature != null){
					// Just a search path entry. There is no beaninfo jar to pick up.
					// We have a nature, so we process search path.
					SearchpathEntry se = (SearchpathEntry) entry;
					if (!toplevelProject) {
						// We are in a nested project, find the raw classpath entry to see
						// if this entry is exported. Only do it if exported. (Note: exported is only used on non-source. Source are always exported).
						IClasspathEntry cpe = get(rawPath, se);
						if (cpe == null || (cpe.getEntryKind() != IClasspathEntry.CPE_SOURCE && !cpe.isExported())) {
							continue; // Not exist or not exported, so we don't want it here either.
						}
					}

					String pkg = se.getPackage();
					if (pkg != null) {
						// Explicit search path
						if (!computedSearchPath.contains(pkg))
							computedSearchPath.add(pkg);
					} else {
						// We no longer allow this, but just to be on safe side we test for it.
					}
				}
			}
		}

		protected void processBeaninfoEntries(
			BeaninfoEntry[] entries,
			IConfigurationContributionController controller,
			IJavaProject javaProject)
			throws CoreException {
			if (entries != null) {
				for (int i = 0; i < entries.length; i++)
					processBeaninfoEntry(entries[i], controller, javaProject);
			}
		}

		protected void processBeaninfoEntry(
			BeaninfoEntry entry,
			IConfigurationContributionController controller,
			IJavaProject javaProject)
			throws CoreException {
			Object[] cps = entry.getClasspath(javaProject);
			for (int j = 0; j < cps.length; j++) {
				Object cp = cps[j];
				if (cp instanceof IProject)
					controller.contributeProject((IProject) cp);
				else if (cp instanceof String)
					controller.contributeClasspath(ProxyLaunchSupport.convertStringPathToURL((String) cp), IConfigurationContributionController.APPEND_USER_CLASSPATH);
				else if (cp instanceof IPath) {
					IPath path = (IPath) cp;
					Bundle bundle = Platform.getBundle(path.segment(0));
					if (bundle != null)
						controller.contributeClasspath(bundle, path.removeFirstSegments(1), IConfigurationContributionController.APPEND_USER_CLASSPATH, true);
				}
			}

			if (nature != null) {
				// Now add in the package names.
				SearchpathEntry[] sees = entry.getSearchPaths();
				for (int j = 0; j < sees.length; j++) {
					SearchpathEntry searchpathEntry = sees[j];
					if (!computedSearchPath.contains(searchpathEntry.getPackage()))
						computedSearchPath.add(searchpathEntry.getPackage());
				}
			}
		}

		public void contributeToConfiguration(final ILaunchConfigurationWorkingCopy config) {
			for (int i = 0; i < explicitContributors.length; i++) {
				final int ii = i;
				Platform.run(new ISafeRunnable() {
					public void handleException(Throwable exception) {
						// do nothing. by default platform logs.
					}

					public void run() throws Exception {
						IBeanInfoContributor contributor = explicitContributors[ii];
						if (contributor instanceof IConfigurationContributor)
							((IConfigurationContributor) contributor).contributeToConfiguration(config);
					}
				});
			}			
		}

		public void contributeToRegistry(final ProxyFactoryRegistry registry) {
			if (nature != null)
				nature.setProxySearchPath(registry, computedSearchPath);
			for (int i = 0; i < explicitContributors.length; i++) {
				final int ii = i;
				Platform.run(new ISafeRunnable() {
					public void handleException(Throwable exception) {
						// do nothing. by default platform logs.
					}

					public void run() throws Exception {
						IBeanInfoContributor contributor = explicitContributors[ii];
						if (contributor instanceof IConfigurationContributor)
							((IConfigurationContributor) contributor).contributeToRegistry(registry);
					}
				});
			}			
		}
	}


}
