/*******************************************************************************
 * Copyright (c) 2006, 2010 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.core;

import javax.xml.parsers.SAXParserFactory;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jpt.core.internal.JptCoreMessages;
import org.eclipse.jpt.core.internal.platform.JpaPlatformManagerImpl;
import org.eclipse.jpt.core.internal.prefs.JpaPreferenceInitializer;
import org.eclipse.jpt.core.internal.resource.ResourceLocatorManager;
import org.eclipse.jpt.core.platform.GenericPlatform;
import org.eclipse.jpt.core.platform.JpaPlatformDescription;
import org.eclipse.jpt.core.platform.JpaPlatformManager;
import org.eclipse.jpt.core.resource.ResourceLocator;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.osgi.framework.BundleContext;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
import org.osgi.util.tracker.ServiceTracker;

/**
 * The Dali core plug-in lifecycle implementation.
 * A number of globally-available constants and methods.
 * <p>
 * Provisional API: This class is part of an interim API that is still
 * under development and expected to change significantly before reaching
 * stability. It is available at this early stage to solicit feedback from
 * pioneering adopters on the understanding that any code that uses this API
 * will almost certainly be broken (repeatedly) as the API evolves.
 * 
 * @version 3.0
 * @since 2.0
 */
public class JptCorePlugin extends Plugin {

	private volatile GenericJpaProjectManager jpaProjectManager;
	private volatile ServiceTracker parserTracker;
	private static volatile boolean flushPreferences = true;


	// ********** public constants **********

	/**
	 * The plug-in identifier of the persistence support
	 * (value <code>"org.eclipse.jpt.core"</code>).
	 */
	public static final String PLUGIN_ID = "org.eclipse.jpt.core";  //$NON-NLS-1$
	public static final String PLUGIN_ID_ = PLUGIN_ID + '.';

	/**
	 * The key for storing a JPA project's platform ID in the Eclipse
	 * project's preferences.
	 */
	private static final String JPA_PLATFORM_PREF_KEY = PLUGIN_ID_ + "platform";  //$NON-NLS-1$

	/**
	 * The old key for storing the default JPA platform ID in the workspace preferences.
	 * @deprecated  As of version 2.3.  Instead use {@link #DEFAULT_JPA_PLATFORM_1_0_PREF_KEY} or 
	 * 		{@link #DEFAULT_JPA_PLATFORM_2_0_PREF_KEY}
	 */
	@Deprecated
	public static final String DEFAULT_JPA_PLATFORM_PREF_KEY = "defaultJpaPlatform"; //$NON-NLS-1$
	
	/**
	 * The key for storing the default JPA platform ID for JPA 1.0 in the workspace preferences.
	 */
	public static final String DEFAULT_JPA_PLATFORM_1_0_PREF_KEY = 
			DEFAULT_JPA_PLATFORM_PREF_KEY + "_" + JpaFacet.VERSION_1_0.getVersionString(); //$NON-NLS-1$
	
	/**
	 * The key for storing the default JPA platform ID for JPA 2.0 in the workspace preferences.
	 */
	public static final String DEFAULT_JPA_PLATFORM_2_0_PREF_KEY = 
			DEFAULT_JPA_PLATFORM_PREF_KEY + "_" + JpaFacet.VERSION_2_0.getVersionString(); //$NON-NLS-1$
	
	/**
	 * The key for storing a JPA project's "discover" flag in the Eclipse
	 * project's preferences.
	 */
	public static final String DISCOVER_ANNOTATED_CLASSES = PLUGIN_ID_ + "discoverAnnotatedClasses";  //$NON-NLS-1$

	/**
	 * The key for storing the name of a JPA project's metamodel source folder
	 * in the Eclipse project's preferences.
	 */
	public static final String METAMODEL_SOURCE_FOLDER_NAME = PLUGIN_ID_ + "metamodelSourceFolderName";  //$NON-NLS-1$

	/**
	 * The key for storing a JPA project's data source connection profile name
	 * in the Eclipse project's persistent properties.
	 */
	public static final QualifiedName DATA_SOURCE_CONNECTION_PROFILE_NAME = 
			new QualifiedName(PLUGIN_ID, "dataSource.connectionProfileName");  //$NON-NLS-1$

	/**
	 * The key for storing a JPA project's user overridden default catalog name
	 * in the Eclipse project's persistent properties.
	 */
	public static final QualifiedName USER_OVERRIDE_DEFAULT_CATALOG = 
		new QualifiedName(PLUGIN_ID, "userOverrideDefaultCatalogName");  //$NON-NLS-1$

	/**
	 * The key for storing a JPA project's user overridden default schema name
	 * in the Eclipse project's persistent properties.
	 */
	public static final QualifiedName USER_OVERRIDE_DEFAULT_SCHEMA = 
			new QualifiedName(PLUGIN_ID, "userOverrideDefaultSchemaName");  //$NON-NLS-1$


	/**
	 * The identifier for the JPA validation marker
	 * (value <code>"org.eclipse.jpt.core.jpaProblemMarker"</code>).
	 */
	public static final String VALIDATION_MARKER_ID = PLUGIN_ID + ".jpaProblemMarker";  //$NON-NLS-1$

	/**
	 * The identifier for the JPA validator
	 * (value <code>"org.eclipse.jpt.core.jpaValidator"</code>).
	 */
	public static final String VALIDATOR_ID = PLUGIN_ID_ + "jpaValidator";  //$NON-NLS-1$

	/**
	 * The content type for Java source code files.
	 */
	public static final IContentType JAVA_SOURCE_CONTENT_TYPE = getContentType(JavaCore.JAVA_SOURCE_CONTENT_TYPE);
	
	/**
	 * The resource type for Java source code files
	 */
	public static final JpaResourceType JAVA_SOURCE_RESOURCE_TYPE = new JpaResourceType(JAVA_SOURCE_CONTENT_TYPE);
	
	/**
	 * The content type for <code>persistence.xml</code> files.
	 */
	public static final IContentType PERSISTENCE_XML_CONTENT_TYPE = getJpaContentType("persistence"); //$NON-NLS-1$
	
	/**
	 * The resource type for <code>persistence.xml</code> version 1.0 files
	 */
	public static final JpaResourceType PERSISTENCE_XML_1_0_RESOURCE_TYPE = 
			new JpaResourceType(PERSISTENCE_XML_CONTENT_TYPE, org.eclipse.jpt.core.resource.persistence.JPA.SCHEMA_VERSION);
	
	/**
	 * The resource type for <code>persistence.xml</code> version 2.0 files
	 */
	public static final JpaResourceType PERSISTENCE_XML_2_0_RESOURCE_TYPE = 
			new JpaResourceType(PERSISTENCE_XML_CONTENT_TYPE, org.eclipse.jpt.core.resource.persistence.v2_0.JPA2_0.SCHEMA_VERSION);
	
	/**
	 * The base content type for all mapping files.
	 */
	public static final IContentType MAPPING_FILE_CONTENT_TYPE = getJpaContentType("mappingFile"); //$NON-NLS-1$

	/**
	 * The content type for <code>orm.xml</code> mapping files.
	 */
	public static final IContentType ORM_XML_CONTENT_TYPE = getJpaContentType("orm"); //$NON-NLS-1$
	
	/**
	 * The resource type for <code>orm.xml</code> version 1.0 mapping files
	 */
	public static final JpaResourceType ORM_XML_1_0_RESOURCE_TYPE = 
			new JpaResourceType(ORM_XML_CONTENT_TYPE, org.eclipse.jpt.core.resource.orm.JPA.SCHEMA_VERSION);
	
	/**
	 * The resource type for <code>orm.xml</code> version 2.0 mapping files
	 */
	public static final JpaResourceType ORM_XML_2_0_RESOURCE_TYPE = 
			new JpaResourceType(ORM_XML_CONTENT_TYPE, org.eclipse.jpt.core.resource.orm.v2_0.JPA2_0.SCHEMA_VERSION);
	
	/**
	 * The content type for Java archives (JARs).
	 */
	public static final IContentType JAR_CONTENT_TYPE = getJpaContentType("jar"); //$NON-NLS-1$
	
	/**
	 * The resource type for Java archives (JARs).
	 */
	public static final JpaResourceType JAR_RESOURCE_TYPE = new JpaResourceType(JAR_CONTENT_TYPE);
	
	/**
	 * Web projects have some special exceptions.
	 */
	public static final String WEB_PROJECT_FACET_ID = IModuleConstants.JST_WEB_MODULE;

	public static final IPath DEFAULT_PERSISTENCE_XML_RUNTIME_PATH = new Path("META-INF/persistence.xml"); //$NON-NLS-1$

	public static final IPath DEFAULT_ORM_XML_RUNTIME_PATH = new Path("META-INF/orm.xml"); //$NON-NLS-1$
	
	private static IContentType getJpaContentType(String jpaContentType) {
		return getContentType(CONTENT_PREFIX_ + jpaContentType);
	}
	
	public static final String CONTENT_PREFIX = PLUGIN_ID_ + "content"; //$NON-NLS-1$
	
	public static final String CONTENT_PREFIX_ = CONTENT_PREFIX + '.';
	
	private static IContentType getContentType(String contentType) {
		return Platform.getContentTypeManager().getContentType(contentType);
	}
	
	
	// ********** singleton **********

	private static JptCorePlugin INSTANCE;

	/**
	 * Return the singleton Dali core plug-in.
	 */
	public static JptCorePlugin instance() {
		return INSTANCE;
	}


	// ********** public static methods **********

	/**
	 * Return the singular JPA project manager corresponding
	 * to the current workspace.
	 */
	public static JpaProjectManager getJpaProjectManager() {
		return INSTANCE.getJpaProjectManager_();
	}

	/**
	 * Return the JPA project corresponding to the specified Eclipse project,
	 * or <code>null</code> if unable to associate the specified project with a
	 * JPA project.
	 */
	public static JpaProject getJpaProject(IProject project) {
		return getJpaProjectManager().getJpaProject(project);
	}

	/**
	 * Return the JPA file corresponding to the specified Eclipse file,
	 * or <code>null</code> if unable to associate the specified file with a JPA file.
	 */
	public static JpaFile getJpaFile(IFile file) {
		return getJpaProjectManager().getJpaFile(file);
	}

	/**
	 * The JPA settings associated with the specified Eclipse project
	 * have changed in such a way as to require the associated
	 * JPA project to be completely rebuilt
	 * (e.g. when the user changes a project's JPA platform).
	 */
	public static void rebuildJpaProject(IProject project) {
		getJpaProjectManager().rebuildJpaProject(project);
	}

	/**
	 * Return whether the specified Eclipse project has a Web facet.
	 */
	public static boolean projectHasWebFacet(IProject project) {
		return projectHasFacet(project, WEB_PROJECT_FACET_ID);
	}

	/**
	 * Checked exceptions bite.
	 */
	private static boolean projectHasFacet(IProject project, String facetId) {
		try {
			return FacetedProjectFramework.hasProjectFacet(project, facetId);
		} catch (CoreException ex) {
			log(ex);  // problems reading the project metadata - assume facet doesn't exist - return 'false'
			return false;
		}
	}
	
	public static ResourceLocator getResourceLocator(IProject project) {
		return ResourceLocatorManager.instance().getResourceLocator(project);
	}
	
	public static IFile getPlatformFile(IProject project, IPath runtimePath) {
		ResourceLocator resourceLocator = getResourceLocator(project);
		if (resourceLocator == null) {
			return null;
		}
		IPath sourcePath = resourceLocator.getResourcePath(project, runtimePath);
		if (sourcePath == null) {
			return null;
		}
		return project.getWorkspace().getRoot().getFile(sourcePath);
	}
	
	public static JpaFile getJpaFile(IProject project, IPath runtimePath) {
		IFile xmlFile = getPlatformFile(project, runtimePath);
		return xmlFile.exists() ? getJpaFile(xmlFile) : null;
	}
	
	/**
	 * Return the runtime path to which JARs are relatively specified for 
	 * the given project.
	 * (Web projects have a different runtime structure than non-web projects.)
	 */
	public static IPath getJarRuntimeRootPath(IProject project) {
		return projectHasWebFacet(project) ? 
				new Path("/" + J2EEConstants.WEB_INF)  //$NON-NLS-1$
				: new Path("/");  //$NON-NLS-1$
	}
	
	public static void initializeDefaultPreferences() {
		IEclipsePreferences node = getDefaultPreferences();

		// default JPA platforms
		JpaPlatformDescription defaultPlatform_1_0 = 
				JpaPlatformManagerImpl.instance().getDefaultJpaPlatform(JpaFacet.VERSION_1_0);
		if (defaultPlatform_1_0 == null) {
			defaultPlatform_1_0 = GenericPlatform.VERSION_1_0;
		}
		node.put(DEFAULT_JPA_PLATFORM_1_0_PREF_KEY, defaultPlatform_1_0.getId());
		
		JpaPlatformDescription defaultPlatform_2_0 = 
				JpaPlatformManagerImpl.instance().getDefaultJpaPlatform(JpaFacet.VERSION_2_0);
		if (defaultPlatform_2_0 == null) {
			defaultPlatform_2_0 = GenericPlatform.VERSION_2_0;
		}
		node.put(DEFAULT_JPA_PLATFORM_2_0_PREF_KEY, defaultPlatform_2_0.getId());
	}
	
	/**
	 * Return the default Dali preferences
	 * @see JpaPreferenceInitializer
	 */
	public static IEclipsePreferences getDefaultPreferences() {
		return getPreferences(new DefaultScope());
	}

	/**
	 * Return the Dali preferences for the current workspace instance.
	 */
	public static IEclipsePreferences getWorkspacePreferences() {
		return getPreferences(new InstanceScope());
	}

	/**
	 * Return the Dali preferences for the specified Eclipse project.
	 */
	public static IEclipsePreferences getProjectPreferences(IProject project) {
		return getPreferences(new ProjectScope(project));
	}

	/**
	 * Return the Dali preferences for the specified context.
	 */
	private static IEclipsePreferences getPreferences(IScopeContext context) {
		return context.getNode(PLUGIN_ID);
	}
	
	/**
	 * Return the default {@link JpaPlatformDescription} for new JPA projects with the given JPA facet version.
	 */
	public static JpaPlatformDescription getDefaultJpaPlatform(IProjectFacetVersion jpaFacetVersion) {
		JpaPlatformDescription defaultPlatform = 
				getDefaultJpaPlatform(jpaFacetVersion, getWorkspacePreferences(), getDefaultPreferences());
		if (defaultPlatform == null) {
			// if the platform ID stored in the workspace prefs is invalid (i.e. null), look in the default prefs
			defaultPlatform = getDefaultJpaPlatform(jpaFacetVersion, getDefaultPreferences());
		}
		return defaultPlatform;
	}
	
	private static JpaPlatformDescription getDefaultJpaPlatform(IProjectFacetVersion jpaFacetVersion, Preferences ... nodes) {
		JpaPlatformDescription defaultDefaultPlatform = 
				getDefaultJpaPlatform(jpaFacetVersion, DEFAULT_JPA_PLATFORM_PREF_KEY, null, nodes);
		String preferenceKey = null;
		if (jpaFacetVersion.equals(JpaFacet.VERSION_1_0)) {
			if (defaultDefaultPlatform == null) {
				defaultDefaultPlatform = GenericPlatform.VERSION_1_0;
			}
			preferenceKey = DEFAULT_JPA_PLATFORM_1_0_PREF_KEY; 
		}
		else if (jpaFacetVersion.equals(JpaFacet.VERSION_2_0)) {
			if (defaultDefaultPlatform == null) {
				defaultDefaultPlatform = GenericPlatform.VERSION_2_0;
			}
			preferenceKey = DEFAULT_JPA_PLATFORM_2_0_PREF_KEY;
		}
		else {
			throw new IllegalArgumentException("Illegal JPA facet version: " + jpaFacetVersion); //$NON-NLS-1$
		}
		return getDefaultJpaPlatform(jpaFacetVersion, preferenceKey, defaultDefaultPlatform, nodes);
	}
	
	private static JpaPlatformDescription getDefaultJpaPlatform(
			IProjectFacetVersion jpaFacetVersion, String preferenceKey, JpaPlatformDescription defaultDefault, Preferences ... nodes) {	
		
		String defaultDefaultId = (defaultDefault == null) ? null : defaultDefault.getId();
		String defaultPlatformId = Platform.getPreferencesService().get(preferenceKey, defaultDefaultId, nodes);
		JpaPlatformDescription defaultPlatform = getJpaPlatformManager().getJpaPlatform(defaultPlatformId);
		if (defaultPlatform != null && defaultPlatform.supportsJpaFacetVersion(jpaFacetVersion)) {
			return defaultPlatform;
		}
		else if (defaultDefault != null && defaultDefault.supportsJpaFacetVersion(jpaFacetVersion)) {
			return defaultDefault;
		}
		return null;
	}
	
	public static JpaPlatformManager getJpaPlatformManager() {
		return JpaPlatformManagerImpl.instance();
	}

	/**
	 * Set the default JPA platform ID for creating new JPA projects
	 */
	public static void setDefaultJpaPlatformId(String jpaFacetVersion, String platformId) {
		IEclipsePreferences prefs = getWorkspacePreferences();
		String preferenceKey = null;
		if (JpaFacet.VERSION_1_0.getVersionString().equals(jpaFacetVersion)) {
			preferenceKey = DEFAULT_JPA_PLATFORM_1_0_PREF_KEY;
		}
		else if (JpaFacet.VERSION_2_0.getVersionString().equals(jpaFacetVersion)) {
			preferenceKey = DEFAULT_JPA_PLATFORM_2_0_PREF_KEY;
		}
		else {
			throw new IllegalArgumentException("Illegal JPA facet version: " + jpaFacetVersion); //$NON-NLS-1$
		}
		prefs.put(preferenceKey, platformId);
		flush(prefs);
	}
	
	/**
	 * Return the JPA platform ID associated with the specified Eclipse project.
	 */
	public static String getJpaPlatformId(IProject project) {
		return getProjectPreferences(project).get(JPA_PLATFORM_PREF_KEY, GenericPlatform.VERSION_1_0.getId());
	}

	/**
	 * Set the JPA platform ID associated with the specified Eclipse project.
	 */
	public static void setJpaPlatformId(IProject project, String jpaPlatformId) {
		IEclipsePreferences prefs = getProjectPreferences(project);
		prefs.put(JPA_PLATFORM_PREF_KEY, jpaPlatformId);
		flush(prefs);
	}

	/**
	 * Return the preferences key used to look up an Eclipse project's
	 * JPA platform ID.
	 */
	public static String getJpaPlatformIdPrefKey() {
		return JPA_PLATFORM_PREF_KEY;
	}

	/**
	 * Return the JPA "discover" flag associated with the specified
	 * Eclipse project.
	 */
	public static boolean discoverAnnotatedClasses(IProject project) {
		return getProjectPreferences(project).getBoolean(DISCOVER_ANNOTATED_CLASSES, false);
	}

	/**
	 * Set the JPA "discover" flag associated with the specified
	 * Eclipse project.
	 */
	public static void setDiscoverAnnotatedClasses(IProject project, boolean discoverAnnotatedClasses) {
		IEclipsePreferences prefs = getProjectPreferences(project);
		prefs.putBoolean(DISCOVER_ANNOTATED_CLASSES, discoverAnnotatedClasses);
		flush(prefs);
	}

	/**
	 * Return the name of the metamodel source folder associated with the
	 * specified Eclipse project.
	 */
	public static String getMetamodelSourceFolderName(IProject project) {
		return getProjectPreferences(project).get(METAMODEL_SOURCE_FOLDER_NAME, null);
	}

	/**
	 * Set the name of the metamodel source folder associated with the
	 * specified Eclipse project.
	 */
	public static void setMetamodelSourceFolderName(IProject project, String metamodelSourceFolderName) {
		IEclipsePreferences prefs = getProjectPreferences(project);
		if (metamodelSourceFolderName == null) {
			prefs.remove(METAMODEL_SOURCE_FOLDER_NAME);
		}
		else {
			prefs.put(METAMODEL_SOURCE_FOLDER_NAME, metamodelSourceFolderName);
		}
		flush(prefs);
	}

	/**
	 * This method is called (via reflection) when the test plug-in is loaded.
	 * The prefs end up getting flushed after the test case has deleted the
	 * project, resulting resource exceptions in the log, e.g.
	 *     Resource '/JpaProjectManagerTests' is not open.
	 * @see JptCoreTestsPlugin#start(BundleContext)
	 */
	@SuppressWarnings("unused")
	private static void doNotFlushPreferences() {
		flushPreferences = false;
	}

	/**
	 * Flush preferences in an asynchronous Job because the flush request will
	 * trigger a lock on the project, which can cause us some deadlocks (e.g.
	 * when deleting the metamodel source folder).
	 */
	private static void flush(IEclipsePreferences prefs) {
		if (flushPreferences) {
			new PreferencesFlushJob(prefs).schedule();
		}
	}

	private static class PreferencesFlushJob extends Job {
		private final IEclipsePreferences prefs;
		PreferencesFlushJob(IEclipsePreferences prefs) {
			super(NLS.bind(JptCoreMessages.PREFERENCES_FLUSH_JOB_NAME, prefs.absolutePath()));
			this.prefs = prefs;
		}
		@Override
		protected IStatus run(IProgressMonitor monitor) {
			try {
				prefs.flush();
			} catch(BackingStoreException ex) {
				log(ex);
			}
			return Status.OK_STATUS;
		}
	}

	/**
	 * Return the name of the connection profile associated with the specified
	 * Eclipse project.
	 */
	public static String getConnectionProfileName(IProject project) {
		try {
			String connectionProfileName = project.getPersistentProperty(DATA_SOURCE_CONNECTION_PROFILE_NAME);
			// some old connection profile names were stored as empty strings instead of nulls :-(
			// convert them here
			return (StringTools.stringIsEmpty(connectionProfileName)) ? null : connectionProfileName;
		} catch (CoreException ex) {
			log(ex);
			return null;
		}
	}

	/**
	 * Set the name of the connection profile associated with the specified
	 * Eclipse project.
	 */
	public static void setConnectionProfileName(IProject project, String connectionProfileName) {
		try {
			project.setPersistentProperty(DATA_SOURCE_CONNECTION_PROFILE_NAME, connectionProfileName);
		} catch (CoreException ex) {
			log(ex);
		}
	}

	/**
	 * Return the default catalog (identifier) associated with the specified Eclipse project.
	 * @see JpaProject#getUserOverrideDefaultCatalog()
	 */
	public static String getUserOverrideDefaultCatalog(IProject project) {
		try {
			return project.getPersistentProperty(USER_OVERRIDE_DEFAULT_CATALOG);
		} catch (CoreException ex) {
			log(ex);
			return null;
		}
	}

	/**
	 * Set the default catalog (identifier) associated with the specified Eclipse project.
	 * @see JpaProject#setUserOverrideDefaultCatalog(String)
	 */
	public static void setUserOverrideDefaultCatalog(IProject project, String defaultCatalog) {
		try {
			project.setPersistentProperty(USER_OVERRIDE_DEFAULT_CATALOG, defaultCatalog);
		} catch (CoreException ex) {
			log(ex);
		}
	}

	/**
	 * Return the default schema (identifier) associated with the specified Eclipse project.
	 * @see JpaProject#getUserOverrideDefaultSchema()
	 */
	public static String getUserOverrideDefaultSchema(IProject project) {
		try {
			return project.getPersistentProperty(USER_OVERRIDE_DEFAULT_SCHEMA);
		} catch (CoreException ex) {
			log(ex);
			return null;
		}
	}

	/**
	 * Set the default schema (identifier) associated with the specified Eclipse project.
	 * @see JpaProject#setUserOverrideDefaultSchema(String)
	 */
	public static void setUserOverrideDefaultSchema(IProject project, String defaultSchema) {
		try {
			project.setPersistentProperty(USER_OVERRIDE_DEFAULT_SCHEMA, defaultSchema);
		} catch (CoreException ex) {
			log(ex);
		}
	}

	public static boolean nodeIsJpa2_0Compatible(JpaNode jpaNode) {
		return jpaNode.getJpaProject().getJpaPlatform().getJpaVersion().isCompatibleWithJpaVersion(JpaFacet.VERSION_2_0.getVersionString());
	}

	/**
	 * Return whether the JPA project manager's Java change listener is active.
	 */
	public static boolean javaElementChangeListenerIsActive() {
		return getJpaProjectManager().javaElementChangeListenerIsActive();
	}

	/**
	 * Set whether the JPA project manager's Java change listener is active.
	 */
	public static void setJavaElementChangeListenerIsActive(boolean javaElementChangeListenerIsActive) {
		getJpaProjectManager().setJavaElementChangeListenerIsActive(javaElementChangeListenerIsActive);
	}

	/**
	 * Log the specified status.
	 */
	public static void log(IStatus status) {
        INSTANCE.getLog().log(status);
    }

	/**
	 * Log the specified message.
	 */
	public static void log(String msg) {
        log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, msg, null));
    }

	/**
	 * Log the specified exception or error.
	 */
	public static void log(Throwable throwable) {
		log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, throwable.getLocalizedMessage(), throwable));
	}


	// ********** plug-in implementation **********

	public JptCorePlugin() {
		super();
		if (INSTANCE != null) {
			throw new IllegalStateException();
		}
		// this convention is *wack*...  ~bjv
		INSTANCE = this;
	}


	@Override
	public void start(BundleContext context) throws Exception {
		super.start(context);
		// nothing yet...
	}

	@Override
	public void stop(BundleContext context) throws Exception {
		try {
			if (this.jpaProjectManager != null) {
				this.jpaProjectManager.stop();
				this.jpaProjectManager = null;
			}
			if (this.parserTracker != null) {
				this.parserTracker.close();
				this.parserTracker = null;
			}
		} finally {
			super.stop(context);
		}
	}

	private synchronized GenericJpaProjectManager getJpaProjectManager_() {
		if (this.jpaProjectManager == null) {
			this.jpaProjectManager = this.buildJpaProjectManager();
			this.jpaProjectManager.start();
		}
		return this.jpaProjectManager;
	}

	private GenericJpaProjectManager buildJpaProjectManager() {
		return new GenericJpaProjectManager();
	}

	public synchronized SAXParserFactory getSAXParserFactory() {
		SAXParserFactory factory = (SAXParserFactory) this.getParserTracker().getService();
		if (factory != null) {
			factory.setNamespaceAware(true);
		}
		return factory;
	}

	private ServiceTracker getParserTracker() {
		if (this.parserTracker == null) {
			this.parserTracker = this.buildParserTracker();
			this.parserTracker.open();
		}
		return this.parserTracker;
	}

	private ServiceTracker buildParserTracker() {
		return new ServiceTracker(this.getBundle().getBundleContext(), "javax.xml.parsers.SAXParserFactory", null); //$NON-NLS-1$
	}

}
