[209275] reworked JpaModel synchronization
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JpaModel.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JpaModel.java
index 43db7de..d7f3718 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JpaModel.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JpaModel.java
@@ -14,13 +14,31 @@
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jpt.core.internal.IJpaProject.Config;
+import org.eclipse.jpt.core.internal.content.orm.EntityMappingsInternal;
+import org.eclipse.jpt.core.internal.content.orm.OrmFactory;
+import org.eclipse.jpt.core.internal.content.orm.OrmResource;
+import org.eclipse.jpt.core.internal.content.orm.resource.OrmArtifactEdit;
+import org.eclipse.jpt.core.internal.content.persistence.Persistence;
+import org.eclipse.jpt.core.internal.content.persistence.PersistenceFactory;
+import org.eclipse.jpt.core.internal.content.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.internal.content.persistence.resource.PersistenceArtifactEdit;
+import org.eclipse.jpt.core.internal.content.persistence.resource.PersistenceResource;
+import org.eclipse.jpt.core.internal.facet.IJpaFacetDataModelProperties;
import org.eclipse.jpt.utility.internal.ClassTools;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.project.facet.core.events.IProjectFacetActionEvent;
/**
* The JPA model is synchronized so all changes to the list of JPA projects
@@ -30,24 +48,25 @@
* their associated JPA projects when necessary. Other than performance,
* this should be transparent to clients.
*/
-public class JpaModel extends AbstractModel implements IJpaModel {
+public class JpaModel
+ extends AbstractModel
+ implements IJpaModel
+{
/** maintain a list of all the current JPA projects */
- private ArrayList<IJpaProjectHolder> jpaProjectHolders = new ArrayList<IJpaProjectHolder>();
+ private final ArrayList<IJpaProjectHolder> jpaProjectHolders = new ArrayList<IJpaProjectHolder>();
// ********** constructor **********
/**
- * Construct a JPA model and populate it with JPA projects to be built
- * from the specified set of JPA project configs.
+ * Construct a JPA model and populate it with JPA projects for all the
+ * current Eclipse projects with JPA facets.
* The JPA model can only be instantiated by the JPA model manager.
*/
- JpaModel(Iterable<IJpaProject.Config> configs) {
+ JpaModel() throws CoreException {
super();
- for (IJpaProject.Config config : configs) {
- this.addJpaProject(config);
- }
+ ResourcesPlugin.getWorkspace().getRoot().accept(new ResourceProxyVisitor(), IResource.NONE);
}
@@ -88,11 +107,16 @@
return this.jpaProjectHolders.size();
}
+ /**
+ * This will trigger the instantiation of the JPA project associated with the
+ * specified file.
+ */
public synchronized IJpaFile jpaFile(IFile file) throws CoreException {
IJpaProject jpaProject = this.jpaProject(file.getProject());
return (jpaProject == null) ? null : jpaProject.jpaFile(file);
}
+
// ********** internal methods **********
/**
@@ -107,13 +131,26 @@
return NullJpaProjectHolder.instance();
}
+ private IJpaProject.Config buildJpaProjectConfig(IProject project) {
+ SimpleJpaProjectConfig config = new SimpleJpaProjectConfig();
+ config.setProject(project);
+ config.setJpaPlatform(JptCorePlugin.jpaPlatform(project));
+ config.setConnectionProfileName(JptCorePlugin.connectionProfileName(project));
+ config.setDiscoverAnnotatedClasses(JptCorePlugin.discoverAnnotatedClasses(project));
+ return config;
+ }
+
+ /* private */ void addJpaProject(IProject project) {
+ this.addJpaProject(this.buildJpaProjectConfig(project));
+ }
+
/**
* Add a JPA project to the JPA model for the specified Eclipse project.
* JPA projects can only be added by the JPA model manager.
* The JPA project will only be instantiated later, on demand.
*/
- synchronized void addJpaProject(IJpaProject.Config config) {
- dumpStackTrace(); // figure out exactly when JPA projects are built
+ private void addJpaProject(IJpaProject.Config config) {
+ dumpStackTrace(); // figure out exactly when JPA projects are added
this.jpaProjectHolders.add(this.jpaProjectHolder(config.project()).buildJpaProjectHolder(this, config));
}
@@ -122,49 +159,117 @@
* from the JPA model. Return whether the removal actually happened.
* JPA projects can only be removed by the JPA model manager.
*/
- synchronized boolean removeJpaProject(IProject project) {
+ private void removeJpaProject(IProject project) {
dumpStackTrace(); // figure out exactly when JPA projects are removed
- if (containsJpaProject(project)) {
- return this.jpaProjectHolder(project).remove();
- }
- return false;
+ this.jpaProjectHolder(project).remove();
}
+
+ // ********** Resource events **********
+
/**
- * Dispose the JPA model by disposing and removing all its JPA projects.
- * The JPA model can only be disposed by the JPA model manager.
+ * A project is being deleted. Remove its corresponding
+ * JPA project if appropriate.
*/
- synchronized void dispose() {
- // clone the list to prevent concurrent modification exceptions
- @SuppressWarnings("unchecked")
- ArrayList<IJpaProjectHolder> holders = (ArrayList<IJpaProjectHolder>) this.jpaProjectHolders.clone();
- for (IJpaProjectHolder holder : holders) {
- holder.remove();
- }
- }
-
- @Override
- public void toString(StringBuilder sb) {
- sb.append("JPA projects size: " + this.jpaProjectsSize());
- }
-
-
- // ********** events **********
-
- synchronized void synchronizeFiles(IProject project, IResourceDelta delta) throws CoreException {
- if (containsJpaProject(project)) {
- this.synchronizeJpaFiles(project, delta);
- }
+ synchronized void projectPreDelete(IProject project) {
+ this.removeJpaProject(project);
}
/**
* Forward the specified resource delta to the JPA project corresponding
* to the specified Eclipse project.
*/
- private void synchronizeJpaFiles(IProject project, IResourceDelta delta) throws CoreException {
+ synchronized void synchronizeFiles(IProject project, IResourceDelta delta) throws CoreException {
this.jpaProjectHolder(project).synchronizeJpaFiles(delta);
}
+
+ // ********** Resource and/or Facet events **********
+
+ /**
+ * Check whether the JPA facet has been added or removed.
+ */
+ synchronized void checkForTransition(IProject project) {
+ boolean jpaFacet = JptCorePlugin.projectHasJpaFacet(project);
+ boolean jpaProject = this.containsJpaProject(project);
+
+ if (jpaFacet) {
+ if ( ! jpaProject) { // JPA facet added
+ this.addJpaProject(project);
+ }
+ } else {
+ if (jpaProject) { // JPA facet removed
+ this.removeJpaProject(project);
+ }
+ }
+ }
+
+
+ // ********** Facet events **********
+
+ synchronized void jpaFacetedProjectPostInstall(IProjectFacetActionEvent event) {
+ IProject project = event.getProject().getProject();
+ IDataModel dataModel = (IDataModel) event.getActionConfig();
+
+ this.createPersistenceXml(project);
+
+ if (dataModel.getBooleanProperty(IJpaFacetDataModelProperties.CREATE_ORM_XML)) {
+ this.createOrmXml(project);
+ }
+
+ // assume(?) this is the first event to indicate we need to add the JPA project to the JPA model
+ this.addJpaProject(project);
+ }
+
+ private void createPersistenceXml(IProject project) {
+ PersistenceArtifactEdit pae =
+ PersistenceArtifactEdit.getArtifactEditForWrite(project);
+ PersistenceResource resource = pae.getPersistenceResource(JptCorePlugin.persistenceXmlDeploymentURI(project));
+
+ // 202811 - do not add content if it is already present
+ if (resource.getPersistence() == null) {
+ Persistence persistence = PersistenceFactory.eINSTANCE.createPersistence();
+ persistence.setVersion("1.0");
+ PersistenceUnit pUnit = PersistenceFactory.eINSTANCE.createPersistenceUnit();
+ pUnit.setName(project.getName());
+ persistence.getPersistenceUnits().add(pUnit);
+ this.resourceContents(resource).add(persistence);
+ pae.save(null);
+ }
+
+ pae.dispose();
+ }
+
+ @SuppressWarnings({ "restriction", "unchecked" })
+ private EList<EObject> resourceContents(PersistenceResource resource) {
+ return resource.getContents();
+ }
+
+ private void createOrmXml(IProject project) {
+ OrmArtifactEdit oae =
+ OrmArtifactEdit.getArtifactEditForWrite(project);
+ OrmResource resource = oae.getOrmResource(JptCorePlugin.ormXmlDeploymentURI(project));
+
+ // 202811 - do not add content if it is already present
+ if (resource.getEntityMappings() == null) {
+ EntityMappingsInternal entityMappings = OrmFactory.eINSTANCE.createEntityMappingsInternal();
+ entityMappings.setVersion("1.0");
+ resource.getContents().add(entityMappings);
+ oae.save(null);
+ }
+
+ oae.dispose();
+ }
+
+ // TODO remove classpath items? persistence.xml? orm.xml?
+ synchronized void jpaFacetedProjectPreUninstall(IProjectFacetActionEvent event) {
+ // assume(?) this is the first event to indicate we need to remove the JPA project to the JPA model
+ this.removeJpaProject(event.getProject().getProject());
+ }
+
+
+ // ********** Java events **********
+
/**
* Forward the Java element changed event to all the JPA projects
* because the event could affect multiple projects.
@@ -176,6 +281,37 @@
}
+ // ********** miscellaneous **********
+
+ /**
+ * The JPA settings associated with the specified Eclipse project
+ * have changed in such a way as to require the associated
+ * JPA project to be completely rebuilt
+ * (e.g. when the user changes a project's JPA platform).
+ */
+ synchronized void rebuildJpaProject(IProject project) {
+ this.removeJpaProject(project);
+ this.addJpaProject(project);
+ }
+
+ /**
+ * Dispose the JPA model by disposing and removing all its JPA projects.
+ * The JPA model can only be disposed by the JPA model manager.
+ */
+ synchronized void dispose() {
+ // clone the list to prevent concurrent modification exceptions
+ IJpaProjectHolder[] holders = this.jpaProjectHolders.toArray(new IJpaProjectHolder[this.jpaProjectHolders.size()]);
+ for (IJpaProjectHolder holder : holders) {
+ holder.remove();
+ }
+ }
+
+ @Override
+ public void toString(StringBuilder sb) {
+ sb.append("JPA projects size: " + this.jpaProjectsSize());
+ }
+
+
// ********** holder callbacks **********
/**
@@ -202,7 +338,7 @@
}
- // ********** JPA project holder **********
+ // ********** JPA project holders **********
private interface IJpaProjectHolder {
@@ -216,7 +352,7 @@
IJpaProjectHolder buildJpaProjectHolder(JpaModel jpaModel, IJpaProject.Config config);
- boolean remove();
+ void remove();
}
@@ -252,8 +388,8 @@
return new JpaProjectHolder(jpaModel, config);
}
- public boolean remove() {
- return false;
+ public void remove() {
+ // do nothing
}
@Override
@@ -309,13 +445,12 @@
throw new IllegalArgumentException(c.project().getName());
}
- public boolean remove() {
+ public void remove() {
this.jpaModel.removeJpaProjectHolder(this);
if (this.jpaProject != null) {
this.jpaModel.jpaProjectRemoved(this.jpaProject);
this.jpaProject.dispose();
}
- return true;
}
@Override
@@ -326,8 +461,50 @@
}
- // ********** debug **********
+ // ********** resource proxy visitor **********
+ /**
+ * Visit the workspace resource tree, adding a JPA project to the
+ * JPA model for each open Eclipse project that has a JPA facet.
+ */
+ private class ResourceProxyVisitor implements IResourceProxyVisitor {
+
+ ResourceProxyVisitor() {
+ super();
+ }
+
+ public boolean visit(IResourceProxy resourceProxy) throws CoreException {
+ switch (resourceProxy.getType()) {
+ case IResource.ROOT :
+ return true; // all projects are in the "root"
+ case IResource.PROJECT :
+ this.checkProject(resourceProxy);
+ return false; // no nested projects
+ default :
+ return false;
+ }
+ }
+
+ private void checkProject(IResourceProxy resourceProxy) {
+ if (resourceProxy.isAccessible()) { // the project exists and is open
+ IProject project = (IProject) resourceProxy.requestResource();
+ if (JptCorePlugin.projectHasJpaFacet(project)) {
+ JpaModel.this.addJpaProject(project);
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return StringTools.buildToStringFor(this);
+ }
+
+ }
+
+
+ // ********** DEBUG **********
+
+ // @see JpaModelTests#testDEBUG()
private static final boolean DEBUG = false;
private static void dumpStackTrace() {
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JpaModelManager.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JpaModelManager.java
index 4c8226f..f9ed33a 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JpaModelManager.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JpaModelManager.java
@@ -9,14 +9,12 @@
******************************************************************************/
package org.eclipse.jpt.core.internal;
-import java.util.ArrayList;
+import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IResourceProxy;
-import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
@@ -31,21 +29,9 @@
import org.eclipse.jdt.core.IOpenable;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jpt.core.internal.IJpaProject.Config;
-import org.eclipse.jpt.core.internal.content.orm.EntityMappingsInternal;
-import org.eclipse.jpt.core.internal.content.orm.OrmFactory;
-import org.eclipse.jpt.core.internal.content.orm.OrmResource;
-import org.eclipse.jpt.core.internal.content.orm.resource.OrmArtifactEdit;
-import org.eclipse.jpt.core.internal.content.persistence.Persistence;
-import org.eclipse.jpt.core.internal.content.persistence.PersistenceFactory;
-import org.eclipse.jpt.core.internal.content.persistence.PersistenceUnit;
-import org.eclipse.jpt.core.internal.content.persistence.resource.PersistenceArtifactEdit;
-import org.eclipse.jpt.core.internal.content.persistence.resource.PersistenceResource;
-import org.eclipse.jpt.core.internal.facet.IJpaFacetDataModelProperties;
import org.eclipse.jpt.core.internal.prefs.JpaPreferenceConstants;
import org.eclipse.jpt.utility.internal.BitTools;
import org.eclipse.jpt.utility.internal.StringTools;
-import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
@@ -55,10 +41,8 @@
* "Internal" global stuff.
* Provide access via a singleton.
* Hold and manage the JPA model (which holds all the JPA projects)
- * and the various global listeners.
- * All the methods that handle the events from the listeners are 'synchronized',
- * effectively single-threading them and forcing the events to be queued up
- * and handled one at a time. Hopefully we don't cause any deadlocks.
+ * and the various global listeners. We attempt to determine whether events
+ * are relevant before forwarding them to the JPA model.
*
* Various things that cause us to add or remove a JPA project:
* - Startup of the Dali plug-in will trigger all the JPA projects to be added
@@ -120,7 +104,7 @@
/**
* Return the singleton JPA model manager.
*/
- public static final synchronized JpaModelManager instance() {
+ public static JpaModelManager instance() {
return INSTANCE;
}
@@ -139,7 +123,7 @@
}
- // ********** life-cycle controlled by the plug-in **********
+ // ********** plug-in controlled life-cycle **********
/**
* internal - called by JptCorePlugin
@@ -147,7 +131,7 @@
public synchronized void start() throws Exception {
debug("*** START JPA model manager ***");
try {
- this.jpaModel = this.buildJpaModel();
+ this.jpaModel = new JpaModel();
ResourcesPlugin.getWorkspace().addResourceChangeListener(this.resourceChangeListener);
FacetedProjectFramework.addListener(this.facetedProjectListener, IFacetedProjectEvent.Type.values());
JavaCore.addElementChangedListener(this.javaElementChangeListener);
@@ -158,12 +142,6 @@
}
}
- private JpaModel buildJpaModel() throws CoreException {
- ResourceProxyVisitor visitor = new ResourceProxyVisitor(this.buildJpaProjectConfigBuilder());
- ResourcesPlugin.getWorkspace().getRoot().accept(visitor, IResource.NONE);
- return new JpaModel(visitor.jpaProjectConfigs());
- }
-
/**
* internal - called by JptCorePlugin
*/
@@ -197,13 +175,21 @@
}
/**
+ * Return the JPA file corresponding to the specified Eclipse file,
+ * or null if unable to associate the specified file with a JPA file.
+ */
+ public IJpaFile jpaFile(IFile file) throws CoreException {
+ return this.jpaModel.jpaFile(file);
+ }
+
+ /**
* The JPA settings associated with the specified Eclipse project
* have changed in such a way as to require the associated
- * JPA project to be completely rebuilt.
+ * JPA project to be completely rebuilt
+ * (e.g. when the user changes a project's JPA platform).
*/
- public synchronized void rebuildJpaProject(IProject project) {
- this.removeJpaProject(project);
- this.addJpaProject(project);
+ public void rebuildJpaProject(IProject project) {
+ this.jpaModel.rebuildJpaProject(project);
}
/**
@@ -228,121 +214,6 @@
}
- // ********** JPA project configs **********
-
- private ResourceProxyVisitor.JpaProjectConfigBuilder buildJpaProjectConfigBuilder() {
- return new ResourceProxyVisitor.JpaProjectConfigBuilder() {
- public Iterable<Config> buildJpaProjectConfigs(Iterable<IProject> jpaFacetedProjects) {
- return JpaModelManager.this.buildJpaProjectConfigs(jpaFacetedProjects);
- }
- };
- }
-
- /* private */ Iterable<IJpaProject.Config> buildJpaProjectConfigs(Iterable<IProject> jpaFacetedProjects) {
- ArrayList<IJpaProject.Config> configs = new ArrayList<IJpaProject.Config>();
- for (IProject project : jpaFacetedProjects) {
- configs.add(buildJpaProjectConfig(project));
- }
- return configs;
- }
-
- private IJpaProject.Config buildJpaProjectConfig(IProject project) {
- SimpleJpaProjectConfig config = new SimpleJpaProjectConfig();
- config.setProject(project);
- config.setJpaPlatform(JptCorePlugin.jpaPlatform(project));
- config.setConnectionProfileName(JptCorePlugin.connectionProfileName(project));
- config.setDiscoverAnnotatedClasses(JptCorePlugin.discoverAnnotatedClasses(project));
- return config;
- }
-
-
- // ********** resource proxy visitor **********
-
- /**
- * Visit the workspace resource tree, collecting open Eclipse projects
- * that have a JPA facet.
- */
- private static class ResourceProxyVisitor implements IResourceProxyVisitor {
- private final JpaProjectConfigBuilder builder;
- private final ArrayList<IProject> jpaFacetedProjects = new ArrayList<IProject>();
-
- ResourceProxyVisitor(JpaProjectConfigBuilder builder) {
- super();
- this.builder = builder;
- }
-
- public boolean visit(IResourceProxy resourceProxy) throws CoreException {
- switch (resourceProxy.getType()) {
- case IResource.ROOT :
- return true; // all projects are in the "root"
- case IResource.PROJECT :
- this.checkProject(resourceProxy);
- return false; // no nested projects
- default :
- return false;
- }
- }
-
- private void checkProject(IResourceProxy resourceProxy) {
- if (resourceProxy.isAccessible()) { // the project exists and is open
- IProject project = (IProject) resourceProxy.requestResource();
- if (JptCorePlugin.projectHasJpaFacet(project)) {
- this.jpaFacetedProjects.add(project);
- }
- }
- }
-
- Iterable<IJpaProject.Config> jpaProjectConfigs() {
- return this.builder.buildJpaProjectConfigs(this.jpaFacetedProjects);
- }
-
- @Override
- public String toString() {
- return StringTools.buildToStringFor(this);
- }
-
- // ********** member interface **********
- interface JpaProjectConfigBuilder {
- Iterable<IJpaProject.Config> buildJpaProjectConfigs(Iterable<IProject> jpaFacetedProjects);
- }
-
- }
-
-
- // ********** internal **********
-
- /**
- * Check whether the JPA facet has been added or removed.
- */
- private void checkForTransition(IProject project) {
- boolean jpaFacet = JptCorePlugin.projectHasJpaFacet(project);
- boolean jpaProject = this.jpaModel.containsJpaProject(project);
-
- if (jpaFacet) {
- if ( ! jpaProject) { // JPA facet added
- this.addJpaProject(project);
- }
- } else {
- if (jpaProject) { // JPA facet removed
- this.removeJpaProject(project);
- }
- }
- }
-
- private void addJpaProject(IProject project) {
- this.jpaModel.addJpaProject(this.buildJpaProjectConfig(project));
- }
-
- /**
- * Remove the JPA project corresponding to the specified Eclipse project.
- * Do nothing if there is no corresponding JPA project.
- */
- // TODO remove classpath items? persistence.xml? orm.xml?
- private void removeJpaProject(IProject project) {
- this.jpaModel.removeJpaProject(project);
- }
-
-
// ********** resource changed **********
/**
@@ -350,7 +221,6 @@
* - project close/delete
* - file add/remove
*/
- //not synchronized, synchronizing once we know we are going to access JpaModel
/* private */ void resourceChanged(IResourceChangeEvent event) {
if (! (event.getSource() instanceof IWorkspace)) {
return; // this probably shouldn't happen...
@@ -376,7 +246,7 @@
*/
private void resourcePreDelete(IResourceChangeEvent event) {
debug("Resource (Project) PRE_DELETE: " + event.getResource());
- this.removeJpaProject((IProject) event.getResource());
+ this.jpaModel.projectPreDelete((IProject) event.getResource());
}
/**
@@ -454,7 +324,7 @@
private void checkForOpenedProject(IProject project, IResourceDelta delta) {
switch (delta.getKind()) {
case IResourceDelta.CHANGED :
- this.checkForOpenedProject2(project, delta);
+ this.checkDeltaFlagsForOpenedProject(project, delta);
break;
case IResourceDelta.REMOVED : // already handled with the PRE_DELETE event
case IResourceDelta.ADDED : // already handled with the facet POST_INSTALL event
@@ -473,10 +343,10 @@
* also triggers a Facet PROJECT_MODIFIED event and that is where we add
* the JPA project, not here
*/
- private synchronized void checkForOpenedProject2(IProject project, IResourceDelta delta) {
+ private void checkDeltaFlagsForOpenedProject(IProject project, IResourceDelta delta) {
if (BitTools.flagIsSet(delta.getFlags(), IResourceDelta.OPEN) && project.isOpen()) {
debug("\tProject CHANGED - OPEN: " + project.getName());
- this.checkForTransition(project);
+ this.jpaModel.checkForTransition(project);
}
}
@@ -489,7 +359,7 @@
* - un-install of JPA facet
* - any other appearance or disappearance of the JPA facet
*/
- /* private */ synchronized void facetedProjectChanged(IFacetedProjectEvent event) {
+ /* private */ void facetedProjectChanged(IFacetedProjectEvent event) {
switch (event.getType()) {
case POST_INSTALL :
this.facetedProjectPostInstall((IProjectFacetActionEvent) event);
@@ -508,71 +378,17 @@
private void facetedProjectPostInstall(IProjectFacetActionEvent event) {
debug("Facet POST_INSTALL: " + event.getProjectFacet());
if (event.getProjectFacet().getId().equals(JptCorePlugin.FACET_ID)) {
- this.jpaFacetedProjectPostInstall(event);
+ this.jpaModel.jpaFacetedProjectPostInstall(event);
}
}
- private void jpaFacetedProjectPostInstall(IProjectFacetActionEvent event) {
- IProject project = event.getProject().getProject();
- IDataModel dataModel = (IDataModel) event.getActionConfig();
-
- this.createPersistenceXml(project);
-
- if (dataModel.getBooleanProperty(IJpaFacetDataModelProperties.CREATE_ORM_XML)) {
- this.createOrmXml(project);
- }
-
- // assume(?) this is the first event to indicate we need to add the JPA project to the JPA model
- this.addJpaProject(project);
- }
-
- private void createPersistenceXml(IProject project) {
- PersistenceArtifactEdit pae =
- PersistenceArtifactEdit.getArtifactEditForWrite(project);
- PersistenceResource resource = pae.getPersistenceResource(JptCorePlugin.persistenceXmlDeploymentURI(project));
-
- // 202811 - do not add content if it is already present
- if (resource.getPersistence() == null) {
- Persistence persistence = PersistenceFactory.eINSTANCE.createPersistence();
- persistence.setVersion("1.0");
- PersistenceUnit pUnit = PersistenceFactory.eINSTANCE.createPersistenceUnit();
- pUnit.setName(project.getName());
- persistence.getPersistenceUnits().add(pUnit);
- resource.getContents().add(persistence);
- pae.save(null);
- }
-
- pae.dispose();
- }
-
- private void createOrmXml(IProject project) {
- OrmArtifactEdit oae =
- OrmArtifactEdit.getArtifactEditForWrite(project);
- OrmResource resource = oae.getOrmResource(JptCorePlugin.ormXmlDeploymentURI(project));
-
- // 202811 - do not add content if it is already present
- if (resource.getEntityMappings() == null) {
- EntityMappingsInternal entityMappings = OrmFactory.eINSTANCE.createEntityMappingsInternal();
- entityMappings.setVersion("1.0");
- resource.getContents().add(entityMappings);
- oae.save(null);
- }
-
- oae.dispose();
- }
-
private void facetedProjectPreUninstall(IProjectFacetActionEvent event) {
debug("Facet PRE_UNINSTALL: " + event.getProjectFacet());
if (event.getProjectFacet().getId().equals(JptCorePlugin.FACET_ID)) {
- this.jpaFacetedProjectPreUninstall(event);
+ this.jpaModel.jpaFacetedProjectPreUninstall(event);
}
}
- private void jpaFacetedProjectPreUninstall(IProjectFacetActionEvent event) {
- // assume(?) this is the first event to indicate we need to remove the JPA project to the JPA model
- this.removeJpaProject(event.getProject().getProject());
- }
-
/**
* This event is triggered for any change to a faceted project.
* We use the event to watch for the following:
@@ -582,7 +398,7 @@
*/
private void facetedProjectModified(IProject project) {
debug("Facet PROJECT_MODIFIED: " + project.getName());
- this.checkForTransition(project);
+ this.jpaModel.checkForTransition(project);
}
@@ -591,28 +407,28 @@
/**
* Forward the event to the JPA model.
*/
- // not synchronized because of a conflict between facet install and
- // java element change notifiation. synchronize on JpaModel instead.
/* private */ void javaElementChanged(ElementChangedEvent event) {
- if (isAddProjectNotOpenEvent(event)) {
+ if (this.eventIndicatesProjectAddedButNotOpen(event)) {
return;
}
this.jpaModel.javaElementChanged(event);
}
//209275 - This particular event only causes problems in a clean workspace the first time a JPA project
- //is created through the JPA wizard. The second time a JPA project is created, this event occurs, but
+ //is created through the JPA wizard. The second time a JPA project is created, this event occurs, but
//it occurs as the wizard is closing so it does not cause a deadlock.
- private boolean isAddProjectNotOpenEvent(ElementChangedEvent event) {
+ private boolean eventIndicatesProjectAddedButNotOpen(ElementChangedEvent event) {
IJavaElementDelta delta = event.getDelta();
if (delta.getKind() == IJavaElementDelta.CHANGED) {
if (delta.getElement().getElementType() == IJavaElement.JAVA_MODEL) {
- if (delta.getAffectedChildren().length == 1) {
- IJavaElementDelta childDelta = delta.getAffectedChildren()[0];
+ IJavaElementDelta[] children = delta.getAffectedChildren();
+ if (children.length == 1) {
+ IJavaElementDelta childDelta = children[0];
if (childDelta.getKind() == IJavaElementDelta.ADDED) {
- if (childDelta.getElement().getElementType() == IJavaElement.JAVA_PROJECT) {
+ IJavaElement childElement = childDelta.getElement();
+ if (childElement.getElementType() == IJavaElement.JAVA_PROJECT) {
if (childDelta.getAffectedChildren().length == 0) {
- if (!((IOpenable) childDelta.getElement()).isOpen()) {
+ if (!((IOpenable) childElement).isOpen()) {
return true;
}
}
@@ -630,7 +446,7 @@
* When the "Default JPA Lib" preference changes,
* update the appropriate JDT Core classpath variable.
*/
- /* private */ synchronized void preferenceChanged(PropertyChangeEvent event) {
+ /* private */ void preferenceChanged(PropertyChangeEvent event) {
if (event.getProperty() == JpaPreferenceConstants.PREF_DEFAULT_JPA_LIB) {
try {
JavaCore.setClasspathVariable("DEFAULT_JPA_LIB", new Path((String) event.getNewValue()), null);
@@ -719,6 +535,7 @@
// ********** debug **********
+ // @see JpaModelTests#testDEBUG()
private static final boolean DEBUG = false;
private static void debug(String message) {
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JptCorePlugin.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JptCorePlugin.java
index b0239cd..d42ed12 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JptCorePlugin.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JptCorePlugin.java
@@ -146,7 +146,7 @@
*/
public static IJpaFile jpaFile(IFile file) {
try {
- return jpaModel().jpaFile(file);
+ return JpaModelManager.instance().jpaFile(file);
} catch (CoreException ex) {
log(ex);
return null;