diff options
author | Brian Vosburgh | 2013-01-08 20:43:43 +0000 |
---|---|---|
committer | Brian Vosburgh | 2013-01-08 21:55:27 +0000 |
commit | f9c748b3a2274490f4f0a959cdf5d1c6ae44a0c2 (patch) | |
tree | 2f9e463cabc51b03d65a3cdb25ef654aa4aecfc0 | |
parent | 8c4d9c7cfac93981df5c901d5bf41aed7c2682ae (diff) | |
download | webtools.dali-f9c748b3a2274490f4f0a959cdf5d1c6ae44a0c2.tar.gz webtools.dali-f9c748b3a2274490f4f0a959cdf5d1c6ae44a0c2.tar.xz webtools.dali-f9c748b3a2274490f4f0a959cdf5d1c6ae44a0c2.zip |
[395211] fix shutdown deadlock etc.
70 files changed, 903 insertions, 694 deletions
diff --git a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/InternalJptWorkspace.java b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/InternalJptWorkspace.java index b1a3b6f446..621e6afc20 100644 --- a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/InternalJptWorkspace.java +++ b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/InternalJptWorkspace.java @@ -21,10 +21,9 @@ public class InternalJptWorkspace { private final IWorkspace workspace; - // NB: the Dali workspace must be synchronized whenever accessing any of this state - private InternalJptResourceTypeManager resourceTypeManager; - private InternalLibraryValidatorManager libraryValidatorManager; - private InternalResourceLocatorManager resourceLocatorManager; + private final InternalJptResourceTypeManager resourceTypeManager; + private final InternalLibraryValidatorManager libraryValidatorManager; + private final InternalResourceLocatorManager resourceLocatorManager; /** @@ -34,19 +33,15 @@ public class InternalJptWorkspace public InternalJptWorkspace(IWorkspace workspace) { super(); this.workspace = workspace; - } - - public IWorkspace getWorkspace() { - return this.workspace; + this.resourceTypeManager = this.buildResourceTypeManager(); + this.libraryValidatorManager = this.buildLibraryValidatorManager(); + this.resourceLocatorManager = this.buildResourceLocatorManager(); } // ********** Dali resource type manager ********** - public synchronized InternalJptResourceTypeManager getResourceTypeManager() { - if ((this.resourceTypeManager == null) && this.isActive()) { - this.resourceTypeManager = this.buildResourceTypeManager(); - } + public InternalJptResourceTypeManager getResourceTypeManager() { return this.resourceTypeManager; } @@ -57,10 +52,7 @@ public class InternalJptWorkspace // ********** Dali library validator manager ********** - public synchronized InternalLibraryValidatorManager getLibraryValidatorManager() { - if ((this.libraryValidatorManager == null) && this.isActive()) { - this.libraryValidatorManager = this.buildLibraryValidatorManager(); - } + public InternalLibraryValidatorManager getLibraryValidatorManager() { return this.libraryValidatorManager; } @@ -71,10 +63,7 @@ public class InternalJptWorkspace // ********** Dali resource locator manager ********** - public synchronized InternalResourceLocatorManager getResourceLocatorManager() { - if ((this.resourceLocatorManager == null) && this.isActive()) { - this.resourceLocatorManager = this.buildResourceLocatorManager(); - } + public InternalResourceLocatorManager getResourceLocatorManager() { return this.resourceLocatorManager; } @@ -85,18 +74,8 @@ public class InternalJptWorkspace // ********** misc ********** - private boolean isActive() { - return JptCommonCorePlugin.instance().isActive(); - } - - /** - * Internal: Called <em>only</em> by the - * {@link JptCommonCorePlugin#stop_() Dali plug-in}. - */ - public synchronized void stop() { - if (this.resourceTypeManager != null) { - this.resourceTypeManager = null; - } + public IWorkspace getWorkspace() { + return this.workspace; } @Override diff --git a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/libprov/JptOsgiBundlesLibraryProviderInstallOperationConfig.java b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/libprov/JptOsgiBundlesLibraryProviderInstallOperationConfig.java index 1af56c4c66..d4847e69d8 100644 --- a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/libprov/JptOsgiBundlesLibraryProviderInstallOperationConfig.java +++ b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/libprov/JptOsgiBundlesLibraryProviderInstallOperationConfig.java @@ -9,7 +9,8 @@ ******************************************************************************/ package org.eclipse.jpt.common.core.internal.libprov; -import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jpt.common.core.JptWorkspace; @@ -31,25 +32,36 @@ public abstract class JptOsgiBundlesLibraryProviderInstallOperationConfig @Override public synchronized IStatus validate() { IStatus status = super.validate(); - if (! status.isOK()) { + if ( ! status.isOK()) { return status; } - - for (LibraryValidator libraryValidator : this.getLibraryValidatorManager().getLibraryValidators(this)) { + LibraryValidatorManager lvManager = this.getLibraryValidatorManager(); + if (lvManager == null) { + return Status.OK_STATUS; + } + for (LibraryValidator libraryValidator : lvManager.getLibraryValidators(this)) { status = libraryValidator.validate(this); - if (! status.isOK()) { + if ( ! status.isOK()) { return status; } } - return Status.OK_STATUS; } private LibraryValidatorManager getLibraryValidatorManager() { - return this.getJptWorkspace().getLibraryValidatorManager(); + JptWorkspace jptWorkspace = this.getJptWorkspace(); + return (jptWorkspace == null) ? null : jptWorkspace.getLibraryValidatorManager(); } private JptWorkspace getJptWorkspace() { - return (JptWorkspace) ResourcesPlugin.getWorkspace().getAdapter(JptWorkspace.class); + return (JptWorkspace) this.getWorkspace().getAdapter(JptWorkspace.class); + } + + private IWorkspace getWorkspace() { + return this.getProject().getWorkspace(); + } + + private IProject getProject() { + return this.getFacetedProject().getProject(); } } diff --git a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/libprov/JptUserLibraryProviderInstallOperationConfig.java b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/libprov/JptUserLibraryProviderInstallOperationConfig.java index d2cb7c9ff5..a7c20a24c9 100644 --- a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/libprov/JptUserLibraryProviderInstallOperationConfig.java +++ b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/libprov/JptUserLibraryProviderInstallOperationConfig.java @@ -9,7 +9,8 @@ ******************************************************************************/ package org.eclipse.jpt.common.core.internal.libprov; -import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jpt.common.core.JptWorkspace; @@ -31,13 +32,16 @@ public abstract class JptUserLibraryProviderInstallOperationConfig @Override public synchronized IStatus validate() { IStatus status = super.validate(); - if (! status.isOK()) { + if ( ! status.isOK()) { return status; } - - for (LibraryValidator libraryValidator : this.getLibraryValidatorManager().getLibraryValidators(this)) { + LibraryValidatorManager lvManager = this.getLibraryValidatorManager(); + if (lvManager == null) { + return Status.OK_STATUS; + } + for (LibraryValidator libraryValidator : lvManager.getLibraryValidators(this)) { status = libraryValidator.validate(this); - if (! status.isOK()) { + if ( ! status.isOK()) { return status; } } @@ -46,10 +50,19 @@ public abstract class JptUserLibraryProviderInstallOperationConfig } private LibraryValidatorManager getLibraryValidatorManager() { - return this.getJptWorkspace().getLibraryValidatorManager(); + JptWorkspace jptWorkspace = this.getJptWorkspace(); + return (jptWorkspace == null) ? null : jptWorkspace.getLibraryValidatorManager(); } private JptWorkspace getJptWorkspace() { - return (JptWorkspace) ResourcesPlugin.getWorkspace().getAdapter(JptWorkspace.class); + return (JptWorkspace) this.getWorkspace().getAdapter(JptWorkspace.class); + } + + private IWorkspace getWorkspace() { + return this.getProject().getWorkspace(); + } + + private IProject getProject() { + return this.getFacetedProject().getProject(); } } diff --git a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/plugin/JptCommonCorePlugin.java b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/plugin/JptCommonCorePlugin.java index 60fef30fcf..41d2dee164 100644 --- a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/plugin/JptCommonCorePlugin.java +++ b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/plugin/JptCommonCorePlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2012 Oracle. All rights reserved. + * Copyright (c) 2011, 2013 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. @@ -9,16 +9,16 @@ ******************************************************************************/ package org.eclipse.jpt.common.core.internal.plugin; -import java.util.HashMap; +import java.util.Hashtable; import org.eclipse.core.resources.IWorkspace; import org.eclipse.jpt.common.core.internal.InternalJptWorkspace; import org.eclipse.jpt.common.core.internal.utility.JptPlugin; +import org.osgi.framework.BundleContext; public class JptCommonCorePlugin extends JptPlugin { - // NB: the plug-in must be synchronized whenever accessing any of this state - private final HashMap<IWorkspace, InternalJptWorkspace> jptWorkspaces = new HashMap<IWorkspace, InternalJptWorkspace>(); + private final Hashtable<IWorkspace, InternalJptWorkspace> jptWorkspaces = new Hashtable<IWorkspace, InternalJptWorkspace>(); // ********** singleton ********** @@ -45,18 +45,12 @@ public class JptCommonCorePlugin } @Override - protected void stop_() throws Exception { + public void stop(BundleContext context) throws Exception { try { - for (InternalJptWorkspace jptWorkspace : this.jptWorkspaces.values()) { - try { - jptWorkspace.stop(); - } catch (Throwable ex) { - this.logError(ex); // keep going - } - } + // force the workspaces to be rebuilt if the plug-in is restarted this.jptWorkspaces.clear(); } finally { - super.stop_(); + super.stop(context); } } @@ -69,13 +63,23 @@ public class JptCommonCorePlugin * The preferred way to retrieve a Dali workspace is via the Eclipse * adapter framework: * <pre> - * JptWorkspace jptWorkspace = (JptWorkspace) ResourcesPlugin.getWorkspace().getAdapter(JptWorkspace.class) + * IWorkspace workspace = ...; + * JptWorkspace jptWorkspace = (JptWorkspace) workspace.getAdapter(JptWorkspace.class) * </pre> * @see org.eclipse.jpt.common.core.internal.WorkspaceAdapterFactory#getJptWorkspace(IWorkspace) */ - public synchronized InternalJptWorkspace getJptWorkspace(IWorkspace workspace) { + public InternalJptWorkspace getJptWorkspace(IWorkspace workspace) { + synchronized (this.jptWorkspaces) { + return this.getJptWorkspace_(workspace); + } + } + + /** + * Pre-condition: {@link #jptWorkspaces} is <code>synchronized</code> + */ + private InternalJptWorkspace getJptWorkspace_(IWorkspace workspace) { InternalJptWorkspace jptWorkspace = this.jptWorkspaces.get(workspace); - if ((jptWorkspace == null) && this.isActive()) { + if ((jptWorkspace == null) && this.isActive()) { // no new workspaces can be built during "start" or "stop"... jptWorkspace = this.buildJptWorkspace(workspace); this.jptWorkspaces.put(workspace, jptWorkspace); } diff --git a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/resource/SimpleProjectResourceLocator.java b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/resource/SimpleProjectResourceLocator.java index b94690d4d6..3848f7f186 100644 --- a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/resource/SimpleProjectResourceLocator.java +++ b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/resource/SimpleProjectResourceLocator.java @@ -12,7 +12,7 @@ package org.eclipse.jpt.common.core.internal.resource; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.runtime.IPath; import org.eclipse.jpt.common.core.JptWorkspace; import org.eclipse.jpt.common.core.resource.ProjectResourceLocator; @@ -61,15 +61,21 @@ public class SimpleProjectResourceLocator } protected ResourceLocator getResourceLocator() { - return this.getResourceLocatorManager().getResourceLocator(this.project); + ResourceLocatorManager rlManager = this.getResourceLocatorManager(); + return (rlManager == null) ? null : rlManager.getResourceLocator(this.project); } private ResourceLocatorManager getResourceLocatorManager() { - return this.getJptWorkspace().getResourceLocatorManager(); + JptWorkspace jptWorkspace = this.getJptWorkspace(); + return (jptWorkspace == null) ? null : jptWorkspace.getResourceLocatorManager(); } private JptWorkspace getJptWorkspace() { - return (JptWorkspace) ResourcesPlugin.getWorkspace().getAdapter(JptWorkspace.class); + return (JptWorkspace) this.getWorkspace().getAdapter(JptWorkspace.class); + } + + private IWorkspace getWorkspace() { + return this.project.getWorkspace(); } @Override diff --git a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/resource/xml/AbstractJptXmlResourceProvider.java b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/resource/xml/AbstractJptXmlResourceProvider.java index ac9f709e79..6128e34bb3 100644 --- a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/resource/xml/AbstractJptXmlResourceProvider.java +++ b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/resource/xml/AbstractJptXmlResourceProvider.java @@ -16,7 +16,6 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; @@ -169,7 +168,7 @@ public abstract class AbstractJptXmlResourceProvider * @param config - A configuration object used to specify options for creation of the resource */ public JptXmlResource createFileAndResource(Object config, IProgressMonitor monitor) throws CoreException { - IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IWorkspace workspace = this.project.getWorkspace(); IWorkspaceRunnable runnable = new CreateFileAndResourceWorkspaceRunnable(config); workspace.run(runnable, this.project, IWorkspace.AVOID_UPDATE, monitor); return this.resource; @@ -217,7 +216,7 @@ public abstract class AbstractJptXmlResourceProvider } public IStatus validateEdit(Object context) { - IWorkspace work = ResourcesPlugin.getWorkspace(); + IWorkspace work = this.project.getWorkspace(); IFile file = WorkbenchResourceHelper.getFile(this.resource); if (file != null) { IFile[] files = { file }; diff --git a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/utility/JptPlugin.java b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/utility/JptPlugin.java index bd91916856..87dabb09da 100644 --- a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/utility/JptPlugin.java +++ b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/utility/JptPlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Oracle. All rights reserved. + * Copyright (c) 2012, 2013 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. @@ -33,6 +33,7 @@ import org.eclipse.jpt.common.core.internal.JptCommonCoreMessages; import org.eclipse.jpt.common.core.internal.plugin.JptCommonCorePlugin; import org.eclipse.jpt.common.utility.ExceptionHandler; import org.eclipse.jpt.common.utility.internal.ArrayTools; +import org.eclipse.jpt.common.utility.internal.ExceptionHandlerAdapter; import org.eclipse.jpt.common.utility.internal.ObjectTools; import org.eclipse.jpt.common.utility.internal.StringTools; import org.eclipse.osgi.service.debug.DebugOptions; @@ -41,6 +42,7 @@ import org.eclipse.osgi.util.NLS; import org.osgi.framework.Bundle; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleReference; import org.osgi.service.prefs.BackingStoreException; import org.osgi.util.tracker.ServiceTracker; @@ -69,8 +71,9 @@ import org.osgi.util.tracker.ServiceTracker; public abstract class JptPlugin implements BundleActivator { + private volatile BundleContext bundleContext; + // NB: the plug-in must be synchronized whenever accessing any of this state - private BundleContext bundleContext; private ExceptionHandler exceptionHandler; private ServiceTracker<DebugOptions, DebugOptions> debugOptionsTracker; private DebugTrace debugTrace; @@ -88,63 +91,36 @@ public abstract class JptPlugin // ********** plug-in lifecycle ********** /** - * @see #start_() - */ - public final synchronized void start(BundleContext context) throws Exception { - // make the instance available immediately; although nothing should - // retrieve it during start-up, as most state should be populated lazily... - this.setInstance(this); - // "activate" the plug-in - this.bundleContext = context; - this.start_(); - } - - /** - * Subclass should call <code>super.start_()</code> at the beginning + * Subclass should call <code>super.start(context)</code> at the beginning * of its override implementation. * <p> * <strong>NB:</strong> Most state should be built lazily.... */ - protected void start_() throws Exception { - // perform any startup stuff + public void start(BundleContext context) throws Exception { + this.bundleContext = context; + // make the instance available immediately; although nothing *should* + // retrieve it during start-up, as most state should be populated lazily... + this.setInstance(this); } /** - * @see #stop_() + * Set the plug-in's singleton instance. */ - public final synchronized void stop(BundleContext context) throws Exception { - try { - this.stop_(); - } finally { - // "deactivate" the plug-in - this.bundleContext = null; - // leave the instance available during shutdown so stuff can be - // logged, traced, etc. - this.setInstance(null); - } - } + protected abstract void setInstance(JptPlugin plugin); /** - * The plug-in will still be {@link #isActive() active} and its instance - * still present when this method is called. - * <p> - * Subclass should call <code>super.stop_()</code> at the end + * Subclass should call <code>super.stop(context)</code> at the end * of its override implementation. + * <p> + * <strong>NB:</strong> the plug-in should not return from this method + * until all its outstanding processes are finished. */ - protected void stop_() throws Exception { - if (this.debugOptionsTracker != null) { - this.debugOptionsTracker.close(); - this.debugOptionsTracker = null; - this.debugTrace = null; - } - this.exceptionHandler = null; + public void stop(BundleContext context) throws Exception { + // the service tracker must be rebuilt with a valid bundle context if the plug-in is restarted + this.closeDebugOptionsTracker(); + // seems like we can leave 'exceptionHandler' in place... } - /** - * Set the plug-in's singleton instance. - */ - protected abstract void setInstance(JptPlugin plugin); - // ********** content type ********** @@ -153,7 +129,7 @@ public abstract class JptPlugin * specified context type within the scope of the plug-in; i.e prefix the * specified content type with the * {@link #getContentTypeScope() plug-in's content type scope}. - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive}. + * Return <code>null</code> if the plug-in has no bundle. */ public IContentType getContentType(String contentType) { StringBuilder scope = this.getContentTypeScope(); @@ -166,7 +142,7 @@ public abstract class JptPlugin * By default, this is in the form * <em><plug-in ID>.content.</em> * (e.g. <code>"org.eclipse.jpt.common.core.content."</code>). - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive}. + * Return <code>null</code> if the plug-in has no bundle. */ protected StringBuilder getContentTypeScope() { String id = this.getPluginID(); @@ -197,7 +173,7 @@ public abstract class JptPlugin /** * Return the specified {@link IResource#getPersistentProperty(QualifiedName) * resource's persistent property}, relative to the plug-in's ID. - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive} + * Return <code>null</code> if the plug-in has no bundle * or if there are any problems retrieving the property. */ public String getPersistentProperty(IResource resource, String key) { @@ -246,7 +222,7 @@ public abstract class JptPlugin /** * Qualify the specified relative name with the plug-in's ID. - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive}. + * Return <code>null</code> if the plug-in has no bundle. */ protected QualifiedName buildPersistentPropertyQualifiedName(String relativeName) { String id = this.getPersistentPropertyPluginID(); @@ -614,7 +590,7 @@ public abstract class JptPlugin /** * Return the plug-in's workspace preferences. These preferences are written * to disk when the workspace is closed. - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive}. + * Return <code>null</code> if the plug-in has no bundle. * These preferences are stored the file<br> * <code> * <em><workspace dir></em>/<em><project dir></em>/.settings/<em><plug-in ID></em>.prefs @@ -627,7 +603,7 @@ public abstract class JptPlugin /** * Return the plug-in's workspace preferences. These preferences are written * to disk when the workspace is closed. - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive}. + * Return <code>null</code> if the plug-in has no bundle. * These preferences are stored the file<br> * <code> * <em><workspace dir></em>/.metadata/.plugins/org.eclipse.core.runtime/.settings/<em><plug-in ID></em>.prefs @@ -641,7 +617,7 @@ public abstract class JptPlugin * Return the plug-in's <em>current</em> default preferences. * These preferences are initialized * during default preferences initialization and are not saved to disk. - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive}. + * Return <code>null</code> if the plug-in has no bundle. * <p> * These preferences must use the <em>current</em> plug-in ID as the * extension is associated with the plug-in. @@ -676,7 +652,7 @@ public abstract class JptPlugin /** * Return the plug-in's preferences for the specified context. - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive}. + * Return <code>null</code> if the plug-in has no bundle. */ protected IEclipsePreferences getPreferences(IScopeContext context) { String qualifier = this.getPreferencesPluginID(); @@ -684,7 +660,7 @@ public abstract class JptPlugin } /** - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive}. + * Return <code>null</code> if the plug-in has no bundle. * @see #getOriginalPluginID_() */ protected String getPreferencesPluginID() { @@ -848,7 +824,7 @@ public abstract class JptPlugin /** * Log the specified message and exception with the specified severity * and code. - * If the plug-in is {@link #isInactive() inactive}, log the information + * If the plug-in has {@link #getBundle() bundle}, log the information * to the appropriate Java system log (instead of the Eclise platform log). * Return the logged status. * @see IStatus#getSeverity() @@ -861,7 +837,7 @@ public abstract class JptPlugin /** * Log the specified message and exception with the specified severity * and code. Bind the message to the specified arguments. - * If the plug-in is {@link #isInactive() inactive}, log the information + * If the plug-in has {@link #getBundle() bundle}, log the information * to the appropriate Java system log (instead of the Eclise platform log). * Return the logged status. * @see IStatus#getSeverity() @@ -889,7 +865,7 @@ public abstract class JptPlugin /** * Return the plug-in's log. - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive}. + * Return <code>null</code> if the plug-in has no bundle. * @see Platform#getLog(Bundle) */ public ILog getLog() { @@ -1158,7 +1134,7 @@ public abstract class JptPlugin * with the appropriate severity; by default, {@link IStatus#ERROR error}. */ public synchronized ExceptionHandler getExceptionHandler() { - if ((this.exceptionHandler == null) && this.isActive()) { + if (this.exceptionHandler == null) { this.exceptionHandler = this.buildExceptionHandler(); } return this.exceptionHandler; @@ -1168,7 +1144,7 @@ public abstract class JptPlugin * By default the plug-in's exception handler will log any exceptions * as {@link IStatus#ERROR errors}. */ - protected ExceptionHandler buildExceptionHandler() { + public ExceptionHandler buildExceptionHandler() { return this.buildExceptionHandler(IStatus.ERROR); } @@ -1177,6 +1153,7 @@ public abstract class JptPlugin * handler, as opposed to using the plug-in's exception handler. * @see #getExceptionHandler() * @see PluginExceptionHandler + * @see IStatus#getSeverity() */ public ExceptionHandler buildExceptionHandler(int severity) { return new PluginExceptionHandler(severity); @@ -1187,20 +1164,17 @@ public abstract class JptPlugin * severity. */ protected class PluginExceptionHandler - implements ExceptionHandler + extends ExceptionHandlerAdapter { private final int severity; protected PluginExceptionHandler(int severity) { super(); this.severity = severity; } + @Override public void handleException(Throwable t) { JptPlugin.this.log(this.severity, t); } - @Override - public String toString() { - return ObjectTools.toString(this); - } } @@ -1264,7 +1238,7 @@ public abstract class JptPlugin * By default, this is in the form * <em><plug-in ID>/debug</em> * (e.g. <code>org.eclipse.jpt.common.core/debug</code>). - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive}. + * Return <code>null</code> if the plug-in has no bundle. */ protected StringBuilder getDebugOptionName() { String id = this.getPluginID(); @@ -1488,15 +1462,37 @@ public abstract class JptPlugin } private synchronized ServiceTracker<DebugOptions, DebugOptions> getDebugOptionsTracker() { - if ((this.debugOptionsTracker == null) && this.isActive()) { + if (this.debugOptionsTracker == null) { this.debugOptionsTracker = this.buildDebugOptionsTracker(); - this.debugOptionsTracker.open(); } return this.debugOptionsTracker; } private ServiceTracker<DebugOptions, DebugOptions> buildDebugOptionsTracker() { - return new ServiceTracker<DebugOptions, DebugOptions>(this.bundleContext, DebugOptions.class, null); + try { + return this.buildDebugOptionsTracker_(); + } catch (RuntimeException ex) { + this.logError(ex); + return null; + } + } + + /** + * @exception RuntimeException if the plug-in's {@link #bundleContext + * bundle context} is missing or invalid + */ + private ServiceTracker<DebugOptions, DebugOptions> buildDebugOptionsTracker_() { + ServiceTracker<DebugOptions, DebugOptions> tracker = new ServiceTracker<DebugOptions, DebugOptions>(this.bundleContext, DebugOptions.class, null); + tracker.open(); + return tracker; + } + + protected synchronized void closeDebugOptionsTracker() { + if (this.debugOptionsTracker != null) { + this.debugOptionsTracker.close(); + this.debugOptionsTracker = null; + this.debugTrace = null; // the debug trace is associated with the tracker's service(?) + } } /** @@ -1505,7 +1501,7 @@ public abstract class JptPlugin * By default, this is in the form * <em><plug-in ID>/debug/</em> * (e.g. <code>org.eclipse.jpt.common.core/debug/</code>). - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive}. + * Return <code>null</code> if the plug-in has no bundle. */ protected StringBuilder getDebugOptionScope() { StringBuilder sb = this.getDebugOptionName(); @@ -1746,7 +1742,7 @@ public abstract class JptPlugin } protected synchronized DebugTrace getDebugTrace() { - if ((this.debugTrace == null) && this.isActive()) { + if (this.debugTrace == null) { this.debugTrace = this.buildDebugTrace(); } return this.debugTrace; @@ -1786,16 +1782,25 @@ public abstract class JptPlugin // ********** misc ********** /** - * Return the plug-in's bundle. Return <code>null</code> if the plug-in is - * {@link #isInactive() inactive}. + * Return the plug-in's bundle. */ - public synchronized Bundle getBundle() { - return (this.bundleContext == null) ? null : this.bundleContext.getBundle(); + public Bundle getBundle() { + return (this.bundleContext != null) ? this.bundleContext.getBundle() : this.getBundle_(); + } + + /** + * If the plug-in has not yet been {@link #start(BundleContext) started}, we + * can still get the bundle from the classloader.... + */ + private Bundle getBundle_() { + ClassLoader cl = this.getClass().getClassLoader(); + return (cl instanceof BundleReference) ? ((BundleReference) cl).getBundle() : null; } /** * Return the plug-in's ID (i.e. the symbolic name of the plug-in's bundle). - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive}. + * Return <code>null</code> if the plug-in has no bundle. + * @see Bundle#getSymbolicName() */ public String getPluginID() { Bundle bundle = this.getBundle(); @@ -1806,10 +1811,11 @@ public abstract class JptPlugin * Return the plug-in's "original" ID. This is useful for backward and * forward compatibility of resource persistent properties and preferences. * By default return the {@link #getPluginID() current plug-in ID}. - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive}. + * Return <code>null</code> if the plug-in has no bundle. */ - public String getOriginalPluginID() { - return this.isActive() ? this.getOriginalPluginID_() : null; + public final String getOriginalPluginID() { + Bundle bundle = this.getBundle(); + return (bundle == null) ? null : this.getOriginalPluginID_(); } /** @@ -1825,15 +1831,29 @@ public abstract class JptPlugin /** * Return whether the plug-in is active; i.e. it has been * {@link #start(BundleContext) started}. + * <p> + * <strong>NB:</strong> The plug-in is <em>not</em> active during the + * execution of the methods {@link #start(BundleContext)} or + * {@link #stop(BundleContext)}. + * + * @see Bundle#getState() + * @see Bundle#ACTIVE */ - public synchronized boolean isActive() { - return this.bundleContext != null; + public boolean isActive() { + return this.getBundle().getState() == Bundle.ACTIVE; } /** * Return whether the plug-in is inactive; i.e. it has been * {@link #stop(BundleContext) stopped} or not yet * {@link #start(BundleContext) started}. + * <p> + * <strong>NB:</strong> The plug-in is <em>not</em> active during the + * execution of the methods {@link #start(BundleContext)} or + * {@link #stop(BundleContext)}. + * + * @see Bundle#getState() + * @see Bundle#ACTIVE */ public boolean isInactive() { return ! this.isActive(); @@ -1841,7 +1861,7 @@ public abstract class JptPlugin /** * Qualify the specified relative name with the plug-in's ID. - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive}. + * Return <code>null</code> if the plug-in has no bundle. */ public QualifiedName buildQualifiedName(String relativeName) { String id = this.getPluginID(); @@ -1849,8 +1869,8 @@ public abstract class JptPlugin } /** - * Return <code>null</code> if the plug-in is {@link #isInactive() inactive} - * or if the system is running with no data area (<code>-data @none</code>). + * Return <code>null</code> if the plug-in has no corresponding bundle + * or if the platform is running with no data area (<code>-data @none</code>). * @see org.eclipse.core.runtime.Plugin#getStateLocation() * @see Platform#getStateLocation(Bundle) */ diff --git a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/utility/PlatformTools.java b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/utility/PlatformTools.java index dbe9ea76cc..7f31a2d03d 100644 --- a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/utility/PlatformTools.java +++ b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/utility/PlatformTools.java @@ -14,6 +14,7 @@ import java.io.InputStream; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; @@ -53,11 +54,10 @@ public class PlatformTools { * Return the {@link IContainer} with the workspace-relative "full" path */ public static IContainer getContainer(IPath fullContainerPath) { - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); // changed to handle non-workspace projects String projectName = fullContainerPath.segment(0).toString(); IPath projectRelativePath = fullContainerPath.removeFirstSegments(1); - IProject project = root.getProject(projectName); + IProject project = getWorkspaceRoot().getProject(projectName); return (projectRelativePath.isEmpty()) ? project : project.getFolder(projectRelativePath); } @@ -65,13 +65,20 @@ public class PlatformTools { * Return the {@link IFile} with the workspace relative "full" path */ public static IFile getFile(IPath fullFilePath) { - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); // changed to handle non-workspace projects String projectName = fullFilePath.segment(0).toString(); IPath projectRelativePath = fullFilePath.removeFirstSegments(1); - IProject project = root.getProject(projectName); + IProject project = getWorkspaceRoot().getProject(projectName); return project.getFile(projectRelativePath); } + + private static IWorkspaceRoot getWorkspaceRoot() { + return getWorkspace().getRoot(); + } + + private static IWorkspace getWorkspace() { + return ResourcesPlugin.getWorkspace(); + } // ********** resource type ********** @@ -87,7 +94,7 @@ public class PlatformTools { } private static JptWorkspace getJptWorkspace() { - return getAdapter(ResourcesPlugin.getWorkspace(), JptWorkspace.class); + return getAdapter(getWorkspace(), JptWorkspace.class); } diff --git a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/resource/java/JavaResourceClassFile.java b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/resource/java/JavaResourceClassFile.java index ebda076809..fdf6faf1f2 100644 --- a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/resource/java/JavaResourceClassFile.java +++ b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/resource/java/JavaResourceClassFile.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2011 Oracle. All rights reserved. + * Copyright (c) 2010, 2012 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. @@ -9,11 +9,13 @@ ******************************************************************************/ package org.eclipse.jpt.common.core.resource.java; - +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.content.IContentType; +import org.eclipse.jdt.core.JavaCore; /** * Java class file - * + * <p> * Provisional API: This interface 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 @@ -31,4 +33,18 @@ public interface JavaResourceClassFile */ JavaResourceAbstractType getType(); + + // ********** content types ********** + + /** + * The content type ID for Java class files. + * <p> + * [The JDT plug-in does not define a constant for this ID....] + */ + String CONTENT_TYPE_ID = JavaCore.PLUGIN_ID + ".javaClass"; //$NON-NLS-1$ + + /** + * The content type for Java class files. + */ + IContentType CONTENT_TYPE = Platform.getContentTypeManager().getContentType(CONTENT_TYPE_ID); } diff --git a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/resource/xml/JptXmlResource.java b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/resource/xml/JptXmlResource.java index 55c42d564b..ea3c64e154 100644 --- a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/resource/xml/JptXmlResource.java +++ b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/resource/xml/JptXmlResource.java @@ -218,7 +218,8 @@ public class JptXmlResource // ********** convenience methods ********** public boolean fileExists() { - return this.getFile().exists(); + IFile file = this.getFile(); + return (file != null) && file.exists(); } public IFile getFile() { @@ -236,8 +237,9 @@ public class JptXmlResource /** * Return the Eclipse file for the specified URI. - * This URI is assumed to be absolute in the following format: + * This URI is assumed to be absolute in the following format:<pre> * platform:/resource/.... + * </pre> */ protected IFile getFile(URI fileURI) { if ( ! WorkbenchResourceHelperBase.isPlatformResourceURI(fileURI)) { diff --git a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/gen/AbstractJptGenerateJob.java b/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/gen/AbstractJptGenerateJob.java index 698c7c6a23..4256de86b4 100644 --- a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/gen/AbstractJptGenerateJob.java +++ b/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/gen/AbstractJptGenerateJob.java @@ -12,7 +12,6 @@ package org.eclipse.jpt.common.ui.gen; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceRuleFactory; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -53,7 +52,7 @@ public abstract class AbstractJptGenerateJob extends WorkspaceJob { this.generationCompleted = new SynchronizedBoolean(false); this.generationSuccessful = false; - IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory(); + IResourceRuleFactory ruleFactory = this.javaProject.getProject().getWorkspace().getRuleFactory(); this.setRule(ruleFactory.modifyRule(this.javaProject.getProject())); } diff --git a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/JptUIPlugin.java b/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/JptUIPlugin.java index c686e1e902..9fff2ba878 100644 --- a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/JptUIPlugin.java +++ b/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/JptUIPlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Oracle. All rights reserved. + * Copyright (c) 2012, 2013 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. @@ -24,6 +24,7 @@ import org.eclipse.jpt.common.core.internal.utility.JptPlugin; import org.eclipse.jpt.common.utility.internal.StringTools; import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; /** * Common Dali UI plug-in behavior:<ul> @@ -52,20 +53,12 @@ public abstract class JptUIPlugin // ********** plug-in lifecycle ********** @Override - protected void start_() throws Exception { - super.start_(); - } - - @Override - protected void stop_() throws Exception { + public void stop(BundleContext context) throws Exception { try { - if (this.dialogSettings != null) { - this.saveDialogSettings(); - } + this.saveDialogSettings(); + // it seems like we can leave 'dialogSettings' and 'preferenceStore' in place... } finally { - this.preferenceStore = null; - this.dialogSettings = null; - super.stop_(); + super.stop(context); } } @@ -93,7 +86,7 @@ public abstract class JptUIPlugin * @see org.eclipse.ui.plugin.AbstractUIPlugin#getDialogSettings() */ public synchronized IDialogSettings getDialogSettings() { - if ((this.dialogSettings == null) && this.isActive()) { + if (this.dialogSettings == null) { this.dialogSettings = this.buildDialogSettings(); } return this.dialogSettings; @@ -136,7 +129,16 @@ public abstract class JptUIPlugin /** * @see org.eclipse.ui.plugin.AbstractUIPlugin#saveDialogSettings() */ - protected void saveDialogSettings() { + protected synchronized void saveDialogSettings() { + if (this.dialogSettings != null) { + this.saveDialogSettings_(); + } + } + + /** + * Pre-condition: the dialog settings are not <code>null</code> + */ + protected void saveDialogSettings_() { String settingsFileName = this.getDialogSettingsFileName(); if (settingsFileName != null) { try { @@ -152,7 +154,8 @@ public abstract class JptUIPlugin if (stateLocation == null) { return null; } - return stateLocation.append(this.getSimpleDialogSettingsFileName()).toOSString(); + IPath path = stateLocation.append(this.getSimpleDialogSettingsFileName()); + return path.toOSString(); } protected String getSimpleDialogSettingsFileName() { @@ -197,7 +200,7 @@ public abstract class JptUIPlugin * @see org.eclipse.ui.plugin.AbstractUIPlugin#getPreferenceStore() */ public synchronized IPreferenceStore getPreferenceStore() { - if ((this.preferenceStore == null) && this.isActive()) { + if (this.preferenceStore == null) { this.preferenceStore = this.buildPreferenceStore(); } return this.preferenceStore; diff --git a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/properties/JptProjectPropertiesPage.java b/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/properties/JptProjectPropertiesPage.java index ab3b73f168..8df0454bf1 100644 --- a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/properties/JptProjectPropertiesPage.java +++ b/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/properties/JptProjectPropertiesPage.java @@ -266,20 +266,24 @@ public abstract class JptProjectPropertiesPage } protected IRunnableWithProgress buildOkRunnableWithProgress() { - return new OkRunnableWithProgress(); + return new OkRunnableWithProgress(this.getProject().getWorkspace()); } protected class OkRunnableWithProgress implements IRunnableWithProgress { + protected final IWorkspace workspace; + protected OkRunnableWithProgress(IWorkspace workspace) { + super(); + this.workspace = workspace; + } public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - IWorkspace ws = ResourcesPlugin.getWorkspace(); try { // the build we execute in #performOk_() locks the workspace root, // so we need to use the workspace root as our scheduling rule here - ws.run( + this.workspace.run( new OkWorkspaceRunnable(), - ws.getRoot(), + this.workspace.getRoot(), IWorkspace.AVOID_UPDATE, monitor ); diff --git a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/wizards/JavaProjectWizardPage.java b/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/wizards/JavaProjectWizardPage.java index 33fa549351..ea35f8414f 100644 --- a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/wizards/JavaProjectWizardPage.java +++ b/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/wizards/JavaProjectWizardPage.java @@ -1,18 +1,16 @@ /******************************************************************************* -* Copyright (c) 2010, 2011 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 -*******************************************************************************/ + * Copyright (c) 2010, 2013 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.common.ui.internal.wizards; import java.util.Iterator; - import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; @@ -113,7 +111,7 @@ public class JavaProjectWizardPage extends WizardPage { String projectName = item.getText(0); if( ! StringTools.isBlank(projectName)) { - IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + IProject project = this.javaProject.getProject().getWorkspace().getRoot().getProject(projectName); this.setJavaProject(JavaCore.create(project)); this.validate(); } @@ -169,7 +167,7 @@ public class JavaProjectWizardPage extends WizardPage { return project.getName(); } }, - new String[0]); + StringTools.EMPTY_STRING_ARRAY); } protected Iterable<IProject> getJavaProjects() { @@ -187,7 +185,7 @@ public class JavaProjectWizardPage extends WizardPage { } protected Iterator<IProject> getProjects() { - return new ArrayIterator<IProject>(ResourcesPlugin.getWorkspace().getRoot().getProjects()); + return new ArrayIterator<IProject>(this.javaProject.getProject().getWorkspace().getRoot().getProjects()); } // ********** inner classes ********** diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/PrintStreamExceptionHandler.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/PrintStreamExceptionHandler.java index 175d731cd1..245da67730 100644 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/PrintStreamExceptionHandler.java +++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/PrintStreamExceptionHandler.java @@ -10,14 +10,13 @@ package org.eclipse.jpt.common.utility.internal; import java.io.PrintStream; -import org.eclipse.jpt.common.utility.ExceptionHandler; /** * An exception handler that prints the exceptions to the configured * {@link PrintStream}. */ public class PrintStreamExceptionHandler - implements ExceptionHandler + extends ExceptionHandlerAdapter { private final PrintStream printStream; @@ -33,12 +32,8 @@ public class PrintStreamExceptionHandler this.printStream = printStream; } + @Override public void handleException(Throwable t) { t.printStackTrace(this.printStream); } - - @Override - public String toString() { - return ObjectTools.toString(this); - } } diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/PrintWriterExceptionHandler.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/PrintWriterExceptionHandler.java index 48cf43116e..4b1e16dd5a 100644 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/PrintWriterExceptionHandler.java +++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/PrintWriterExceptionHandler.java @@ -10,14 +10,13 @@ package org.eclipse.jpt.common.utility.internal; import java.io.PrintWriter; -import org.eclipse.jpt.common.utility.ExceptionHandler; /** * An exception handler that prints the exceptions to the configured * {@link PrintWriter}. */ public class PrintWriterExceptionHandler - implements ExceptionHandler + extends ExceptionHandlerAdapter { private final PrintWriter printWriter; @@ -33,12 +32,8 @@ public class PrintWriterExceptionHandler this.printWriter = printWriter; } + @Override public void handleException(Throwable t) { t.printStackTrace(this.printWriter); } - - @Override - public String toString() { - return ObjectTools.toString(this); - } } diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/log/LoggingMultiThreadedExceptionHandler.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/log/LoggingMultiThreadedExceptionHandler.java index f195f3023c..84b8680e4e 100644 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/log/LoggingMultiThreadedExceptionHandler.java +++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/log/LoggingMultiThreadedExceptionHandler.java @@ -12,14 +12,13 @@ package org.eclipse.jpt.common.utility.internal.log; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; -import org.eclipse.jpt.common.utility.MultiThreadedExceptionHandler; -import org.eclipse.jpt.common.utility.internal.ObjectTools; +import org.eclipse.jpt.common.utility.internal.MultiThreadedExceptionHandlerAdapter; /** * This exception handler logs any exceptions to a JDK logger. */ public class LoggingMultiThreadedExceptionHandler - implements MultiThreadedExceptionHandler + extends MultiThreadedExceptionHandlerAdapter { private final Logger logger; private final Level level; @@ -67,6 +66,7 @@ public class LoggingMultiThreadedExceptionHandler } + @Override public void handleException(Throwable exception) { this.handleException(null, exception); } @@ -76,6 +76,7 @@ public class LoggingMultiThreadedExceptionHandler * does not pass through {@link Logger#doLog(LogRecord)} * like all the other <code>Logger#log(...)</code> methods. */ + @Override public void handleException(Thread thread, Throwable exception) { LogRecord logRecord = new LogRecord(this.level, this.message); logRecord.setParameters(new Object[] { (thread == null) ? "null" : thread.getName() }); //$NON-NLS-1$ @@ -84,9 +85,4 @@ public class LoggingMultiThreadedExceptionHandler logRecord.setResourceBundle(this.logger.getResourceBundle()); this.logger.log(logRecord); } - - @Override - public String toString() { - return ObjectTools.toString(this); - } } diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/CompositeExceptionHandlerTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/CompositeExceptionHandlerTests.java index ddb7a643a6..d55eae8108 100644 --- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/CompositeExceptionHandlerTests.java +++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/CompositeExceptionHandlerTests.java @@ -12,6 +12,7 @@ package org.eclipse.jpt.common.utility.tests.internal; import junit.framework.TestCase; import org.eclipse.jpt.common.utility.ExceptionHandler; import org.eclipse.jpt.common.utility.internal.CompositeExceptionHandler; +import org.eclipse.jpt.common.utility.internal.ExceptionHandlerAdapter; import org.eclipse.jpt.common.utility.internal.iterable.IterableTools; @SuppressWarnings("nls") @@ -117,9 +118,10 @@ public class CompositeExceptionHandlerTests public static class TestExceptionHandler - implements ExceptionHandler + extends ExceptionHandlerAdapter { public volatile Throwable throwable = null; + @Override public void handleException(Throwable t) { this.throwable = t; } diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/InternalJaxbProjectManager.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/InternalJaxbProjectManager.java index 8da837921e..023254830a 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/InternalJaxbProjectManager.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/InternalJaxbProjectManager.java @@ -36,6 +36,7 @@ import org.eclipse.jpt.common.core.utility.command.JobCommand; import org.eclipse.jpt.common.utility.ExceptionHandler; import org.eclipse.jpt.common.utility.command.Command; import org.eclipse.jpt.common.utility.command.StatefulCommandExecutor; +import org.eclipse.jpt.common.utility.internal.ExceptionHandlerAdapter; import org.eclipse.jpt.common.utility.internal.ObjectTools; import org.eclipse.jpt.common.utility.internal.command.AsynchronousExtendedCommandExecutor; import org.eclipse.jpt.common.utility.internal.command.SimpleStatefulExtendedCommandExecutor; @@ -161,15 +162,12 @@ public class InternalJaxbProjectManager ); /* CU private */ class LocalExceptionHandler - implements ExceptionHandler + extends ExceptionHandlerAdapter { + @Override public void handleException(Throwable t) { JptJaxbCorePlugin.instance().logError(t); } - @Override - public String toString() { - return ObjectTools.toString(this); - } } /** @@ -225,7 +223,7 @@ public class InternalJaxbProjectManager // ********** constructor ********** /** - * Internal: called by {@link JptJUaxbCorePlugin Dali plug-in}. + * Internal: called by {@link InternalJaxbWorkspace}. */ InternalJaxbProjectManager(JaxbWorkspace jaxbWorkspace) { super(); diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/InternalJaxbWorkspace.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/InternalJaxbWorkspace.java index b9abb16591..06e4119665 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/InternalJaxbWorkspace.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/InternalJaxbWorkspace.java @@ -13,47 +13,33 @@ import org.eclipse.core.resources.IWorkspace; import org.eclipse.jpt.common.utility.internal.ObjectTools; import org.eclipse.jpt.jaxb.core.JaxbWorkspace; import org.eclipse.jpt.jaxb.core.internal.platform.InternalJaxbPlatformManager; -import org.eclipse.jpt.jaxb.core.internal.plugin.JptJaxbCorePlugin; public class InternalJaxbWorkspace implements JaxbWorkspace { private final IWorkspace workspace; - // NB: the JAXB workspace must be synchronized whenever accessing any of this state - private InternalJaxbPlatformManager jaxbPlatformManager; - private InternalJaxbProjectManager jaxbProjectManager; + private final InternalJaxbPlatformManager jaxbPlatformManager; + private final InternalJaxbProjectManager jaxbProjectManager; /** * Internal: Called <em>only</em> by the - * {@link JptJaxbCorePlugin#buildJaxbWorkspace(IWorkspace) Dali JAXB plug-in}. + * {@link org.eclipse.jpt.jaxb.core.internal.plugin.JptJaxbCorePlugin#buildJaxbWorkspace(IWorkspace) + * Dali JAXB plug-in}. */ public InternalJaxbWorkspace(IWorkspace workspace) { super(); this.workspace = workspace; - } - - public IWorkspace getWorkspace() { - return this.workspace; - } - - /** - * Internal: Called <em>only</em> by the - * {@link JaxbPreferenceInitializer#initializeDefaultPreferences() - * JAXB preferences initializer}. - */ - void initializeDefaultPreferences() { - this.getJaxbPlatformManager().initializeDefaultPreferences(); + this.jaxbPlatformManager = this.buildJaxbPlatformManager(); + this.jaxbProjectManager = this.buildJaxbProjectManager(); + this.jaxbProjectManager.start(); } // ********** JAXB platform manager ********** - public synchronized InternalJaxbPlatformManager getJaxbPlatformManager() { - if ((this.jaxbPlatformManager == null) && this.isActive()) { - this.jaxbPlatformManager = this.buildJaxbPlatformManager(); - } + public InternalJaxbPlatformManager getJaxbPlatformManager() { return this.jaxbPlatformManager; } @@ -64,11 +50,7 @@ public class InternalJaxbWorkspace // ********** JAXB project manager ********** - public synchronized InternalJaxbProjectManager getJaxbProjectManager() { - if ((this.jaxbProjectManager == null) && this.isActive()) { - this.jaxbProjectManager = this.buildJaxbProjectManager(); - this.jaxbProjectManager.start(); - } + public InternalJaxbProjectManager getJaxbProjectManager() { return this.jaxbProjectManager; } @@ -79,22 +61,26 @@ public class InternalJaxbWorkspace // ********** misc ********** - private boolean isActive() { - return JptJaxbCorePlugin.instance().isActive(); + public IWorkspace getWorkspace() { + return this.workspace; + } + + /** + * Internal: Called <em>only</em> by the + * {@link JaxbPreferenceInitializer#initializeDefaultPreferences() + * JAXB preferences initializer}. + */ + void initializeDefaultPreferences() { + this.getJaxbPlatformManager().initializeDefaultPreferences(); } /** * Internal: Called <em>only</em> by the - * {@link JptJaxbCorePlugin#stop_() Dali plug-in}. + * {@link org.eclipse.jpt.jaxb.core.internal.plugin.JptJaxbCorePlugin#stop(org.osgi.framework.BundleContext) + * Dali JAXB plug-in}. */ - public synchronized void stop() { - if (this.jaxbPlatformManager != null) { - this.jaxbPlatformManager = null; - } - if (this.jaxbProjectManager != null) { - this.jaxbProjectManager.stop(); - this.jaxbProjectManager = null; - } + public void dispose() { + this.jaxbProjectManager.stop(); } @Override diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/libprov/JaxbJreLibraryProviderInstallOperationConfig.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/libprov/JaxbJreLibraryProviderInstallOperationConfig.java index f19aa786aa..0d0f8cf252 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/libprov/JaxbJreLibraryProviderInstallOperationConfig.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/libprov/JaxbJreLibraryProviderInstallOperationConfig.java @@ -9,7 +9,8 @@ ******************************************************************************/ package org.eclipse.jpt.jaxb.core.internal.libprov; -import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jpt.common.core.JptWorkspace; @@ -47,13 +48,16 @@ public class JaxbJreLibraryProviderInstallOperationConfig @Override public synchronized IStatus validate() { IStatus status = super.validate(); - if (! status.isOK()) { + if ( ! status.isOK()) { return status; } - - for (LibraryValidator libraryValidator : this.getLibraryValidatorManager().getLibraryValidators(this)) { + LibraryValidatorManager lvManager = this.getLibraryValidatorManager(); + if (lvManager == null) { + return Status.OK_STATUS; + } + for (LibraryValidator libraryValidator : lvManager.getLibraryValidators(this)) { status = libraryValidator.validate(this); - if (! status.isOK()) { + if ( ! status.isOK()) { return status; } } @@ -62,10 +66,19 @@ public class JaxbJreLibraryProviderInstallOperationConfig } private LibraryValidatorManager getLibraryValidatorManager() { - return this.getJptWorkspace().getLibraryValidatorManager(); + JptWorkspace jptWorkspace = this.getJptWorkspace(); + return (jptWorkspace == null) ? null : jptWorkspace.getLibraryValidatorManager(); } private JptWorkspace getJptWorkspace() { - return (JptWorkspace) ResourcesPlugin.getWorkspace().getAdapter(JptWorkspace.class); + return (JptWorkspace) this.getWorkspace().getAdapter(JptWorkspace.class); + } + + private IWorkspace getWorkspace() { + return this.getProject().getWorkspace(); + } + + private IProject getProject() { + return this.getFacetedProject().getProject(); } } diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/plugin/JptJaxbCorePlugin.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/plugin/JptJaxbCorePlugin.java index 6b2ab875da..94565a0c4e 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/plugin/JptJaxbCorePlugin.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/plugin/JptJaxbCorePlugin.java @@ -9,16 +9,16 @@ ******************************************************************************/ package org.eclipse.jpt.jaxb.core.internal.plugin; -import java.util.HashMap; +import java.util.Hashtable; import org.eclipse.core.resources.IWorkspace; import org.eclipse.jpt.common.core.internal.utility.JptPlugin; import org.eclipse.jpt.jaxb.core.internal.InternalJaxbWorkspace; +import org.osgi.framework.BundleContext; public class JptJaxbCorePlugin extends JptPlugin { - // NB: the plug-in must be synchronized whenever accessing any of this state - private final HashMap<IWorkspace, InternalJaxbWorkspace> jaxbWorkspaces = new HashMap<IWorkspace, InternalJaxbWorkspace>(); + private final Hashtable<IWorkspace, InternalJaxbWorkspace> jaxbWorkspaces = new Hashtable<IWorkspace, InternalJaxbWorkspace>(); // ********** singleton ********** @@ -45,18 +45,11 @@ public class JptJaxbCorePlugin } @Override - protected void stop_() throws Exception { + public void stop(BundleContext context) throws Exception { try { - for (InternalJaxbWorkspace jaxbWorkspace : this.jaxbWorkspaces.values()) { - try { - jaxbWorkspace.stop(); - } catch (Throwable ex) { - this.logError(ex); // keep going - } - } - this.jaxbWorkspaces.clear(); + this.disposeJaxbWorkspaces(); } finally { - super.stop_(); + super.stop(context); } } @@ -69,13 +62,23 @@ public class JptJaxbCorePlugin * The preferred way to retrieve a JAXB workspace is via the Eclipse * adapter framework: * <pre> - * JaxbWorkspace jaxbWorkspace = (JaxbWorkspace) ResourcesPlugin.getWorkspace().getAdapter(JaxbWorkspace.class) + * IWorkspace workspace = ...; + * JaxbWorkspace jaxbWorkspace = (JaxbWorkspace) workspace.getAdapter(JaxbWorkspace.class) * </pre> * @see org.eclipse.jpt.jaxb.core.internal.WorkspaceAdapterFactory#getJaxbWorkspace(IWorkspace) */ - public synchronized InternalJaxbWorkspace getJaxbWorkspace(IWorkspace workspace) { + public InternalJaxbWorkspace getJaxbWorkspace(IWorkspace workspace) { + synchronized (this.jaxbWorkspaces) { + return this.getJaxbWorkspace_(workspace); + } + } + + /** + * Pre-condition: {@link #jaxbWorkspaces} is <code>synchronized</code> + */ + private InternalJaxbWorkspace getJaxbWorkspace_(IWorkspace workspace) { InternalJaxbWorkspace jaxbWorkspace = this.jaxbWorkspaces.get(workspace); - if ((jaxbWorkspace == null) && this.isActive()) { + if ((jaxbWorkspace == null) && this.isActive()) { // no new workspaces can be built during "start" or "stop"... jaxbWorkspace = this.buildJaxbWorkspace(workspace); this.jaxbWorkspaces.put(workspace, jaxbWorkspace); } @@ -85,4 +88,16 @@ public class JptJaxbCorePlugin private InternalJaxbWorkspace buildJaxbWorkspace(IWorkspace workspace) { return new InternalJaxbWorkspace(workspace); } + + private void disposeJaxbWorkspaces() { + // the list will not change during "stop" + for (InternalJaxbWorkspace jaxbWorkspace : this.jaxbWorkspaces.values()) { + try { + jaxbWorkspace.dispose(); + } catch (Throwable ex) { + this.logError(ex); // keep going + } + } + this.jaxbWorkspaces.clear(); + } } diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/InternalJaxbWorkbench.java b/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/InternalJaxbWorkbench.java index 412eca5817..011e1ae748 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/InternalJaxbWorkbench.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/InternalJaxbWorkbench.java @@ -20,8 +20,7 @@ public class InternalJaxbWorkbench { private final IWorkbench workbench; - // NB: the JAXB workbench must be synchronized whenever accessing any of this state - private InternalJaxbPlatformUiManager jaxbPlatformUiManager; + private final InternalJaxbPlatformUiManager jaxbPlatformUiManager; /** @@ -31,19 +30,13 @@ public class InternalJaxbWorkbench public InternalJaxbWorkbench(IWorkbench workbench) { super(); this.workbench = workbench; - } - - public IWorkbench getWorkbench() { - return this.workbench; + this.jaxbPlatformUiManager = this.buildJaxbPlatformUiManager(); } // ********** JAXB platform UI manager ********** - public synchronized InternalJaxbPlatformUiManager getJaxbPlatformUiManager() { - if ((this.jaxbPlatformUiManager == null) && this.isActive()) { - this.jaxbPlatformUiManager = this.buildJaxbPlatformUiManager(); - } + public InternalJaxbPlatformUiManager getJaxbPlatformUiManager() { return this.jaxbPlatformUiManager; } @@ -54,18 +47,12 @@ public class InternalJaxbWorkbench // ********** misc ********** - private boolean isActive() { - return JptJaxbUiPlugin.instance().isActive(); + public IWorkbench getWorkbench() { + return this.workbench; } - /** - * Internal: Called <em>only</em> by the - * {@link JptJaxbUiPlugin#stop_() Dali plug-in}. - */ - public synchronized void stop() { - if (this.jaxbPlatformUiManager != null) { - this.jaxbPlatformUiManager = null; - } + public void dispose() { + // nothing yet... } @Override diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/plugin/JptJaxbUiPlugin.java b/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/plugin/JptJaxbUiPlugin.java index 59acce9892..78ae705bb5 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/plugin/JptJaxbUiPlugin.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/plugin/JptJaxbUiPlugin.java @@ -9,11 +9,12 @@ ******************************************************************************/ package org.eclipse.jpt.jaxb.ui.internal.plugin; -import java.util.HashMap; +import java.util.Hashtable; import org.eclipse.jpt.common.core.internal.utility.JptPlugin; import org.eclipse.jpt.common.ui.internal.JptUIPlugin; import org.eclipse.jpt.jaxb.ui.internal.InternalJaxbWorkbench; import org.eclipse.ui.IWorkbench; +import org.osgi.framework.BundleContext; /** * Dali JAXB UI plug-in. @@ -21,8 +22,7 @@ import org.eclipse.ui.IWorkbench; public class JptJaxbUiPlugin extends JptUIPlugin { - // NB: the plug-in must be synchronized whenever accessing any of this state - private final HashMap<IWorkbench, InternalJaxbWorkbench> jaxbWorkbenchs = new HashMap<IWorkbench, InternalJaxbWorkbench>(); + private final Hashtable<IWorkbench, InternalJaxbWorkbench> jaxbWorkbenches = new Hashtable<IWorkbench, InternalJaxbWorkbench>(); // ********** singleton ********** @@ -49,23 +49,16 @@ public class JptJaxbUiPlugin } @Override - public void stop_() throws Exception { + public void stop(BundleContext context) throws Exception { try { - for (InternalJaxbWorkbench jaxbWorkbench : this.jaxbWorkbenchs.values()) { - try { - jaxbWorkbench.stop(); - } catch (Throwable ex) { - this.logError(ex); // keep going - } - } - this.jaxbWorkbenchs.clear(); + this.disposeJaxbWorkbenches(); } finally { - super.stop_(); + super.stop(context); } } - // ********** JAXB workbenchs ********** + // ********** JAXB workbenches ********** /** * Return the JAXB workbench corresponding to the specified Eclipse workbench. @@ -73,15 +66,25 @@ public class JptJaxbUiPlugin * The preferred way to retrieve a JAXB workbench is via the Eclipse * adapter framework: * <pre> - * JaxbWorkbench jaxbWorkbench = PlatformTools.getAdapter(PlatformUI.getWorkbench(), JaxbWorkbench.class); + * IWorkbench workbench = ...; + * JaxbWorkbench jaxbWorkbench = PlatformTools.getAdapter(workbench, JaxbWorkbench.class); * </pre> * @see org.eclipse.jpt.jaxb.ui.internal.WorkbenchAdapterFactory#getJaxbWorkbench(IWorkbench) */ - public synchronized InternalJaxbWorkbench getJaxbWorkbench(IWorkbench workbench) { - InternalJaxbWorkbench jaxbWorkbench = this.jaxbWorkbenchs.get(workbench); - if ((jaxbWorkbench == null) && this.isActive()) { + public InternalJaxbWorkbench getJaxbWorkbench(IWorkbench workbench) { + synchronized (this.jaxbWorkbenches) { + return this.getJaxbWorkbench_(workbench); + } + } + + /** + * Pre-condition: {@link #jaxbWorkbenches} is <code>synchronized</code> + */ + private InternalJaxbWorkbench getJaxbWorkbench_(IWorkbench workbench) { + InternalJaxbWorkbench jaxbWorkbench = this.jaxbWorkbenches.get(workbench); + if ((jaxbWorkbench == null) && this.isActive()) { // no new workbenches can be built during "start" or "stop"... jaxbWorkbench = this.buildJaxbWorkbench(workbench); - this.jaxbWorkbenchs.put(workbench, jaxbWorkbench); + this.jaxbWorkbenches.put(workbench, jaxbWorkbench); } return jaxbWorkbench; } @@ -89,4 +92,16 @@ public class JptJaxbUiPlugin private InternalJaxbWorkbench buildJaxbWorkbench(IWorkbench workbench) { return new InternalJaxbWorkbench(workbench); } + + private void disposeJaxbWorkbenches() { + // the list will not change during "stop" + for (InternalJaxbWorkbench jaxbWorkbench : this.jaxbWorkbenches.values()) { + try { + jaxbWorkbench.dispose(); + } catch (Throwable ex) { + this.logError(ex); // keep going + } + } + this.jaxbWorkbenches.clear(); + } } diff --git a/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/plugin/JptJaxbCoreTestsPlugin.java b/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/plugin/JptJaxbCoreTestsPlugin.java index 4a4ee477e1..e96147d3a3 100644 --- a/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/plugin/JptJaxbCoreTestsPlugin.java +++ b/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/plugin/JptJaxbCoreTestsPlugin.java @@ -14,6 +14,7 @@ import org.eclipse.jpt.common.core.internal.utility.JptPlugin; import org.eclipse.jpt.common.utility.internal.ObjectTools; import org.eclipse.jpt.jaxb.core.JaxbProjectManager; import org.eclipse.jpt.jaxb.core.JaxbWorkspace; +import org.osgi.framework.BundleContext; /** * Configure the core for testing:<ul> @@ -41,8 +42,8 @@ public class JptJaxbCoreTestsPlugin } @Override - protected void start_() throws Exception { - super.start_(); + public void start(BundleContext context) throws Exception { + super.start(context); JaxbProjectManager jaxbProjectManager = this.getJaxbProjectManager(); ObjectTools.execute(jaxbProjectManager, "handleEventsSynchronously"); JptPlugin.FlushPreferences = false; diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/property_files/jpa_core.properties b/jpa/plugins/org.eclipse.jpt.jpa.core/property_files/jpa_core.properties index bcd84c4a08..d344e207f1 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/property_files/jpa_core.properties +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/property_files/jpa_core.properties @@ -11,6 +11,7 @@ NONE=<None> BUILD_JPA_PROJECTS_JOB_NAME=Building JPA Projects +DISPOSE_JPA_PROJECTS_JOB_NAME=Disposing JPA Projects GET_JPA_PROJECTS_JOB_NAME=Retrieving JPA Projects GET_JPA_PROJECT_JOB_NAME=Retrieving JPA Project REBUILD_JPA_PROJECT_JOB_NAME=Rebuilding JPA Project diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatform.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatform.java index f8030169f6..ad67c3c8af 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatform.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatform.java @@ -89,6 +89,12 @@ public interface JpaPlatform */ JpaFile buildJpaFile(JpaProject jpaProject, IFile file); + /** + * Return the specified file's content type, as defined by various + * extensions. + */ + IContentType getContentType(IFile file); + // ********** Java annotations ********** @@ -158,8 +164,8 @@ public interface JpaPlatform // ********** database ********** /** - * Return a connection repository that can be used to query the database - * about database metadata. + * Return a connection factory that can be used to query the database + * about its metadata etc. */ ConnectionProfileFactory getConnectionProfileFactory(); diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatformFactory.java index dd1e4b001d..6b7e5bec62 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatformFactory.java @@ -9,6 +9,8 @@ ******************************************************************************/ package org.eclipse.jpt.jpa.core; +import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; + /** * This interface is to be implemented by a JPA vendor to extend Dali by * building a {@link JpaPlatform}. @@ -31,7 +33,7 @@ package org.eclipse.jpt.jpa.core; */ public interface JpaPlatformFactory { /** - * Build the JPA platform with the specified ID. + * Build the JPA platform with the specified config. */ - JpaPlatform buildJpaPlatform(String id); + JpaPlatform buildJpaPlatform(JpaPlatformConfig config); } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaProject.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaProject.java index de869a3908..d246640165 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaProject.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaProject.java @@ -490,6 +490,11 @@ public interface JpaProject */ ExtendedCommandExecutor getModifySharedDocumentCommandExecutor(); + /** + * Return the JPA project's JPA workspace. + */ + JpaWorkspace getJpaWorkspace(); + // ********** logging ********** diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaWorkspace.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaWorkspace.java index f73d35b7aa..8b2628ff3f 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaWorkspace.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaWorkspace.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Oracle. All rights reserved. + * Copyright (c) 2012, 2103 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. @@ -11,6 +11,7 @@ package org.eclipse.jpt.jpa.core; import org.eclipse.core.resources.IWorkspace; import org.eclipse.jpt.jpa.core.platform.JpaPlatformManager; +import org.eclipse.jpt.jpa.db.ConnectionProfileFactory; /** * The Dali JPA state corresponding to an {@link IWorkspace Eclipse workspace}. @@ -49,4 +50,9 @@ public interface JpaWorkspace { * Return the manager for all the workspace's JPA projects. */ JpaProjectManager getJpaProjectManager(); + + /** + * Return the workspace's connection profile factory. + */ + ConnectionProfileFactory getConnectionProfileFactory(); } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/AbstractJpaProject.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/AbstractJpaProject.java index 51d770fe17..9e1d5cf735 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/AbstractJpaProject.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/AbstractJpaProject.java @@ -1559,8 +1559,6 @@ public abstract class AbstractJpaProject this.stopCommand(this.synchronizeContextModelCommand); this.stopCommand(this.updateCommand); this.updateCommand.removeListener(this.updateCommandListener); -// this.setUserOverrideDefaultCatalog(null); -// this.setUserOverrideDefaultSchema(null); this.dataSource.dispose(); // the XML resources are held indefinitely by the WTP translator framework, // so we better remove our listener or the JPA project will not be GCed @@ -1807,8 +1805,8 @@ public abstract class AbstractJpaProject return false; } - protected static IContentType getContentType(IFile file) { - return GenericJpaPlatform.getContentType(file); + protected IContentType getContentType(IFile file) { + return this.getJpaPlatform().getContentType(file); } protected void resolveExternalJavaTypes() { diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatform.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatform.java index 400831c0d8..9946f21baf 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatform.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatform.java @@ -10,10 +10,8 @@ package org.eclipse.jpt.jpa.core.internal; import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.content.IContentType; -import org.eclipse.jdt.core.JavaCore; import org.eclipse.jpt.common.core.AnnotationProvider; import org.eclipse.jpt.common.core.JptResourceModel; import org.eclipse.jpt.common.core.JptResourceType; @@ -30,13 +28,11 @@ import org.eclipse.jpt.jpa.core.JpaPlatformProvider; import org.eclipse.jpt.jpa.core.JpaPlatformVariation; import org.eclipse.jpt.jpa.core.JpaProject; import org.eclipse.jpt.jpa.core.JpaResourceModelProvider; -import org.eclipse.jpt.jpa.core.JpaWorkspace; import org.eclipse.jpt.jpa.core.ResourceDefinition; import org.eclipse.jpt.jpa.core.context.java.DefaultJavaAttributeMappingDefinition; import org.eclipse.jpt.jpa.core.context.java.JavaAttributeMappingDefinition; import org.eclipse.jpt.jpa.core.context.java.JavaTypeMappingDefinition; import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; -import org.eclipse.jpt.jpa.core.platform.JpaPlatformManager; import org.eclipse.jpt.jpa.db.ConnectionProfileFactory; import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar; @@ -47,7 +43,7 @@ import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar; public class GenericJpaPlatform implements JpaPlatform { - private final String id; + private final JpaPlatformConfig config; private final Version jpaVersion; @@ -62,9 +58,17 @@ public class GenericJpaPlatform private final JPQLGrammar jpqlGrammar; - public GenericJpaPlatform(String id, Version jpaVersion, JpaFactory jpaFactory, AnnotationProvider annotationProvider, JpaPlatformProvider platformProvider, JpaPlatformVariation jpaVariation, JPQLGrammar jpqlGrammar) { + public GenericJpaPlatform( + JpaPlatformConfig config, + Version jpaVersion, + JpaFactory jpaFactory, + AnnotationProvider annotationProvider, + JpaPlatformProvider platformProvider, + JpaPlatformVariation jpaVariation, + JPQLGrammar jpqlGrammar + ) { super(); - this.id = id; + this.config = config; this.jpaVersion = jpaVersion; this.jpaFactory = jpaFactory; this.annotationProvider = annotationProvider; @@ -77,19 +81,11 @@ public class GenericJpaPlatform // ********** meta stuff ********** public String getId() { - return this.id; + return this.config.getId(); } public JpaPlatformConfig getConfig() { - return this.getJpaPlatformManager().getJpaPlatformConfig(this.getId()); - } - - private JpaPlatformManager getJpaPlatformManager() { - return this.getJpaWorkspace().getJpaPlatformManager(); - } - - private JpaWorkspace getJpaWorkspace() { - return (JpaWorkspace) ResourcesPlugin.getWorkspace().getAdapter(JpaWorkspace.class); + return this.config; } public Version getJpaVersion() { @@ -98,7 +94,7 @@ public class GenericJpaPlatform @Override public String toString() { - return ObjectTools.toString(this, this.id); + return ObjectTools.toString(this, this.getId()); } @@ -123,33 +119,21 @@ public class GenericJpaPlatform return (contentType == null) ? null : this.buildJpaFile(jpaProject, file, contentType); } - //TODO make this a non-static method on JpaPlatform - //I have done this because our code PlatformTools.getContentType(IFile) opens an InputStream - //on the IFile in order to find the content type for our xml mapping files. This is expensive - //when called for every file in the project and is only needed for xml mapping files. For now - //I am attempting to find the content type just based on the file name first and short-circuiting - //if it is a .java or .class file. If we made this api on the JpaPlatform we could potentially - //check if it is XML content type and then only do the more expensive InputStream look-up - //in that case. Because we are extensible we can't be 100% certain that a "mapping file" - //has xml content type so we would allow this to be overridable. - public static IContentType getContentType(IFile file) { + /** + * Performance hook: {@link PlatformTools#getContentType(IFile)} gets the + * file contents <em>every</em> time. Many of our files are Java files and + * it is possible to determine a Java file's content type from the file + * name; so do that here, before using {@link PlatformTools}. + */ + public IContentType getContentType(IFile file) { IContentType contentType = Platform.getContentTypeManager().findContentTypeFor(file.getName()); if (contentType != null) { if (contentType.equals(JavaResourceCompilationUnit.CONTENT_TYPE)) { return contentType; } - if (contentType.equals(JAVA_CLASS_CONTENT_TYPE)) { - return contentType; - } } return PlatformTools.getContentType(file); } - //TODO JptCommonCorePlugin.JAVA_CLASS_CONTENT_TYPE after API freeze - private static final IContentType JAVA_CLASS_CONTENT_TYPE = getContentType(JavaCore.PLUGIN_ID + ".javaClass");//$NON-NLS-1$ - - private static IContentType getContentType(String contentType) { - return Platform.getContentTypeManager().getContentType(contentType); - } protected JpaFile buildJpaFile(JpaProject jpaProject, IFile file, IContentType contentType) { JptResourceModel resourceModel = this.buildResourceModel(jpaProject, file, contentType); @@ -240,7 +224,7 @@ public class GenericJpaPlatform // ********** database ********** public ConnectionProfileFactory getConnectionProfileFactory() { - return (ConnectionProfileFactory) ResourcesPlugin.getWorkspace().getAdapter(ConnectionProfileFactory.class); + return this.config.getJpaPlatformManager().getJpaWorkspace().getConnectionProfileFactory(); } public EntityGeneratorDatabaseAnnotationNameBuilder getEntityGeneratorDatabaseAnnotationNameBuilder() { @@ -266,6 +250,6 @@ public class GenericJpaPlatform // ********** Hermes integration ********** public JPQLGrammar getJpqlGrammar() { - return jpqlGrammar; + return this.jpqlGrammar; } -}
\ No newline at end of file +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatformFactory.java index cc6a9d0279..6be7a9b2be 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatformFactory.java @@ -17,6 +17,7 @@ import org.eclipse.jpt.jpa.core.JpaPlatformVariation; import org.eclipse.jpt.jpa.core.JpaProject; import org.eclipse.jpt.jpa.core.context.AccessType; import org.eclipse.jpt.jpa.core.internal.jpa1.GenericJpaFactory; +import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar1_0; /** @@ -43,9 +44,9 @@ public class GenericJpaPlatformFactory super(); } - public JpaPlatform buildJpaPlatform(String id) { + public JpaPlatform buildJpaPlatform(JpaPlatformConfig config) { return new GenericJpaPlatform( - id, + config, this.buildJpaVersion(), new GenericJpaFactory(), new JpaAnnotationProvider(GenericJpaAnnotationDefinitionProvider.instance()), diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/InternalJpaProjectManager.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/InternalJpaProjectManager.java index 687b95de49..b56f41b0dc 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/InternalJpaProjectManager.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/InternalJpaProjectManager.java @@ -38,6 +38,7 @@ import org.eclipse.jdt.core.JavaCore; import org.eclipse.jpt.common.core.internal.JptCommonCoreMessages; import org.eclipse.jpt.common.core.internal.utility.ProjectTools; import org.eclipse.jpt.common.core.internal.utility.command.CommandJobCommandAdapter; +import org.eclipse.jpt.common.core.internal.utility.command.JobCommandAdapter; import org.eclipse.jpt.common.core.internal.utility.command.SimpleJobCommandExecutor; import org.eclipse.jpt.common.core.internal.utility.command.SingleUseQueueingExtendedJobCommandExecutor; import org.eclipse.jpt.common.core.utility.command.ExtendedJobCommandExecutor; @@ -46,6 +47,7 @@ import org.eclipse.jpt.common.utility.ExceptionHandler; import org.eclipse.jpt.common.utility.command.Command; import org.eclipse.jpt.common.utility.command.ExtendedCommandExecutor; import org.eclipse.jpt.common.utility.internal.ObjectTools; +import org.eclipse.jpt.common.utility.internal.command.CommandAdapter; import org.eclipse.jpt.common.utility.internal.command.ThreadLocalExtendedCommandExecutor; import org.eclipse.jpt.common.utility.internal.iterable.EmptyIterable; import org.eclipse.jpt.common.utility.internal.iterable.SingleElementIterable; @@ -70,7 +72,7 @@ import org.eclipse.wst.validation.internal.provisional.core.IMessage; import org.eclipse.wst.validation.internal.provisional.core.IReporter; /** - * The JPA project manager maintains a list of all the JPA projects in the + * The JPA project manager maintains a list of all the JPA projects in a * workspace. It keeps the list (and the state of the JPA projects themselves) * synchronized with the workspace by listening for Resource and Java change * events. @@ -92,9 +94,10 @@ import org.eclipse.wst.validation.internal.provisional.core.IReporter; * "synchronized" with the background jobs. This allows any outstanding events * to be handled <em>before</em> the value is returned. * <p> - * Various things that cause us to add or remove a JPA project:<ul> - * <li>The {@link JptJpaCorePlugin} will "lazily" instantiate and - * {@link #start() start} a JPA project manager as appropriate. + * Various things that cause us to add or remove a JPA project: + * <ul> + * <li>The {@link JptJpaCorePlugin} will "lazily" instantiate a JPA workspace + * and its corresponding JPA project manager as appropriate. * This will trigger the manager to find and add all pre-existing * JPA projects. * @@ -145,7 +148,7 @@ import org.eclipse.wst.validation.internal.provisional.core.IReporter; * facet settings file * </ul> */ -public class InternalJpaProjectManager +class InternalJpaProjectManager extends AbstractModel implements JpaProjectManager, JpaProject.Manager { @@ -248,53 +251,26 @@ public class InternalJpaProjectManager /** * Internal: Called <em>only</em> by the * {@link InternalJpaWorkspace#buildJpaProjectManager() JPA workspace}. + * <p> + * <strong>NB:</strong> The JPA projects are built asynchronously. */ - public InternalJpaProjectManager(JpaWorkspace jpaWorkspace) { + InternalJpaProjectManager(JpaWorkspace jpaWorkspace) { super(); this.jpaWorkspace = jpaWorkspace; - } - - - // ********** plug-in controlled life-cycle ********** - /** - * Internal: Called <em>only</em> by the - * {@link InternalJpaWorkspace#getJpaProjectManager() JPA workspace}. - * The JPA project manager will not be returned to any clients by the - * {@link JpaWorkspace JPA workspace} until <em>after</em> - * the manager has been started (i.e. this method has been called). - * As a result, we need not synchronize with the scheduling rule. - */ - public void start() { // dump a stack trace so we can determine what triggers this - JptJpaCorePlugin.instance().dumpStackTrace(TRACE_OPTION, "*** JPA project manager START ***"); //$NON-NLS-1$ + JptJpaCorePlugin.instance().dumpStackTrace(TRACE_OPTION, "*** new JPA project manager ***"); //$NON-NLS-1$ try { this.commandExecutor = this.buildAsynchronousCommandExecutor(); - this.buildJpaProjects(); + this.buildJpaProjects(); // typically async this.getWorkspace().addResourceChangeListener(this.resourceChangeListener, RESOURCE_CHANGE_EVENT_TYPES); JavaCore.addElementChangedListener(this.javaElementChangeListener, JAVA_CHANGE_EVENT_TYPES); } catch (RuntimeException ex) { JptJpaCorePlugin.instance().logError(ex); - this.stop(); + this.dispose(); } } - /** - * Internal: Called <em>only</em> by the - * {@link InternalJpaWorkspace#stop() JPA workspace}. - * The JPA project manager will <em>not</em> be restarted. - */ - public void stop() { - JptJpaCorePlugin.instance().trace(TRACE_OPTION, "*** JPA project manager STOP ***"); //$NON-NLS-1$ - JavaCore.removeElementChangedListener(this.javaElementChangeListener); - this.getWorkspace().removeResourceChangeListener(this.resourceChangeListener); - this.clearJpaProjects(); - // if the current executor is async, commands can continue to execute - // after we replace it here, but there will be no JPA projects for them to process... - this.commandExecutor = ExtendedJobCommandExecutor.Inactive.instance(); - JptJpaCorePlugin.instance().trace(TRACE_OPTION, "*** JPA project manager DEAD ***"); //$NON-NLS-1$ - } - // ********** build JPA projects ********** @@ -309,8 +285,9 @@ public class InternalJpaProjectManager } /* CU private */ class BuildJpaProjectsCommand - implements JobCommand + extends JobCommandAdapter { + @Override public IStatus execute(IProgressMonitor monitor) { InternalJpaProjectManager.this.buildJpaProjects_(monitor); return Status.OK_STATUS; @@ -330,27 +307,68 @@ public class InternalJpaProjectManager } - // ********** clear JPA projects ********** + // ********** disposal ********** /** - * <strong>NB:</strong> - * {@link IJobManager#beginRule(ISchedulingRule, IProgressMonitor)} - * will jump <em>ahead</em> of any job scheduled with a conflicting rule(!). - * We should only use this method of synchronization in {@link #stop()}. + * Internal: Called <em>only</em> by the + * {@link InternalJpaWorkspace#dispose() JPA workspace}. + * Once disposed, the JPA project manager cannot be restarted. */ - private void clearJpaProjects() { + void dispose() { + JptJpaCorePlugin.instance().trace(TRACE_OPTION, "*** JPA project manager dispose ***"); //$NON-NLS-1$ + JavaCore.removeElementChangedListener(this.javaElementChangeListener); + this.getWorkspace().removeResourceChangeListener(this.resourceChangeListener); + ExtendedJobCommandExecutor oldCE = this.commandExecutor; + // if the current executor is async, commands can continue to execute after we replace it here... + this.commandExecutor = ExtendedJobCommandExecutor.Inactive.instance(); + this.clearJpaProjects(oldCE); // synchronous + JptJpaCorePlugin.instance().trace(TRACE_OPTION, "*** JPA project manager DEAD ***"); //$NON-NLS-1$ + } + + /** + * Clear the JPA projects <em>synchronously</em>; + * suspending the workspace shutdown until the currently executing Dali + * jobs finish executing. + * <p> + * A typical scenario for outstanding Dali jobs is when the user saves a JPA + * file (e.g. an JPA-annotated Java file) as the workspace shuts down. This + * will trigger a validation job once the file is saved. + */ + private void clearJpaProjects(ExtendedJobCommandExecutor oldCE) { try { - this.getJobManager().beginRule(this.getWorkspaceRoot(), null); - this.clearJpaProjects_(); - } finally { - this.getJobManager().endRule(this.getWorkspaceRoot()); + this.clearJpaProjects_(oldCE); + } catch (InterruptedException ex) { + // it would be interesting to know how we could get here... + Thread.currentThread().interrupt(); + JptJpaCorePlugin.instance().logError(ex); } } - private void clearJpaProjects_() { + private void clearJpaProjects_(ExtendedJobCommandExecutor oldCE) throws InterruptedException { + JptJpaCorePlugin.instance().trace(TRACE_OPTION, "dispatch: clear JPA projects"); //$NON-NLS-1$ + ClearJpaProjectsCommand command = new ClearJpaProjectsCommand(); + oldCE.waitToExecute(command, JptCoreMessages.DISPOSE_JPA_PROJECTS_JOB_NAME, this.getWorkspaceRoot()); + JptJpaCorePlugin.instance().trace(TRACE_OPTION, "end: clear JPA projects"); //$NON-NLS-1$ + } + + /* CU private */ class ClearJpaProjectsCommand + extends JobCommandAdapter + { + @Override + public IStatus execute(IProgressMonitor monitor) { + InternalJpaProjectManager.this.clearJpaProjects_(monitor); + return Status.OK_STATUS; + } + } + + /* CU private */ void clearJpaProjects_(IProgressMonitor monitor) { JptJpaCorePlugin.instance().trace(TRACE_OPTION, "execute: clear JPA projects"); //$NON-NLS-1$ - // clone the collection to prevent concurrent modification exception - for (JpaProject jpaProject : this.getJpaProjects()) { + for (JpaProject jpaProject : this.jpaProjects) { + if (monitor.isCanceled()) { + JptJpaCorePlugin.instance().trace(TRACE_OPTION, "CANCEL: clear JPA projects: {0}", jpaProject.getName()); //$NON-NLS-1$ + throw new OperationCanceledException(); + } + // *remove* the JPA projects so we fire the appropriate model events(?) this.removeJpaProject(jpaProject); } JptJpaCorePlugin.instance().trace(TRACE_OPTION, "end: clear JPA projects"); //$NON-NLS-1$ @@ -367,18 +385,21 @@ public class InternalJpaProjectManager } /* CU private */ class GetJpaProjectsCommand - implements Command + extends CommandAdapter { Iterable<JpaProject> result; + + @Override public void execute() { this.result = InternalJpaProjectManager.this.getJpaProjects_(); } } /** - * Pre-condition: called from {@link GetJpaProjectsCommand#execute()} + * @see GetJpaProjectsCommand#execute() + * @see ProjectAdapterFactory#getJpaProject(IProject) */ - /* CU private */ Iterable<JpaProject> getJpaProjects_() { + Iterable<JpaProject> getJpaProjects_() { JptJpaCorePlugin.instance().trace(TRACE_OPTION, "execute: get JPA projects: {0}", this.jpaProjects); //$NON-NLS-1$ // clone the JPA projects immediately, while we have the lock return this.getJpaProjects(); @@ -429,13 +450,17 @@ public class InternalJpaProjectManager } /* CU private */ class GetJpaProjectCommand - implements Command + extends CommandAdapter { private final IProject project; JpaProject result; + GetJpaProjectCommand(IProject project) { + super(); this.project = project; } + + @Override public void execute() { this.result = InternalJpaProjectManager.this.getJpaProjectUnsafe(this.project); } @@ -454,10 +479,7 @@ public class InternalJpaProjectManager return jpaProject; } - /** - * Called from {@link ProjectAdapterFactory#getJpaProject(IProject)}. - */ - JpaProject getJpaProject_(IProject project) { + private JpaProject getJpaProject_(IProject project) { return selectJpaProject(this.getJpaProjects(), project); } @@ -485,13 +507,17 @@ public class InternalJpaProjectManager } /* CU private */ class RebuildJpaProjectCommand - implements JobCommand + extends JobCommandAdapter { private final IProject project; JpaProject result; + RebuildJpaProjectCommand(IProject project) { + super(); this.project = project; } + + @Override public IStatus execute(IProgressMonitor monitor) { this.result = InternalJpaProjectManager.this.rebuildJpaProject_(this.project, monitor); return Status.OK_STATUS; @@ -502,6 +528,7 @@ public class InternalJpaProjectManager JptJpaCorePlugin.instance().trace(TRACE_OPTION, "execute: rebuild JPA project: {0}", project.getName()); //$NON-NLS-1$ this.removeJpaProject(this.getJpaProject_(project)); if (monitor.isCanceled()) { + JptJpaCorePlugin.instance().trace(TRACE_OPTION, "CANCEL: rebuild JPA project: {0}", project.getName()); //$NON-NLS-1$ throw new OperationCanceledException(); } return this.addJpaProject(project); @@ -521,15 +548,19 @@ public class InternalJpaProjectManager } /* CU private */ class BuildValidationMessagesCommand - implements Command + extends CommandAdapter { private final IProject project; private final IReporter reporter; Iterable<IMessage> result; + BuildValidationMessagesCommand(IProject project, IReporter reporter) { + super(); this.project = project; this.reporter = reporter; } + + @Override public void execute() { this.result = InternalJpaProjectManager.this.buildValidationMessages_(this.project, this.reporter); } @@ -677,6 +708,10 @@ public class InternalJpaProjectManager // dump a stack trace so we can determine what triggers this JptJpaCorePlugin.instance().dumpStackTrace(TRACE_OPTION, "remove JPA project: {0}", jpaProject); //$NON-NLS-1$ this.removeItemFromCollection(jpaProject, this.jpaProjects, JPA_PROJECTS_COLLECTION); + this.disposeJpaProject(jpaProject); + } + + private void disposeJpaProject(JpaProject jpaProject) { try { jpaProject.dispose(); } catch (RuntimeException ex) { @@ -694,12 +729,16 @@ public class InternalJpaProjectManager } /* CU private */ class ProjectChangeEventHandlerCommand - implements JobCommand + extends JobCommandAdapter { private final IResourceDelta delta; + ProjectChangeEventHandlerCommand(IResourceDelta delta) { + super(); this.delta = delta; } + + @Override public IStatus execute(IProgressMonitor monitor) { InternalJpaProjectManager.this.projectChanged_(this.delta, monitor); return Status.OK_STATUS; @@ -714,14 +753,15 @@ public class InternalJpaProjectManager JptJpaCorePlugin.instance().trace(TRACE_OPTION, "execute: project changed: {0}", delta.getResource()); //$NON-NLS-1$ // debug("execute: project changed: ", ((org.eclipse.core.internal.events.ResourceDelta) delta).toDeepDebugString()); //$NON-NLS-1$ for (JpaProject jpaProject : this.jpaProjects) { + if (monitor.isCanceled()) { + JptJpaCorePlugin.instance().trace(TRACE_OPTION, "CANCEL: project changed: {0}", jpaProject.getName()); //$NON-NLS-1$ + throw new OperationCanceledException(); + } try { jpaProject.projectChanged(delta); } catch (RuntimeException ex) { JptJpaCorePlugin.instance().logError(ex); } - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } } } @@ -735,12 +775,16 @@ public class InternalJpaProjectManager } /* CU private */ class ProjectPostCleanBuildEventHandlerCommand - implements JobCommand + extends JobCommandAdapter { private final IProject project; + ProjectPostCleanBuildEventHandlerCommand(IProject project) { + super(); this.project = project; } + + @Override public IStatus execute(IProgressMonitor monitor) { InternalJpaProjectManager.this.projectPostCleanBuild_(this.project, monitor); return Status.OK_STATUS; @@ -753,6 +797,7 @@ public class InternalJpaProjectManager if (jpaProject != null) { this.removeJpaProject(jpaProject); if (monitor.isCanceled()) { + JptJpaCorePlugin.instance().trace(TRACE_OPTION, "CANCEL: post clean build: {0}", project.getName()); //$NON-NLS-1$ throw new OperationCanceledException(); } this.addJpaProject(project); @@ -774,12 +819,16 @@ public class InternalJpaProjectManager } /* CU private */ class FacetFileChangeEventHandlerCommand - implements Command + extends CommandAdapter { private final IProject project; + FacetFileChangeEventHandlerCommand(IProject project) { + super(); this.project = project; } + + @Override public void execute() { InternalJpaProjectManager.this.checkForJpaFacetTransition_(this.project); } @@ -810,12 +859,16 @@ public class InternalJpaProjectManager } /* CU private */ class JavaChangeEventHandlerCommand - implements JobCommand + extends JobCommandAdapter { private final ElementChangedEvent event; + JavaChangeEventHandlerCommand(ElementChangedEvent event) { + super(); this.event = event; } + + @Override public IStatus execute(IProgressMonitor monitor) { InternalJpaProjectManager.this.javaElementChanged_(this.event, monitor); return Status.OK_STATUS; @@ -829,14 +882,15 @@ public class InternalJpaProjectManager /* CU private */ void javaElementChanged_(ElementChangedEvent event, IProgressMonitor monitor) { JptJpaCorePlugin.instance().trace(TRACE_OPTION, "execute: Java element changed: {0}", event.getDelta()); //$NON-NLS-1$ for (JpaProject jpaProject : this.jpaProjects) { + if (monitor.isCanceled()) { + JptJpaCorePlugin.instance().trace(TRACE_OPTION, "CANCEL: Java element changed: {0}", jpaProject.getName()); //$NON-NLS-1$ + throw new OperationCanceledException(); + } try { jpaProject.javaElementChanged(event); } catch (RuntimeException ex) { JptJpaCorePlugin.instance().logError(ex); } - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } } } @@ -936,7 +990,8 @@ public class InternalJpaProjectManager /** * Check whether the specified scheduling rule * {@link ISchedulingRule#isConflicting(ISchedulingRule) conflicts} with the - * {@link IJobManager#currentRule() current rule}. If the rules conflict, + * {@link IJobManager#currentRule() rule held by the current thread}. + * If the rules conflict, * execute the specified command directly (i.e. synchronously) to prevent a * deadlock. This should not cause a problem because if the current rule * conflicts with the specified rule, the current rule will also prevent any @@ -987,12 +1042,12 @@ public class InternalJpaProjectManager // de-activate Java events this.addJavaEventListenerFlag(BooleanReference.False.instance()); // save the current executor - SimpleJobCommandExecutor old = (SimpleJobCommandExecutor) this.commandExecutor; + SimpleJobCommandExecutor oldCE = (SimpleJobCommandExecutor) this.commandExecutor; // install a new (not-yet-started) executor SingleUseQueueingExtendedJobCommandExecutor newCE = this.buildSynchronousCommandExecutor(); this.commandExecutor = newCE; // wait for all the outstanding commands to finish - old.waitToExecute(Command.Null.instance()); + oldCE.waitToExecute(Command.Null.instance()); // start up the new executor (it will now execute any commands that // arrived while we were waiting on the outstanding commands) newCE.start(); @@ -1096,15 +1151,16 @@ public class InternalJpaProjectManager } private void processProject(IResourceProxy resourceProxy) { + if (this.monitor.isCanceled()) { + JptJpaCorePlugin.instance().trace(TRACE_OPTION, "CANCEL: resource proxy visitor: {0}", resourceProxy); //$NON-NLS-1$ + throw new OperationCanceledException(); + } if (resourceProxy.isAccessible()) { // the project exists and is open IProject project = (IProject) resourceProxy.requestResource(); if (ProjectTools.hasFacet(project, JpaProject.FACET)) { InternalJpaProjectManager.this.addJpaProject(project); } } - if (this.monitor.isCanceled()) { - throw new OperationCanceledException(); - } } @Override @@ -1313,7 +1369,7 @@ public class InternalJpaProjectManager // ********** java events ********** - boolean javaEventListenersAreActive() { + /* CU private */ boolean javaEventListenersAreActive() { synchronized (this.javaEventListenerFlags) { return this.javaEventListenersAreActive_(); } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/InternalJpaWorkspace.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/InternalJpaWorkspace.java index 2c8ca787aa..97d5287b19 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/InternalJpaWorkspace.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/InternalJpaWorkspace.java @@ -13,47 +13,35 @@ import org.eclipse.core.resources.IWorkspace; import org.eclipse.jpt.common.utility.internal.ObjectTools; import org.eclipse.jpt.jpa.core.JpaWorkspace; import org.eclipse.jpt.jpa.core.internal.platform.InternalJpaPlatformManager; -import org.eclipse.jpt.jpa.core.internal.plugin.JptJpaCorePlugin; +import org.eclipse.jpt.jpa.db.ConnectionProfileFactory; public class InternalJpaWorkspace implements JpaWorkspace { private final IWorkspace workspace; - // NB: the JPA workspace must be synchronized whenever accessing any of this state - private InternalJpaPlatformManager jpaPlatformManager; - private InternalJpaProjectManager jpaProjectManager; + private final InternalJpaPlatformManager jpaPlatformManager; + private final InternalJpaProjectManager jpaProjectManager; + private final ConnectionProfileFactory connectionProfileFactory; /** * Internal: Called <em>only</em> by the - * {@link JptJpaCorePlugin#buildJpaWorkspace(IWorkspace) Dali JPA plug-in}. + * {@link org.eclipse.jpt.jpa.core.internal.plugin.JptJpaCorePlugin#buildJpaWorkspace(IWorkspace) + * Dali JPA plug-in}. */ public InternalJpaWorkspace(IWorkspace workspace) { super(); this.workspace = workspace; - } - - public IWorkspace getWorkspace() { - return this.workspace; - } - - /** - * Internal: Called <em>only</em> by the - * {@link JpaPreferenceInitializer#initializeDefaultPreferences() - * JPA preferences initializer}. - */ - void initializeDefaultPreferences() { - this.getJpaPlatformManager().initializeDefaultPreferences(); + this.jpaPlatformManager = this.buildJpaPlatformManager(); + this.jpaProjectManager = this.buildJpaProjectManager(); + this.connectionProfileFactory = this.buildConnectionProfileFactory(); } // ********** JPA platform manager ********** - public synchronized InternalJpaPlatformManager getJpaPlatformManager() { - if ((this.jpaPlatformManager == null) && this.isActive()) { - this.jpaPlatformManager = this.buildJpaPlatformManager(); - } + public InternalJpaPlatformManager getJpaPlatformManager() { return this.jpaPlatformManager; } @@ -64,11 +52,7 @@ public class InternalJpaWorkspace // ********** JPA project manager ********** - public synchronized InternalJpaProjectManager getJpaProjectManager() { - if ((this.jpaProjectManager == null) && this.isActive()) { - this.jpaProjectManager = this.buildJpaProjectManager(); - this.jpaProjectManager.start(); - } + public InternalJpaProjectManager getJpaProjectManager() { return this.jpaProjectManager; } @@ -77,24 +61,42 @@ public class InternalJpaWorkspace } + // ********** connection profile factory ********** + + public ConnectionProfileFactory getConnectionProfileFactory() { + return this.connectionProfileFactory; + } + + private ConnectionProfileFactory buildConnectionProfileFactory() { + return (ConnectionProfileFactory) this.workspace.getAdapter(ConnectionProfileFactory.class); + } + + // ********** misc ********** - private boolean isActive() { - return JptJpaCorePlugin.instance().isActive(); + public IWorkspace getWorkspace() { + return this.workspace; + } + + /** + * Internal: Called <em>only</em> by the + * {@link JpaPreferenceInitializer#initializeDefaultPreferences() + * JPA preferences initializer}. + */ + void initializeDefaultPreferences() { + this.getJpaPlatformManager().initializeDefaultPreferences(); } /** * Internal: Called <em>only</em> by the - * {@link JptJpaCorePlugin#stop_() Dali plug-in}. + * {@link org.eclipse.jpt.jpa.core.internal.plugin.JptJpaCorePlugin#stop(org.osgi.framework.BundleContext) + * Dali plug-in}. + * <p> + * This will suspend the current thread until all the JPA projects are + * disposed etc. */ - public synchronized void stop() { - if (this.jpaPlatformManager != null) { - this.jpaPlatformManager = null; - } - if (this.jpaProjectManager != null) { - this.jpaProjectManager.stop(); - this.jpaProjectManager = null; - } + public void dispose() { + this.jpaProjectManager.dispose(); } @Override diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/JptCoreMessages.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/JptCoreMessages.java index 357002c36d..267f0ac3e7 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/JptCoreMessages.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/JptCoreMessages.java @@ -25,6 +25,7 @@ public class JptCoreMessages { public static String NONE; public static String BUILD_JPA_PROJECTS_JOB_NAME; + public static String DISPOSE_JPA_PROJECTS_JOB_NAME; public static String GET_JPA_PROJECTS_JOB_NAME; public static String GET_JPA_PROJECT_JOB_NAME; public static String REBUILD_JPA_PROJECT_JOB_NAME; diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/WorkspaceAdapterFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/WorkspaceAdapterFactory.java index 786c73cdb1..e56a87deaa 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/WorkspaceAdapterFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/WorkspaceAdapterFactory.java @@ -56,6 +56,7 @@ public class WorkspaceAdapterFactory } private JpaProjectManager getJpaProjectManager(IWorkspace workspace) { - return this.getJpaWorkspace(workspace).getJpaProjectManager(); + JpaWorkspace jpaWorkspace = this.getJpaWorkspace(workspace); + return (jpaWorkspace == null) ? null : jpaWorkspace.getJpaProjectManager(); } } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/facet/JpaFacetActionDelegate.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/facet/JpaFacetActionDelegate.java index 4816e6e256..4eba85371c 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/facet/JpaFacetActionDelegate.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/facet/JpaFacetActionDelegate.java @@ -10,7 +10,6 @@ package org.eclipse.jpt.jpa.core.internal.facet; import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubMonitor; @@ -68,18 +67,18 @@ public abstract class JpaFacetActionDelegate subMonitor.worked(1); // defaults settings - this.getJpaPlatformManager().setDefaultJpaPlatformConfig(fv, platformConfig); + this.getJpaPlatformManager(project).setDefaultJpaPlatformConfig(fv, platformConfig); subMonitor.worked(1); //Delegate to LibraryInstallDelegate to configure the project classpath ((LibraryInstallDelegate) dataModel.getProperty(JpaFacetDataModelProperties.LIBRARY_PROVIDER_DELEGATE)).execute(subMonitor.newChild(1)); } - protected JpaPlatformManager getJpaPlatformManager() { - return this.getJpaWorkspace().getJpaPlatformManager(); + protected JpaPlatformManager getJpaPlatformManager(IProject project) { + return this.getJpaWorkspace(project).getJpaPlatformManager(); } - protected JpaWorkspace getJpaWorkspace() { - return (JpaWorkspace) ResourcesPlugin.getWorkspace().getAdapter(JpaWorkspace.class); + protected JpaWorkspace getJpaWorkspace(IProject project) { + return (JpaWorkspace) project.getWorkspace().getAdapter(JpaWorkspace.class); } } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/facet/JpaFacetInstallDelegate.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/facet/JpaFacetInstallDelegate.java index 8dd1959846..3bb2bc6e8c 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/facet/JpaFacetInstallDelegate.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/facet/JpaFacetInstallDelegate.java @@ -12,7 +12,6 @@ package org.eclipse.jpt.jpa.core.internal.facet; import static org.eclipse.jpt.common.core.internal.operations.JptFileCreationDataModelProperties.CONTAINER_PATH; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; @@ -71,13 +70,13 @@ public class JpaFacetInstallDelegate } String driverName = dataModel.getStringProperty(DB_DRIVER_NAME); - IClasspathContainer container = this.getConnectionProfileFactory().buildDriverClasspathContainer(driverName); + IClasspathContainer container = this.getConnectionProfileFactory(javaProject.getProject()).buildDriverClasspathContainer(driverName); IClasspathEntry entry = JavaCore.newContainerEntry(container.getPath()); this.addClasspathEntryToProject(entry, javaProject, monitor); } - private ConnectionProfileFactory getConnectionProfileFactory() { - return (ConnectionProfileFactory) ResourcesPlugin.getWorkspace().getAdapter(ConnectionProfileFactory.class); + private ConnectionProfileFactory getConnectionProfileFactory(IProject project) { + return (ConnectionProfileFactory) project.getWorkspace().getAdapter(ConnectionProfileFactory.class); } private void addClasspathEntryToProject( diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/GenericJpaDataSource.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/GenericJpaDataSource.java index 85a99162e9..46a5d2114f 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/GenericJpaDataSource.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/GenericJpaDataSource.java @@ -16,6 +16,7 @@ import org.eclipse.jpt.jpa.core.internal.AbstractJpaNode; import org.eclipse.jpt.jpa.db.ConnectionAdapter; import org.eclipse.jpt.jpa.db.ConnectionListener; import org.eclipse.jpt.jpa.db.ConnectionProfile; +import org.eclipse.jpt.jpa.db.ConnectionProfileAdapter; import org.eclipse.jpt.jpa.db.ConnectionProfileFactory; import org.eclipse.jpt.jpa.db.ConnectionProfileListener; import org.eclipse.jpt.jpa.db.Database; @@ -124,7 +125,6 @@ public class GenericJpaDataSource if (this.connectionProfile != null) { this.connectionProfile.removeConnectionListener(this.connectionListener); } -// this.setConnectionProfileName(null); this.getConnectionProfileFactory().removeConnectionProfileListener(this.connectionProfileListener); } @@ -169,12 +169,9 @@ public class GenericJpaDataSource * Also listen for our connection's name being changed. */ protected class LocalConnectionProfileListener - implements ConnectionProfileListener + extends ConnectionProfileAdapter { - protected LocalConnectionProfileListener() { - super(); - } - + @Override public void connectionProfileAdded(String name) { // check to see if a connection profile with our name was added // (assume our connection profile is null) @@ -185,6 +182,7 @@ public class GenericJpaDataSource } } + @Override public void connectionProfileRemoved(String name) { if (GenericJpaDataSource.this.connectionProfile == null) { return; @@ -194,6 +192,7 @@ public class GenericJpaDataSource } } + @Override public void connectionProfileRenamed(String oldName, String newName) { if (GenericJpaDataSource.this.connectionProfile == null) { if (newName.equals(GenericJpaDataSource.this.connectionProfileName)) { diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa2/Generic2_0JpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa2/Generic2_0JpaPlatformFactory.java index 3d60c81881..eef02f6cd0 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa2/Generic2_0JpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa2/Generic2_0JpaPlatformFactory.java @@ -18,6 +18,7 @@ import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatform; import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatformFactory.GenericJpaPlatformVersion; import org.eclipse.jpt.jpa.core.internal.JpaAnnotationProvider; import org.eclipse.jpt.jpa.core.jpa2.JpaProject2_0; +import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar2_0; /** @@ -36,9 +37,9 @@ public class Generic2_0JpaPlatformFactory super(); } - public JpaPlatform buildJpaPlatform(String id) { + public JpaPlatform buildJpaPlatform(JpaPlatformConfig config) { return new GenericJpaPlatform( - id, + config, this.buildJpaVersion(), new GenericJpaFactory2_0(), new JpaAnnotationProvider(Generic2_0JpaAnnotationDefinitionProvider.instance()), diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa2_1/Generic2_1JpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa2_1/Generic2_1JpaPlatformFactory.java index b6b23dd3f5..0c93fa4ea6 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa2_1/Generic2_1JpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa2_1/Generic2_1JpaPlatformFactory.java @@ -19,6 +19,7 @@ import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatformFactory.GenericJpaPla import org.eclipse.jpt.jpa.core.internal.JpaAnnotationProvider; import org.eclipse.jpt.jpa.core.internal.jpa2.GenericJpaFactory2_0; import org.eclipse.jpt.jpa.core.jpa2_1.JpaProject2_1; +import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar2_1; /** @@ -37,9 +38,9 @@ public class Generic2_1JpaPlatformFactory super(); } - public JpaPlatform buildJpaPlatform(String id) { + public JpaPlatform buildJpaPlatform(JpaPlatformConfig config) { return new GenericJpaPlatform( - id, + config, this.buildJpaVersion(), new GenericJpaFactory2_0(), new JpaAnnotationProvider(Generic2_1JpaAnnotationDefinitionProvider.instance()), diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/platform/InternalJpaPlatformConfig.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/platform/InternalJpaPlatformConfig.java index 30e6f82b3d..621705805f 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/platform/InternalJpaPlatformConfig.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/platform/InternalJpaPlatformConfig.java @@ -94,7 +94,7 @@ class InternalJpaPlatformConfig this.pluginId = pluginId; } - synchronized JpaPlatform getJpaPlatform() { + public synchronized JpaPlatform getJpaPlatform() { if (this.jpaPlatform == null) { this.jpaPlatform = this.buildJpaPlatform(); } @@ -103,7 +103,7 @@ class InternalJpaPlatformConfig private JpaPlatform buildJpaPlatform() { JpaPlatformFactory factory = this.buildJpaPlatformFactory(); - return (factory == null) ? null : factory.buildJpaPlatform(this.id); + return (factory == null) ? null : factory.buildJpaPlatform(this); } private JpaPlatformFactory buildJpaPlatformFactory() { diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/plugin/JptJpaCorePlugin.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/plugin/JptJpaCorePlugin.java index 871da7e474..1ecebacc58 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/plugin/JptJpaCorePlugin.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/plugin/JptJpaCorePlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2012 Oracle. All rights reserved. + * Copyright (c) 2006, 2013 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. @@ -9,11 +9,12 @@ ******************************************************************************/ package org.eclipse.jpt.jpa.core.internal.plugin; -import java.util.HashMap; +import java.util.Hashtable; import org.eclipse.core.resources.IWorkspace; import org.eclipse.jpt.common.core.internal.utility.JptPlugin; import org.eclipse.jpt.common.utility.internal.StringTools; import org.eclipse.jpt.jpa.core.internal.InternalJpaWorkspace; +import org.osgi.framework.BundleContext; /** * Dali JPA core plug-in. @@ -21,8 +22,7 @@ import org.eclipse.jpt.jpa.core.internal.InternalJpaWorkspace; public class JptJpaCorePlugin extends JptPlugin { - // NB: the plug-in must be synchronized whenever accessing any of this state - private final HashMap<IWorkspace, InternalJpaWorkspace> jpaWorkspaces = new HashMap<IWorkspace, InternalJpaWorkspace>(); + private final Hashtable<IWorkspace, InternalJpaWorkspace> jpaWorkspaces = new Hashtable<IWorkspace, InternalJpaWorkspace>(); // ********** singleton ********** @@ -49,18 +49,11 @@ public class JptJpaCorePlugin } @Override - protected void stop_() throws Exception { + public void stop(BundleContext context) throws Exception { try { - for (InternalJpaWorkspace jpaWorkspace : this.jpaWorkspaces.values()) { - try { - jpaWorkspace.stop(); - } catch (Throwable ex) { - this.logError(ex); // keep going - } - } - this.jpaWorkspaces.clear(); + this.disposeJpaWorkspaces(); } finally { - super.stop_(); + super.stop(context); } } @@ -92,13 +85,23 @@ public class JptJpaCorePlugin * The preferred way to retrieve a JPA workspace is via the Eclipse * adapter framework: * <pre> - * JpaWorkspace jpaWorkspace = (JpaWorkspace) ResourcesPlugin.getWorkspace().getAdapter(JpaWorkspace.class) + * IWorkspace workspace = ...; + * JpaWorkspace jpaWorkspace = (JpaWorkspace) workspace.getAdapter(JpaWorkspace.class) * </pre> * @see org.eclipse.jpt.jpa.core.internal.WorkspaceAdapterFactory#getJpaWorkspace(IWorkspace) */ - public synchronized InternalJpaWorkspace getJpaWorkspace(IWorkspace workspace) { + public InternalJpaWorkspace getJpaWorkspace(IWorkspace workspace) { + synchronized (this.jpaWorkspaces) { + return this.getJpaWorkspace_(workspace); + } + } + + /** + * Pre-condition: {@link #jpaWorkspaces} is <code>synchronized</code> + */ + private InternalJpaWorkspace getJpaWorkspace_(IWorkspace workspace) { InternalJpaWorkspace jpaWorkspace = this.jpaWorkspaces.get(workspace); - if ((jpaWorkspace == null) && this.isActive()) { + if ((jpaWorkspace == null) && this.isActive()) { // no new workspaces can be built during "start" or "stop"... jpaWorkspace = this.buildJpaWorkspace(workspace); this.jpaWorkspaces.put(workspace, jpaWorkspace); } @@ -108,4 +111,20 @@ public class JptJpaCorePlugin private InternalJpaWorkspace buildJpaWorkspace(IWorkspace workspace) { return new InternalJpaWorkspace(workspace); } + + /** + * This will suspend the current thread until all the JPA projects are + * disposed etc. + */ + private void disposeJpaWorkspaces() { + // the list will not change during "stop" + for (InternalJpaWorkspace jpaWorkspace : this.jpaWorkspaces.values()) { + try { + jpaWorkspace.dispose(); + } catch (Throwable ex) { + this.logError(ex); // keep going + } + } + this.jpaWorkspaces.clear(); + } } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/refactoring/JpaDeletePackageOrFolderParticipant.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/refactoring/JpaDeletePackageOrFolderParticipant.java index 42822f6663..afce75b234 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/refactoring/JpaDeletePackageOrFolderParticipant.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/refactoring/JpaDeletePackageOrFolderParticipant.java @@ -32,9 +32,9 @@ import org.eclipse.jpt.common.utility.internal.ObjectTools; import org.eclipse.jpt.common.utility.internal.iterable.CompositeIterable; import org.eclipse.jpt.common.utility.internal.iterable.FilteringIterable; import org.eclipse.jpt.common.utility.internal.iterable.TransformationIterable; +import org.eclipse.jpt.jpa.core.JpaPlatform; import org.eclipse.jpt.jpa.core.JpaProject; import org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnit; -import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatform; import org.eclipse.jpt.jpa.core.internal.plugin.JptJpaCorePlugin; import org.eclipse.jpt.jpa.core.resource.ResourceMappingFile; import org.eclipse.ltk.core.refactoring.participants.ISharableParticipant; @@ -173,6 +173,7 @@ public class JpaDeletePackageOrFolderParticipant @SuppressWarnings("unchecked") protected Iterable<IFile> getMappingFilesOnClasspath(final JpaProject jpaProject) { final IJavaProject javaProject = jpaProject.getJavaProject(); + final JpaPlatform jpaPlatform = jpaProject.getJpaPlatform(); return new FilteringIterable<IFile>(new CompositeIterable<IFile>( getPossibleMappingFilesInFolders(), getPossibleMappingFilesInPackageFragments())) @@ -180,7 +181,7 @@ public class JpaDeletePackageOrFolderParticipant @Override protected boolean accept(IFile file) { if (javaProject.isOnClasspath(file)) { - IContentType contentType = GenericJpaPlatform.getContentType(file); + IContentType contentType = jpaPlatform.getContentType(file); return contentType != null && contentType.isKindOf(ResourceMappingFile.Root.CONTENT_TYPE); } return false; diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/validation/JpaValidator.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/validation/JpaValidator.java index 04c4d88316..6d7a779111 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/validation/JpaValidator.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/validation/JpaValidator.java @@ -9,6 +9,7 @@ ******************************************************************************/ package org.eclipse.jpt.jpa.core.internal.validation; +import java.util.ArrayList; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -80,34 +81,24 @@ public class JpaValidator // ********** internal ********** - private void clearMarkers(IProject project) { - try { - this.clearMarkers_(project); - } catch (CoreException ex) { - JptJpaCorePlugin.instance().logError(ex); - } - } + private void validate(IReporter reporter, IProject project) { + Iterable<IMessage> allMessages = this.buildValidationMessages(reporter, project); - private void clearMarkers_(IProject project) throws CoreException { - IMarker[] markers = project.findMarkers(MARKER_ID, true, IResource.DEPTH_INFINITE); - for (IMarker marker : markers) { - marker.delete(); + ArrayList<IMessage> messages = new ArrayList<IMessage>(); + for (IMessage message : allMessages) { + // check preferences for IGNORE + if (ObjectTools.notEquals(JpaPreferences.getProblemSeverity(project, message.getId()), JpaPreferences.PROBLEM_IGNORE)) { + messages.add(message); + } } - } - private void validate(IReporter reporter, IProject project) { - Iterable<IMessage> messages = this.buildValidationMessages(reporter, project); - // since the validation messages are usually built asynchronously // and a workspace shutdown could occur in the meantime, // wait until we actually get the new messages before we clear out the old messages this.clearMarkers(project); for (IMessage message : messages) { - // check preferences for IGNORE - if (ObjectTools.notEquals(JpaPreferences.getProblemSeverity(project, message.getId()), JpaPreferences.PROBLEM_IGNORE)) { - reporter.addMessage(this, message); - } + reporter.addMessage(this, message); } } @@ -127,4 +118,19 @@ public class JpaValidator private JpaProject.Reference getJpaProjectReference(IProject project) { return (JpaProject.Reference) project.getAdapter(JpaProject.Reference.class); } + + private void clearMarkers(IProject project) { + try { + this.clearMarkers_(project); + } catch (CoreException ex) { + JptJpaCorePlugin.instance().logError(ex); + } + } + + private void clearMarkers_(IProject project) throws CoreException { + IMarker[] markers = project.findMarkers(MARKER_ID, true, IResource.DEPTH_INFINITE); + for (IMarker marker : markers) { + marker.delete(); + } + } } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/platform/JpaPlatformConfig.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/platform/JpaPlatformConfig.java index 24ab60ca6e..c62e857df0 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/platform/JpaPlatformConfig.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/platform/JpaPlatformConfig.java @@ -10,6 +10,7 @@ package org.eclipse.jpt.jpa.core.platform; import org.eclipse.jpt.common.utility.filter.Filter; +import org.eclipse.jpt.jpa.core.JpaPlatform; import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion; /** @@ -83,6 +84,11 @@ public interface JpaPlatformConfig { */ String getPluginId(); + /** + * Build and return the config's JPA platform. + */ + JpaPlatform getJpaPlatform(); + Filter<JpaPlatformConfig> DEFAULT_FILTER = new DefaultFilter(); /* CU private */ static class DefaultFilter extends Filter.Adapter<JpaPlatformConfig> diff --git a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/ConnectionProfileAdapter.java b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/ConnectionProfileAdapter.java index ecf4a98e1e..0781cd8d9f 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/ConnectionProfileAdapter.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/ConnectionProfileAdapter.java @@ -9,6 +9,8 @@ ******************************************************************************/ package org.eclipse.jpt.jpa.db; +import org.eclipse.jpt.common.utility.internal.ObjectTools; + /** * An empty implementation of {@link ConnectionProfileListener}. * <p> @@ -32,4 +34,9 @@ public class ConnectionProfileAdapter public void connectionProfileRenamed(String oldName, String newName) { // do nothing } + + @Override + public String toString() { + return ObjectTools.toString(this); + } } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/DTPConnectionProfileFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/DTPConnectionProfileFactory.java index 3eae5ca0f1..4c681dae0f 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/DTPConnectionProfileFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/DTPConnectionProfileFactory.java @@ -24,44 +24,26 @@ import org.eclipse.jpt.jpa.db.ConnectionProfileListener; import org.eclipse.jpt.jpa.db.DatabaseIdentifierAdapter; /** - * Wrap the DTP {@link ProfileManager} in yet another singleton. + * Wrap the DTP {@link ProfileManager}. */ public final class DTPConnectionProfileFactory implements ConnectionProfileFactory { private final IWorkspace workspace; - private ProfileManager dtpProfileManager; + private final ProfileManager dtpProfileManager; - private LocalProfileListener profileListener; + private final LocalProfileListener profileListener; public DTPConnectionProfileFactory(IWorkspace workspace) { super(); this.workspace = workspace; - } - - - // ********** lifecycle ********** - - /** - * called by plug-in - */ - public synchronized void start() { this.dtpProfileManager = ProfileManager.getInstance(); - this.profileListener = new LocalProfileListener(); + this.profileListener = this.buildProfileListener(); this.dtpProfileManager.addProfileListener(this.profileListener); } - /** - * called by plug-in - */ - public synchronized void stop() { - this.dtpProfileManager.removeProfileListener(this.profileListener); - this.profileListener = null; - this.dtpProfileManager = null; - } - // ********** connection profiles ********** @@ -106,6 +88,10 @@ public final class DTPConnectionProfileFactory this.profileListener.removeConnectionProfileListener(listener); } + private LocalProfileListener buildProfileListener() { + return new LocalProfileListener(); + } + // ********** misc ********** @@ -117,6 +103,13 @@ public final class DTPConnectionProfileFactory return new DriverClasspathContainer(driverName); } + /** + * @see org.eclipse.jpt.jpa.db.internal.plugin.JptJpaDbPlugin#stop(org.osgi.framework.BundleContext) + */ + public void dispose() { + this.dtpProfileManager.removeProfileListener(this.profileListener); + } + @Override public String toString() { return this.getClass().getSimpleName(); diff --git a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/plugin/JptJpaDbPlugin.java b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/plugin/JptJpaDbPlugin.java index 7f32f7d3ef..29ed79d2bc 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/plugin/JptJpaDbPlugin.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/plugin/JptJpaDbPlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2012 Oracle. All rights reserved. + * Copyright (c) 2006, 2013 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. @@ -13,6 +13,7 @@ import java.util.Hashtable; import org.eclipse.core.resources.IWorkspace; import org.eclipse.jpt.common.core.internal.utility.JptPlugin; import org.eclipse.jpt.jpa.db.internal.DTPConnectionProfileFactory; +import org.osgi.framework.BundleContext; public class JptJpaDbPlugin extends JptPlugin @@ -44,29 +45,42 @@ public class JptJpaDbPlugin } @Override - protected void stop_() throws Exception { + public void stop(BundleContext context) throws Exception { try { - for (DTPConnectionProfileFactory factory : this.connectionProfileFactories.values()) { - try { - factory.stop(); - } catch (Throwable ex) { - this.logError(ex); // keep going - } - } - this.connectionProfileFactories.clear(); + this.disposeConnectionProfileFactories(); } finally { - super.stop_(); + super.stop(context); } } // ********** connection profile factories ********** - public synchronized DTPConnectionProfileFactory getConnectionProfileFactory(IWorkspace workspace) { + /** + * Return the connection profile factory corresponding to the specified + * Eclipse workspace. + * <p> + * The preferred way to retrieve a connection profile factory is via the + * Eclipse adapter framework: + * <pre> + * IWorkspace workspace = ...; + * ConnectionProfileFactory factory = (ConnectionProfileFactory) workspace.getAdapter(ConnectionProfileFactory.class) + * </pre> + * @see org.eclipse.jpt.jpa.db.internal.WorkspaceAdapterFactory#getConnectionProfileFactory(IWorkspace) + */ + public DTPConnectionProfileFactory getConnectionProfileFactory(IWorkspace workspace) { + synchronized (this.connectionProfileFactories) { + return this.getConnectionProfileFactory_(workspace); + } + } + + /** + * Pre-condition: {@link #connectionProfileFactories} is <code>synchronized</code> + */ + private DTPConnectionProfileFactory getConnectionProfileFactory_(IWorkspace workspace) { DTPConnectionProfileFactory factory = this.connectionProfileFactories.get(workspace); - if (this.isActive() && (factory == null)) { + if ((factory == null) && this.isActive()) { // no new factories can be built during "start" or "stop"... factory = this.buildConnectionProfileFactory(workspace); - factory.start(); this.connectionProfileFactories.put(workspace, factory); } return factory; @@ -75,4 +89,16 @@ public class JptJpaDbPlugin private DTPConnectionProfileFactory buildConnectionProfileFactory(IWorkspace workspace) { return new DTPConnectionProfileFactory(workspace); } + + private void disposeConnectionProfileFactories() { + // the list will not change during "stop" + for (DTPConnectionProfileFactory factory : this.connectionProfileFactories.values()) { + try { + factory.dispose(); + } catch (Throwable ex) { + this.logError(ex); // keep going + } + } + this.connectionProfileFactories.clear(); + } } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink1_1JpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink1_1JpaPlatformFactory.java index 8e71769ef7..0d529e0491 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink1_1JpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink1_1JpaPlatformFactory.java @@ -19,6 +19,7 @@ import org.eclipse.jpt.jpa.core.context.AccessType; import org.eclipse.jpt.jpa.core.internal.GenericJpaAnnotationDefinitionProvider; import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatform; import org.eclipse.jpt.jpa.core.internal.JpaAnnotationProvider; +import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; import org.eclipse.jpt.jpa.eclipselink.core.internal.EclipseLinkJpaPlatformFactory.EclipseLinkJpaPlatformVersion; import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkJPQLGrammar1; @@ -41,9 +42,9 @@ public class EclipseLink1_1JpaPlatformFactory super(); } - public JpaPlatform buildJpaPlatform(String id) { + public JpaPlatform buildJpaPlatform(JpaPlatformConfig config) { return new GenericJpaPlatform( - id, + config, buildJpaVersion(), new EclipseLinkJpaFactory(), buildAnnotationProvider(), diff --git a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink1_2JpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink1_2JpaPlatformFactory.java index 764d1dde05..fd79b0d469 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink1_2JpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink1_2JpaPlatformFactory.java @@ -19,6 +19,7 @@ import org.eclipse.jpt.jpa.core.context.AccessType; import org.eclipse.jpt.jpa.core.internal.GenericJpaAnnotationDefinitionProvider; import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatform; import org.eclipse.jpt.jpa.core.internal.JpaAnnotationProvider; +import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; import org.eclipse.jpt.jpa.eclipselink.core.internal.EclipseLinkJpaPlatformFactory.EclipseLinkJpaPlatformVersion; import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkJPQLGrammar1; @@ -42,9 +43,9 @@ public class EclipseLink1_2JpaPlatformFactory super(); } - public JpaPlatform buildJpaPlatform(String id) { + public JpaPlatform buildJpaPlatform(JpaPlatformConfig config) { return new GenericJpaPlatform( - id, + config, buildJpaVersion(), new EclipseLinkJpaFactory(), buildAnnotationProvider(), diff --git a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_0JpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_0JpaPlatformFactory.java index a61a9d7d80..33da53f97e 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_0JpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_0JpaPlatformFactory.java @@ -19,6 +19,7 @@ import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatform; import org.eclipse.jpt.jpa.core.internal.JpaAnnotationProvider; import org.eclipse.jpt.jpa.core.internal.jpa2.Generic2_0JpaAnnotationDefinitionProvider; import org.eclipse.jpt.jpa.core.jpa2.JpaProject2_0; +import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; import org.eclipse.jpt.jpa.eclipselink.core.internal.EclipseLinkJpaPlatformFactory.EclipseLinkJpaPlatformVersion; import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkJPQLGrammar2_0; @@ -37,9 +38,9 @@ public class EclipseLink2_0JpaPlatformFactory super(); } - public JpaPlatform buildJpaPlatform(String id) { + public JpaPlatform buildJpaPlatform(JpaPlatformConfig config) { return new GenericJpaPlatform( - id, + config, buildJpaVersion(), new EclipseLink2_0JpaFactory(), this.buildAnnotationProvider(), diff --git a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_1JpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_1JpaPlatformFactory.java index a391f02bdf..2f8bb2d49d 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_1JpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_1JpaPlatformFactory.java @@ -19,6 +19,7 @@ import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatform; import org.eclipse.jpt.jpa.core.internal.JpaAnnotationProvider; import org.eclipse.jpt.jpa.core.internal.jpa2.Generic2_0JpaAnnotationDefinitionProvider; import org.eclipse.jpt.jpa.core.jpa2.JpaProject2_0; +import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; import org.eclipse.jpt.jpa.eclipselink.core.context.EclipseLinkAccessType; import org.eclipse.jpt.jpa.eclipselink.core.internal.EclipseLinkJpaPlatformFactory.EclipseLinkJpaPlatformVersion; import org.eclipse.jpt.jpa.eclipselink.core.internal.context.orm.EclipseLinkOrmXml2_1Definition; @@ -39,9 +40,9 @@ public class EclipseLink2_1JpaPlatformFactory super(); } - public JpaPlatform buildJpaPlatform(String id) { + public JpaPlatform buildJpaPlatform(JpaPlatformConfig config) { return new GenericJpaPlatform( - id, + config, buildJpaVersion(), new EclipseLink2_0JpaFactory(), this.buildAnnotationProvider(), diff --git a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_2JpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_2JpaPlatformFactory.java index 51999a4bce..4bad334e5b 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_2JpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_2JpaPlatformFactory.java @@ -19,6 +19,7 @@ import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatform; import org.eclipse.jpt.jpa.core.internal.JpaAnnotationProvider; import org.eclipse.jpt.jpa.core.internal.jpa2.Generic2_0JpaAnnotationDefinitionProvider; import org.eclipse.jpt.jpa.core.jpa2.JpaProject2_0; +import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; import org.eclipse.jpt.jpa.eclipselink.core.internal.EclipseLinkJpaPlatformFactory.EclipseLinkJpaPlatformVersion; import org.eclipse.jpt.jpa.eclipselink.core.internal.context.orm.EclipseLinkOrmXml2_1Definition; import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkJPQLGrammar2_2; @@ -38,9 +39,9 @@ public class EclipseLink2_2JpaPlatformFactory super(); } - public JpaPlatform buildJpaPlatform(String id) { + public JpaPlatform buildJpaPlatform(JpaPlatformConfig config) { return new GenericJpaPlatform( - id, + config, buildJpaVersion(), new EclipseLink2_0JpaFactory(), this.buildAnnotationProvider(), diff --git a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_3JpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_3JpaPlatformFactory.java index 739174e0ed..f2871448f4 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_3JpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_3JpaPlatformFactory.java @@ -19,6 +19,7 @@ import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatform; import org.eclipse.jpt.jpa.core.internal.JpaAnnotationProvider; import org.eclipse.jpt.jpa.core.internal.jpa2.Generic2_0JpaAnnotationDefinitionProvider; import org.eclipse.jpt.jpa.core.jpa2.JpaProject2_0; +import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; import org.eclipse.jpt.jpa.eclipselink.core.internal.EclipseLinkJpaPlatformFactory.EclipseLinkJpaPlatformVersion; import org.eclipse.jpt.jpa.eclipselink.core.internal.context.orm.EclipseLinkOrmXml2_1Definition; import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkJPQLGrammar2_3; @@ -38,9 +39,9 @@ public class EclipseLink2_3JpaPlatformFactory super(); } - public JpaPlatform buildJpaPlatform(String id) { + public JpaPlatform buildJpaPlatform(JpaPlatformConfig config) { return new GenericJpaPlatform( - id, + config, buildJpaVersion(), new EclipseLink2_0JpaFactory(), buildAnnotationProvider(), diff --git a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_4JpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_4JpaPlatformFactory.java index a9022fcc93..22226fdecd 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_4JpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_4JpaPlatformFactory.java @@ -19,6 +19,7 @@ import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatform; import org.eclipse.jpt.jpa.core.internal.JpaAnnotationProvider; import org.eclipse.jpt.jpa.core.internal.jpa2.Generic2_0JpaAnnotationDefinitionProvider; import org.eclipse.jpt.jpa.core.jpa2.JpaProject2_0; +import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; import org.eclipse.jpt.jpa.eclipselink.core.internal.EclipseLinkJpaPlatformFactory.EclipseLinkJpaPlatformVersion; import org.eclipse.jpt.jpa.eclipselink.core.internal.context.orm.EclipseLinkOrmXml2_1Definition; import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkJPQLGrammar2_4; @@ -38,9 +39,9 @@ public class EclipseLink2_4JpaPlatformFactory super(); } - public JpaPlatform buildJpaPlatform(String id) { + public JpaPlatform buildJpaPlatform(JpaPlatformConfig config) { return new GenericJpaPlatform( - id, + config, buildJpaVersion(), new EclipseLink2_4JpaFactory(), buildAnnotationProvider(), diff --git a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_5JpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_5JpaPlatformFactory.java index fc712cb596..133205ad83 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_5JpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLink2_5JpaPlatformFactory.java @@ -19,6 +19,7 @@ import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatform; import org.eclipse.jpt.jpa.core.internal.JpaAnnotationProvider; import org.eclipse.jpt.jpa.core.internal.jpa2_1.Generic2_1JpaAnnotationDefinitionProvider; import org.eclipse.jpt.jpa.core.jpa2_1.JpaProject2_1; +import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; import org.eclipse.jpt.jpa.eclipselink.core.internal.EclipseLinkJpaPlatformFactory.EclipseLinkJpaPlatformVersion; import org.eclipse.jpt.jpa.eclipselink.core.internal.context.orm.EclipseLinkOrmXml2_1Definition; import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkJPQLGrammar2_5; @@ -38,9 +39,9 @@ public class EclipseLink2_5JpaPlatformFactory super(); } - public JpaPlatform buildJpaPlatform(String id) { + public JpaPlatform buildJpaPlatform(JpaPlatformConfig config) { return new GenericJpaPlatform( - id, + config, buildJpaVersion(), new EclipseLink2_4JpaFactory(), buildAnnotationProvider(), diff --git a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLinkJpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLinkJpaPlatformFactory.java index 2cd13e5ceb..0af84f8254 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLinkJpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLinkJpaPlatformFactory.java @@ -21,6 +21,7 @@ import org.eclipse.jpt.jpa.core.internal.GenericJpaAnnotationDefinitionProvider; import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatform; import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatformFactory.GenericJpaPlatformVersion; import org.eclipse.jpt.jpa.core.internal.JpaAnnotationProvider; +import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkJPQLGrammar1; /** @@ -43,9 +44,9 @@ public class EclipseLinkJpaPlatformFactory super(); } - public JpaPlatform buildJpaPlatform(String id) { + public JpaPlatform buildJpaPlatform(JpaPlatformConfig config) { return new GenericJpaPlatform( - id, + config, buildJpaVersion(), new EclipseLinkJpaFactory(), buildAnnotationProvider(), diff --git a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.ui/src/org/eclipse/jpt/jpa/eclipselink/ui/internal/persistence/connection/JdbcConnectionPropertiesComposite.java b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.ui/src/org/eclipse/jpt/jpa/eclipselink/ui/internal/persistence/connection/JdbcConnectionPropertiesComposite.java index 7e6f841980..a87fce1de7 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.ui/src/org/eclipse/jpt/jpa/eclipselink/ui/internal/persistence/connection/JdbcConnectionPropertiesComposite.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.ui/src/org/eclipse/jpt/jpa/eclipselink/ui/internal/persistence/connection/JdbcConnectionPropertiesComposite.java @@ -60,10 +60,10 @@ public class JdbcConnectionPropertiesComposite<T extends Connection> private static final String DIALOG_SETTINGS = "org.eclipse.jpt.jpa.eclipselink.ui.dialogs.ConnectionDialog"; public JdbcConnectionPropertiesComposite( - Pane<T> parentComposite, - Composite parent) { - - super(parentComposite, parent); + Pane<T> parent, + Composite parentComposite + ) { + super(parent, parentComposite); } private ModifiablePropertyValueModel<String> buildPasswordHolder() { diff --git a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/InternalJpaWorkbench.java b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/InternalJpaWorkbench.java index 473d50632c..5e338214dd 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/InternalJpaWorkbench.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/InternalJpaWorkbench.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Oracle. All rights reserved. + * Copyright (c) 2012, 2013 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. @@ -26,10 +26,9 @@ public class InternalJpaWorkbench { private final IWorkbench workbench; - // NB: the JPA workbench must be synchronized whenever accessing any of this state - private InternalJpaPlatformUiManager jpaPlatformUiManager; - private JpaSelectionManager jpaSelectionManager; - private ResourceManager resourceManager; + private final InternalJpaPlatformUiManager jpaPlatformUiManager; + private volatile JpaSelectionManager jpaSelectionManager; + private final ResourceManager resourceManager; /** @@ -39,19 +38,14 @@ public class InternalJpaWorkbench public InternalJpaWorkbench(IWorkbench workbench) { super(); this.workbench = workbench; - } - - public IWorkbench getWorkbench() { - return this.workbench; + this.jpaPlatformUiManager = this.buildJpaPlatformUiManager(); + this.resourceManager = this.buildResourceManager(); } // ********** JPA platform UI manager ********** - public synchronized InternalJpaPlatformUiManager getJpaPlatformUiManager() { - if ((this.jpaPlatformUiManager == null) && this.isActive()) { - this.jpaPlatformUiManager = this.buildJpaPlatformUiManager(); - } + public InternalJpaPlatformUiManager getJpaPlatformUiManager() { return this.jpaPlatformUiManager; } @@ -62,7 +56,7 @@ public class InternalJpaWorkbench // ********** JPA selection manager ********** - public synchronized JpaSelectionManager getJpaSelectionManager() { + public JpaSelectionManager getJpaSelectionManager() { return this.jpaSelectionManager; } @@ -72,7 +66,7 @@ public class InternalJpaWorkbench * @see org.eclipse.jpt.jpa.ui.internal.selection.JpaWorkbenchSelectionManager#dispose() * @see org.eclipse.jpt.jpa.ui.internal.selection.JpaWorkbenchSelectionManager#forWorkbench_(IWorkbench) */ - public synchronized void setJpaSelectionManager(JpaSelectionManager jpaSelectionManager) { + public void setJpaSelectionManager(JpaSelectionManager jpaSelectionManager) { this.jpaSelectionManager = jpaSelectionManager; } @@ -80,8 +74,7 @@ public class InternalJpaWorkbench // ********** resource manager ********** public ResourceManager buildLocalResourceManager() { - ResourceManager rm = this.getResourceManager(); - return (rm == null) ? null : new LocalResourceManager(rm); + return new LocalResourceManager(this.resourceManager); } /** @@ -92,24 +85,13 @@ public class InternalJpaWorkbench public synchronized ResourceManager getResourceManager(Control control) { ResourceManager controlRM = (ResourceManager) control.getData(RESOURCE_MANAGER_KEY); if (controlRM == null) { - ResourceManager rm = this.getResourceManager(); - if (rm == null) { - return null; - } - controlRM = new LocalResourceManager(rm, control); + controlRM = new LocalResourceManager(this.resourceManager, control); control.setData(RESOURCE_MANAGER_KEY, controlRM); } return controlRM; } private static final String RESOURCE_MANAGER_KEY = JptJpaUiPlugin.instance().getPluginID() + ".ResourceManager"; //$NON-NLS-1$ - private synchronized ResourceManager getResourceManager() { - if ((this.resourceManager == null) && this.isActive()) { - this.resourceManager = this.buildResourceManager(); - } - return this.resourceManager; - } - private ResourceManager buildResourceManager() { return new LocalResourceManager(this.getParentResourceManager()); } @@ -125,22 +107,17 @@ public class InternalJpaWorkbench // ********** misc ********** - private boolean isActive() { - return JptJpaUiPlugin.instance().isActive(); + public IWorkbench getWorkbench() { + return this.workbench; } /** * Internal: Called <em>only</em> by the - * {@link JptJpaUiPlugin#stop_() Dali plug-in}. + * {@link JptJpaUiPlugin#stop(org.osgi.framework.BundleContext) + * Dali JPA UI plug-in}. */ - public synchronized void stop() { - if (this.resourceManager != null) { - this.resourceManager.dispose(); - this.resourceManager = null; - } - if (this.jpaPlatformUiManager != null) { - this.jpaPlatformUiManager = null; - } + public void dispose() { + this.resourceManager.dispose(); } @Override diff --git a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/ProjectAdapterFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/ProjectAdapterFactory.java index 8375e26a0d..9008aea553 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/ProjectAdapterFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/ProjectAdapterFactory.java @@ -112,6 +112,7 @@ public class ProjectAdapterFactory /* class private */ static class Predicate extends SimpleFilter<JpaProject, IProject> { + private static final long serialVersionUID = 1L; Predicate(IProject project) { super(project); } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/plugin/JptJpaUiPlugin.java b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/plugin/JptJpaUiPlugin.java index d8e620745d..17fcd52f02 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/plugin/JptJpaUiPlugin.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/plugin/JptJpaUiPlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2012 Oracle. All rights reserved. + * Copyright (c) 2006, 2013 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. @@ -9,7 +9,7 @@ ******************************************************************************/ package org.eclipse.jpt.jpa.ui.internal.plugin; -import java.util.HashMap; +import java.util.Hashtable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.jpt.common.core.internal.utility.JptPlugin; import org.eclipse.jpt.common.ui.internal.JptUIPlugin; @@ -25,6 +25,7 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.IWorkbench; +import org.osgi.framework.BundleContext; /** * Dali JPA UI plug-in. @@ -32,15 +33,14 @@ import org.eclipse.ui.IWorkbench; public class JptJpaUiPlugin extends JptUIPlugin { - // NB: the plug-in must be synchronized whenever accessing any of this state - private final HashMap<IWorkbench, InternalJpaWorkbench> jpaWorkbenchs = new HashMap<IWorkbench, InternalJpaWorkbench>(); + private final Hashtable<IWorkbench, InternalJpaWorkbench> jpaWorkbenches = new Hashtable<IWorkbench, InternalJpaWorkbench>(); /** * @see #focusIn(Control) */ private final ControlIsNonDaliListenerFlag controlIsNonDaliFlag = new ControlIsNonDaliListenerFlag(); private final AsyncEventListenerFlag asyncEventListenerFlag = new AsyncEventListenerFlag(this.controlIsNonDaliFlag); - private Display display; + private volatile Display display; private final Listener focusListener = new FocusListener(); @@ -72,8 +72,8 @@ public class JptJpaUiPlugin * of every "focus in" event. */ @Override - public void start_() throws Exception { - super.start_(); + public void start(BundleContext context) throws Exception { + super.start(context); // no leak here - the flag has no backpointer to the plug-in this.getJpaProjectManager().addJavaEventListenerFlag(this.asyncEventListenerFlag); @@ -99,17 +99,9 @@ public class JptJpaUiPlugin * Unregister our SWT listener with the display. */ @Override - public void stop_() throws Exception { + public void stop(BundleContext context) throws Exception { try { - for (InternalJpaWorkbench jpaWorkbench : this.jpaWorkbenchs.values()) { - try { - jpaWorkbench.stop(); - } catch (Throwable ex) { - this.logError(ex); // keep going - } - } - this.jpaWorkbenchs.clear(); - + this.disposeJpaWorkbenches(); // must be on UI thread... if ((this.display != null) && ( ! this.display.isDisposed())) { this.display.removeFilter(SWT.FocusIn, this.focusListener); @@ -117,12 +109,12 @@ public class JptJpaUiPlugin this.getJpaProjectManager().removeJavaEventListenerFlag(this.asyncEventListenerFlag); } finally { this.display = null; - super.stop_(); + super.stop(context); } } - // ********** JPA workbenchs ********** + // ********** JPA workbenches ********** /** * Return the JPA workbench corresponding to the specified Eclipse workbench. @@ -130,15 +122,25 @@ public class JptJpaUiPlugin * The preferred way to retrieve a JPA workbench is via the Eclipse * adapter framework: * <pre> - * JpaWorkbench jpaWorkbench = PlatformTools.getAdapter(PlatformUI.getWorkbench(), JpaWorkbench.class); + * IWorkbench workbench = ...; + * JpaWorkbench jpaWorkbench = PlatformTools.getAdapter(workbench, JpaWorkbench.class); * </pre> * @see org.eclipse.jpt.jpa.ui.internal.WorkbenchAdapterFactory#getJpaWorkbench(IWorkbench) */ - public synchronized InternalJpaWorkbench getJpaWorkbench(IWorkbench workbench) { - InternalJpaWorkbench jpaWorkbench = this.jpaWorkbenchs.get(workbench); - if ((jpaWorkbench == null) && this.isActive()) { + public InternalJpaWorkbench getJpaWorkbench(IWorkbench workbench) { + synchronized (this.jpaWorkbenches) { + return this.getJpaWorkbench_(workbench); + } + } + + /** + * Pre-condition: {@link #jpaWorkbenches} is <code>synchronized</code> + */ + private InternalJpaWorkbench getJpaWorkbench_(IWorkbench workbench) { + InternalJpaWorkbench jpaWorkbench = this.jpaWorkbenches.get(workbench); + if ((jpaWorkbench == null) && this.isActive()) { // no new workbenches can be built during "start" or "stop"... jpaWorkbench = this.buildJpaWorkbench(workbench); - this.jpaWorkbenchs.put(workbench, jpaWorkbench); + this.jpaWorkbenches.put(workbench, jpaWorkbench); } return jpaWorkbench; } @@ -147,6 +149,18 @@ public class JptJpaUiPlugin return new InternalJpaWorkbench(workbench); } + private void disposeJpaWorkbenches() { + // the list will not change during "stop" + for (InternalJpaWorkbench jpaWorkbench : this.jpaWorkbenches.values()) { + try { + jpaWorkbench.dispose(); + } catch (Throwable ex) { + this.logError(ex); // keep going + } + } + this.jpaWorkbenches.clear(); + } + // ********** focus listener ********** @@ -273,7 +287,7 @@ public class JptJpaUiPlugin } } - // ********** control is non dali listener listener flag ********** + // ********** control is non-Dali listener flag ********** /** * This flag's value is determined by the current UI focus (i.e. whether the diff --git a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/properties/JpaProjectPropertiesPage.java b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/properties/JpaProjectPropertiesPage.java index ce06715dea..7d54bd7585 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/properties/JpaProjectPropertiesPage.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/properties/JpaProjectPropertiesPage.java @@ -66,6 +66,7 @@ import org.eclipse.jpt.common.utility.model.value.ModifiablePropertyValueModel; import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; import org.eclipse.jpt.common.utility.transformer.Transformer; import org.eclipse.jpt.jpa.core.JpaDataSource; +import org.eclipse.jpt.jpa.core.JpaPlatform; import org.eclipse.jpt.jpa.core.JpaPreferences; import org.eclipse.jpt.jpa.core.JpaProject; import org.eclipse.jpt.jpa.core.JpaWorkspace; @@ -79,6 +80,7 @@ import org.eclipse.jpt.jpa.db.Catalog; import org.eclipse.jpt.jpa.db.ConnectionAdapter; import org.eclipse.jpt.jpa.db.ConnectionListener; import org.eclipse.jpt.jpa.db.ConnectionProfile; +import org.eclipse.jpt.jpa.db.ConnectionProfileAdapter; import org.eclipse.jpt.jpa.db.ConnectionProfileFactory; import org.eclipse.jpt.jpa.db.ConnectionProfileListener; import org.eclipse.jpt.jpa.db.Database; @@ -443,6 +445,10 @@ public class JpaProjectPropertiesPage return null; } + public JpaPlatform getJpaPlatform() { + return null; + } + public boolean supportsJpaFacetVersion(IProjectFacetVersion jpaFacetVersion) { return false; } @@ -1097,14 +1103,19 @@ public class JpaProjectPropertiesPage } /* class private */ class LocalConnectionProfileListener - implements ConnectionProfileListener + extends ConnectionProfileAdapter { + @Override public void connectionProfileAdded(String name) { ConnectionChoicesModel.this.collectionChanged(); } + + @Override public void connectionProfileRemoved(String name) { ConnectionChoicesModel.this.collectionChanged(); } + + @Override public void connectionProfileRenamed(String oldName, String newName) { // Ignore this event for now. Connecting a profile actually // throws a connection renamed event, which messes up the diff --git a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/selection/JpaWorkbenchSelectionManager.java b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/selection/JpaWorkbenchSelectionManager.java index 769a331bc8..1200314398 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/selection/JpaWorkbenchSelectionManager.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/selection/JpaWorkbenchSelectionManager.java @@ -145,7 +145,7 @@ class JpaWorkbenchSelectionManager } /** - * <strong>NB:</strong> May trigger construction of workbench manager. + * <strong>NB:</strong> May trigger construction of workbench selection manager. */ static JpaWorkbenchSelectionManager forWorkbench_(IWorkbench workbench) { InternalJpaWorkbench jpaWorkbench = getJpaWorkbench(workbench); diff --git a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/wizards/gen/DatabaseGroup.java b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/wizards/gen/DatabaseGroup.java index 6876ef6c63..1e9bb0b9b0 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/wizards/gen/DatabaseGroup.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/wizards/gen/DatabaseGroup.java @@ -17,7 +17,6 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.SortedSet; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.resource.ResourceManager; @@ -262,7 +261,7 @@ public class DatabaseGroup } private ConnectionProfileFactory getConnectionProfileFactory() { - return (ConnectionProfileFactory) ResourcesPlugin.getWorkspace().getAdapter(ConnectionProfileFactory.class); + return (ConnectionProfileFactory) this.jpaProject.getProject().getWorkspace().getAdapter(ConnectionProfileFactory.class); } diff --git a/jpa/tests/org.eclipse.jpt.jpa.core.tests.extension.resource/src/org/eclipse/jpt/jpa/core/tests/extension/resource/TestJpaPlatformFactory.java b/jpa/tests/org.eclipse.jpt.jpa.core.tests.extension.resource/src/org/eclipse/jpt/jpa/core/tests/extension/resource/TestJpaPlatformFactory.java index e7a29f6be2..42cb1beb63 100644 --- a/jpa/tests/org.eclipse.jpt.jpa.core.tests.extension.resource/src/org/eclipse/jpt/jpa/core/tests/extension/resource/TestJpaPlatformFactory.java +++ b/jpa/tests/org.eclipse.jpt.jpa.core.tests.extension.resource/src/org/eclipse/jpt/jpa/core/tests/extension/resource/TestJpaPlatformFactory.java @@ -19,6 +19,7 @@ import org.eclipse.jpt.jpa.core.internal.GenericJpaAnnotationDefinitionProvider; import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatform; import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatformFactory.GenericJpaPlatformVersion; import org.eclipse.jpt.jpa.core.internal.JpaAnnotationProvider; +import org.eclipse.jpt.jpa.core.platform.JpaPlatformConfig; import org.eclipse.persistence.jpa.jpql.parser.DefaultJPQLGrammar; /** @@ -36,9 +37,9 @@ public class TestJpaPlatformFactory super(); } - public JpaPlatform buildJpaPlatform(String id) { + public JpaPlatform buildJpaPlatform(JpaPlatformConfig config) { return new GenericJpaPlatform( - id, + config, buildJpaVersion(), new TestJpaFactory(), new JpaAnnotationProvider(GenericJpaAnnotationDefinitionProvider.instance()), diff --git a/jpa/tests/org.eclipse.jpt.jpa.core.tests/src/org/eclipse/jpt/jpa/core/tests/internal/plugin/JptJpaCoreTestsPlugin.java b/jpa/tests/org.eclipse.jpt.jpa.core.tests/src/org/eclipse/jpt/jpa/core/tests/internal/plugin/JptJpaCoreTestsPlugin.java index ea59f4a77b..720c2086bf 100644 --- a/jpa/tests/org.eclipse.jpt.jpa.core.tests/src/org/eclipse/jpt/jpa/core/tests/internal/plugin/JptJpaCoreTestsPlugin.java +++ b/jpa/tests/org.eclipse.jpt.jpa.core.tests/src/org/eclipse/jpt/jpa/core/tests/internal/plugin/JptJpaCoreTestsPlugin.java @@ -13,6 +13,7 @@ import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.jpt.common.core.internal.utility.JptPlugin;
import org.eclipse.jpt.common.utility.internal.ObjectTools;
import org.eclipse.jpt.jpa.core.JpaProjectManager;
+import org.osgi.framework.BundleContext;
/**
* Configure the core for testing:<ul>
@@ -40,8 +41,8 @@ public class JptJpaCoreTestsPlugin }
@Override
- protected void start_() throws Exception {
- super.start_();
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
JpaProjectManager jpaProjectManager = this.getJpaProjectManager();
ObjectTools.execute(jpaProjectManager, "executeCommandsSynchronously");
JptPlugin.FlushPreferences = false;
diff --git a/jpa/tests/org.eclipse.jpt.jpa.db.tests/src/org/eclipse/jpt/jpa/db/tests/internal/platforms/DTPPlatformTests.java b/jpa/tests/org.eclipse.jpt.jpa.db.tests/src/org/eclipse/jpt/jpa/db/tests/internal/platforms/DTPPlatformTests.java index af9c416f8d..7bb4711ff2 100644 --- a/jpa/tests/org.eclipse.jpt.jpa.db.tests/src/org/eclipse/jpt/jpa/db/tests/internal/platforms/DTPPlatformTests.java +++ b/jpa/tests/org.eclipse.jpt.jpa.db.tests/src/org/eclipse/jpt/jpa/db/tests/internal/platforms/DTPPlatformTests.java @@ -54,8 +54,8 @@ import org.eclipse.jpt.jpa.db.Catalog; import org.eclipse.jpt.jpa.db.Column; import org.eclipse.jpt.jpa.db.ConnectionListener; import org.eclipse.jpt.jpa.db.ConnectionProfile; +import org.eclipse.jpt.jpa.db.ConnectionProfileAdapter; import org.eclipse.jpt.jpa.db.ConnectionProfileFactory; -import org.eclipse.jpt.jpa.db.ConnectionProfileListener; import org.eclipse.jpt.jpa.db.Database; import org.eclipse.jpt.jpa.db.DatabaseIdentifierAdapter; import org.eclipse.jpt.jpa.db.DatabaseObject; @@ -722,6 +722,7 @@ public abstract class DTPPlatformTests extends TestCase { this.dumpOn(sql, pw, columnWidth); } pw.flush(); + pw.close(); } protected void dumpOn(String sql, IndentingPrintWriter pw, int columnWidth) throws Exception { @@ -813,6 +814,7 @@ public abstract class DTPPlatformTests extends TestCase { this.dumpDatabaseOn(pw, deep); } pw.flush(); + pw.close(); } protected void dumpDatabaseOn(IndentingPrintWriter pw, boolean deep) { @@ -853,6 +855,7 @@ public abstract class DTPPlatformTests extends TestCase { this.dumpSchemaOn(schema, pw, deep); } pw.flush(); + pw.close(); } protected void dumpSchemaOn(Schema schema, IndentingPrintWriter pw, boolean deep) { @@ -928,6 +931,7 @@ public abstract class DTPPlatformTests extends TestCase { this.dumpJDBCCatalogsOn(pw); } pw.flush(); + pw.close(); } protected void dumpJDBCCatalogsOn(IndentingPrintWriter pw) throws SQLException { @@ -948,6 +952,7 @@ public abstract class DTPPlatformTests extends TestCase { this.dumpJDBCSchemataOn(pw); } pw.flush(); + pw.close(); } protected void dumpJDBCSchemataOn(IndentingPrintWriter pw) throws SQLException { @@ -969,18 +974,23 @@ public abstract class DTPPlatformTests extends TestCase { // ********** connection profile listener ********** - protected static class TestConnectionProfileListener implements ConnectionProfileListener { + protected static class TestConnectionProfileListener + extends ConnectionProfileAdapter + { public String addedName; public String removedName; public String renamedOldName; public String renamedNewName; + @Override public void connectionProfileAdded(String name) { this.addedName = name; } + @Override public void connectionProfileRemoved(String name) { this.removedName = name; } + @Override public void connectionProfileRenamed(String oldName, String newName) { this.renamedOldName = oldName; this.renamedNewName = newName; diff --git a/jpa/tests/org.eclipse.jpt.jpa.eclipselink.core.tests/src/org/eclipse/jpt/jpa/eclipselink/core/tests/internal/plugin/JptJpaEclipseLinkCoreTestsPlugin.java b/jpa/tests/org.eclipse.jpt.jpa.eclipselink.core.tests/src/org/eclipse/jpt/jpa/eclipselink/core/tests/internal/plugin/JptJpaEclipseLinkCoreTestsPlugin.java index ad93244d89..06a78e1c53 100644 --- a/jpa/tests/org.eclipse.jpt.jpa.eclipselink.core.tests/src/org/eclipse/jpt/jpa/eclipselink/core/tests/internal/plugin/JptJpaEclipseLinkCoreTestsPlugin.java +++ b/jpa/tests/org.eclipse.jpt.jpa.eclipselink.core.tests/src/org/eclipse/jpt/jpa/eclipselink/core/tests/internal/plugin/JptJpaEclipseLinkCoreTestsPlugin.java @@ -10,6 +10,7 @@ package org.eclipse.jpt.jpa.eclipselink.core.tests.internal.plugin; import org.eclipse.jpt.common.core.internal.utility.JptPlugin; +import org.osgi.framework.BundleContext; /** * Configure the core for testing:<ul> @@ -45,8 +46,8 @@ public class JptJpaEclipseLinkCoreTestsPlugin } @Override - protected void start_() throws Exception { - super.start_(); + public void start(BundleContext context) throws Exception { + super.start(context); JptPlugin.FlushPreferences = false; } |