diff options
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse')
21 files changed, 322 insertions, 229 deletions
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> |