improve performance of resolver in workspaces with many sigil projects - prevent cyclical resolver tasks
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@963491 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/builders/SigilIncrementalProjectBuilder.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/builders/SigilIncrementalProjectBuilder.java
index d05be8f..9205692 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/builders/SigilIncrementalProjectBuilder.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/builders/SigilIncrementalProjectBuilder.java
@@ -44,6 +44,9 @@
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.JavaCore;
@@ -56,7 +59,6 @@
public class SigilIncrementalProjectBuilder extends IncrementalProjectBuilder
{
-
@Override
protected IProject[] build( int kind, @SuppressWarnings("unchecked") Map args, IProgressMonitor monitor )
throws CoreException
@@ -216,25 +218,34 @@
private static void loginfo( String message )
{
- BuildConsole console = findConsole();
- MessageConsoleStream stream = console.getMessageStream();
- stream.println( "INFO: " + message );
+ log("INFO: " + message);
}
-
private static void logwarn( String message )
{
- BuildConsole console = findConsole();
- MessageConsoleStream stream = console.getMessageStream();
- stream.println( "WARN: " + message );
+ log( "WARN: " + message );
}
private static void logerror( String message )
{
- BuildConsole console = findConsole();
- MessageConsoleStream stream = console.getMessageStream();
- stream.println( "ERROR: " + message );
+ log( "ERROR: " + message );
+ }
+
+ private static void log(final String message)
+ {
+ // do this in background to avoid deadlock with ui
+ Job job = new Job("log") {
+ @Override
+ protected IStatus run(IProgressMonitor arg0)
+ {
+ BuildConsole console = findConsole();
+ MessageConsoleStream stream = console.getMessageStream();
+ stream.println( message );
+ return Status.OK_STATUS;
+ }
+ };
+ job.schedule();
}
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/resources/ProjectResourceListener.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/resources/ProjectResourceListener.java
index d833e48..463abf0 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/resources/ProjectResourceListener.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/resources/ProjectResourceListener.java
@@ -21,6 +21,7 @@
import java.util.LinkedList;
import org.apache.felix.sigil.eclipse.SigilCore;
+import org.apache.felix.sigil.eclipse.job.ResolveProjectsJob;
import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
import org.apache.felix.sigil.model.ICapabilityModelElement;
import org.apache.felix.sigil.model.IModelElement;
@@ -33,10 +34,10 @@
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
+//import org.eclipse.core.runtime.IProgressMonitor;
+//import org.eclipse.core.runtime.IStatus;
+//import org.eclipse.core.runtime.Status;
+//import org.eclipse.core.runtime.jobs.Job;
public class ProjectResourceListener implements IResourceChangeListener
{
@@ -53,6 +54,9 @@
try
{
switch ( event.getType() ) {
+ case IResourceChangeEvent.PRE_REFRESH:
+ handleRefresh(event);
+ break;
case IResourceChangeEvent.PRE_DELETE:
handlePreDelete(event);
break;
@@ -60,6 +64,8 @@
handlePostChange(event);
break;
}
+
+ handleUpdate();
}
catch (CoreException e)
{
@@ -67,6 +73,43 @@
}
}
+ private void handleUpdate()
+ {
+ if( capabilities.size() > 0 ) {
+ final LinkedList<ICapabilityModelElement> changes = new LinkedList<ICapabilityModelElement>(capabilities);
+ capabilities.clear();
+
+ ResolveProjectsJob job = new ResolveProjectsJob(ResourcesPlugin.getWorkspace(), changes);
+ job.schedule();
+ }
+ }
+
+ private void handleRefresh(IResourceChangeEvent event) throws CoreException
+ {
+ IResourceDelta delta = event.getDelta();
+ if ( delta != null )
+ {
+ delta.accept( new IResourceDeltaVisitor()
+ {
+ public boolean visit( IResourceDelta delta ) throws CoreException
+ {
+ IResource resource = delta.getResource();
+ if ( resource instanceof IProject )
+ {
+ IProject project = ( IProject ) resource;
+ if ( SigilCore.isSigilProject( project ) )
+ {
+ readCapabilities(project);
+ }
+ // Recurse no more
+ return false;
+ }
+ return true;
+ }
+ } );
+ }
+ }
+
private LinkedList<ICapabilityModelElement> capabilities = new LinkedList<ICapabilityModelElement>();
private void handlePostChange(IResourceChangeEvent event) throws CoreException
@@ -97,25 +140,7 @@
}
return true;
}
- } );
-
- if( capabilities.size() > 0 ) {
- final LinkedList<ICapabilityModelElement> changes = new LinkedList<ICapabilityModelElement>(capabilities);
- capabilities.clear();
-
- Job job = new Job("Rebuild project dependencies")
- {
-
- @Override
- protected IStatus run(IProgressMonitor monitor)
- {
- SigilCore.rebuildBundleDependencies(null, changes, monitor);
- return Status.OK_STATUS;
- }
- };
- job.setRule(ResourcesPlugin.getWorkspace().getRoot());
- job.schedule();
- }
+ } );
}
}
@@ -147,6 +172,4 @@
}
});
}
-
-
}
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ResolveProjectsJob.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ResolveProjectsJob.java
index 2bfff2b..7c24d6c 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ResolveProjectsJob.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ResolveProjectsJob.java
@@ -22,9 +22,15 @@
import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedList;
import org.apache.felix.sigil.eclipse.SigilCore;
import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
+import org.apache.felix.sigil.model.ICapabilityModelElement;
+import org.apache.felix.sigil.model.IModelElement;
+import org.apache.felix.sigil.model.IModelWalker;
+import org.apache.felix.sigil.model.IRequirementModelElement;
+import org.apache.felix.sigil.model.eclipse.ISigilBundle;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
@@ -36,23 +42,32 @@
public class ResolveProjectsJob extends WorkspaceJob
{
private final Collection<ISigilProjectModel> sigilProjects;
+ private final LinkedList<ICapabilityModelElement> capabilities;
public ResolveProjectsJob( IWorkspace workspace )
{
super( "Resolving Sigil projects" );
setRule( workspace.getRoot() );
sigilProjects = SigilCore.getRoot().getProjects();
+ capabilities = null;
}
+ public ResolveProjectsJob(IWorkspace workspace, LinkedList<ICapabilityModelElement> capabilities)
+ {
+ super( "Resolving Sigil projects" );
+ this.capabilities = capabilities;
+ setRule( workspace.getRoot() );
+ sigilProjects = SigilCore.getRoot().getProjects();
+ }
public ResolveProjectsJob(ISigilProjectModel project)
{
super( "Resolving Sigil project" );
setRule( project.getProject().getWorkspace().getRoot() );
sigilProjects = Collections.singleton(project);
+ capabilities = null;
}
-
@Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException
{
@@ -64,8 +79,10 @@
{
try
{
- if ( flush ) sigilProject.flushDependencyState();
- sigilProject.rebuildDependencies(monitor);
+ if ( isDependent(sigilProject) ) {
+ if ( flush) sigilProject.flushDependencyState();
+ sigilProject.rebuildDependencies(monitor);
+ }
}
catch ( CoreException e )
{
@@ -75,4 +92,42 @@
return status;
}
+
+ private boolean isDependent(ISigilProjectModel sigilProject)
+ {
+ if ( capabilities == null ) {
+ return true;
+ }
+ else {
+ ISigilBundle b = sigilProject.getBundle();
+ if ( b == null ) {
+ // sigil project deleted can't be a dependent
+ return false;
+ }
+ else {
+ final boolean[] dep = new boolean[1];
+
+ b.visit(new IModelWalker()
+ {
+ public boolean visit(IModelElement element)
+ {
+ if (element instanceof IRequirementModelElement) {
+ IRequirementModelElement r = (IRequirementModelElement) element;
+
+ for (ICapabilityModelElement c : capabilities) {
+ if( r.accepts(c)) {
+ dep[0] = true;
+ break;
+ }
+ }
+ }
+ // found a dependency stop walking
+ return !dep[0];
+ }
+ });
+
+ return dep[0];
+ }
+ }
+ }
}
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/startup/SigilStartup.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/startup/SigilStartup.java
index b33e8fc..219f383 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/startup/SigilStartup.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/startup/SigilStartup.java
@@ -26,6 +26,7 @@
import org.apache.felix.sigil.eclipse.job.ResolveProjectsJob;
import org.apache.felix.sigil.repository.IRepositoryChangeListener;
import org.apache.felix.sigil.repository.RepositoryChangeEvent;
+import org.apache.felix.sigil.ui.eclipse.ui.SigilUI;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -47,24 +48,29 @@
{
public void repositoryChanged( RepositoryChangeEvent event )
{
- final int update = updateCounter.incrementAndGet();
-
- Job job = new Job("Pending repository update") {
- @Override
- protected IStatus run(IProgressMonitor monitor)
- {
- if ( update == updateCounter.get() ) {
- IWorkspace workspace = ResourcesPlugin.getWorkspace();
- ResolveProjectsJob job = new ResolveProjectsJob( workspace );
- job.setSystem( true );
- job.schedule();
- }
- return Status.OK_STATUS;
- }
+ if ( !SigilUI.WORKSPACE_REPOSITORY_ID.equals( event.getRepository().getId() ) ) {
+ final int update = updateCounter.incrementAndGet();
- };
- job.setSystem(true);
- job.schedule(100);
+ Job job = new Job("Pending repository update") {
+ @Override
+ protected IStatus run(IProgressMonitor monitor)
+ {
+ if ( update == updateCounter.get() ) {
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ ResolveProjectsJob job = new ResolveProjectsJob( workspace );
+ job.setSystem( true );
+ job.schedule();
+ }
+ return Status.OK_STATUS;
+ }
+
+ };
+ job.setSystem(true);
+ job.schedule(100);
+ }
+ //else {
+ // Repository changes are handled by ProjectResourceListener
+ //}
}
} );
}
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/SigilUI.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/SigilUI.java
index 3ccfee2..a2a3a08 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/SigilUI.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/SigilUI.java
@@ -54,6 +54,8 @@
public static final String ID_REPOSITORY_VIEW = "org.apache.felix.sigil.ui.repositoryBrowser";
public static final String ID_DEPENDENCY_VIEW = "org.apache.felix.sigil.ui.bundleDependencyView";
+
+ public static final String WORKSPACE_REPOSITORY_ID = "org.apache.felix.sigil.core.workspaceprovider";
// The shared instance
private static SigilUI plugin;
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/SigilProjectEditorPart.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/SigilProjectEditorPart.java
index 104363c..f10490c 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/SigilProjectEditorPart.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/SigilProjectEditorPart.java
@@ -238,9 +238,6 @@
try
{
switch (event.getType()) {
- case IResourceChangeEvent.PRE_REFRESH:
- handleRefresh(event);
- break;
case IResourceChangeEvent.POST_BUILD:
handleBuild(event);
break;
@@ -262,13 +259,6 @@
}
- private void handleRefresh(IResourceChangeEvent event)
- {
- ResolveProjectsJob job = new ResolveProjectsJob(project);
- job.schedule();
- }
-
-
private void handleChange(IResourceChangeEvent event) throws CoreException
{
IResourceDelta delta = event.getDelta();
@@ -386,8 +376,6 @@
tempProject.setBundle(null);
project.setBundle( null );
refreshAllPages();
- ResolveProjectsJob job = new ResolveProjectsJob(project);
- job.schedule();
}