Patch to address ui/classpath consistency issues when adding and removing projects from workspace that provide dependencies (related to FELIX-1349)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@919635 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/SigilCore.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/SigilCore.java
index 95a2d40..b2b3fa8 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/SigilCore.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/SigilCore.java
@@ -278,6 +278,7 @@
installs = new OSGiInstallManager();
globalRepositoryManager = new GlobalRepositoryManager();
+ globalRepositoryManager.initialise();
projectManager = new SigilProjectManager();
@@ -513,18 +514,19 @@
Set<ISigilProjectModel> affected = SigilCore.getRoot().resolveDependentProjects( caps, monitor );
if ( project != null ) {
- affected.add( project );
+ affected.remove( project );
}
SubMonitor progress = SubMonitor.convert( monitor, affected.size() * 20 );
for ( ISigilProjectModel dependent : affected )
{
+ //dependent.flushDependencyState();
rebuild( dependent, progress );
}
}
- private static void rebuild( ISigilProjectModel dependent, SubMonitor progress )
+ public static void rebuild( ISigilProjectModel dependent, SubMonitor progress )
{
try
{
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilProject.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilProject.java
index 737a183..2dbe8de 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilProject.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilProject.java
@@ -99,6 +99,8 @@
private IEclipsePreferences preferences;
+ private List<IRequirementModelElement> lastReqs = new LinkedList<IRequirementModelElement>();
+ private List<ICapabilityModelElement> lastCaps = new LinkedList<ICapabilityModelElement>();
public SigilProject()
{
@@ -150,16 +152,23 @@
if ( reqsChanged ) {
processRequirementsChanges(progress.newChild(600));
+ SigilCore.rebuild(this, progress.newChild(50));
}
- progress.setWorkRemaining( 300 );
+ progress.setWorkRemaining( 250 );
if ( capsChanged ) {
changes.addAll(caps);
- SigilCore.rebuildBundleDependencies( this, changes, progress.newChild( 300 ) );
+ SigilCore.rebuildBundleDependencies( this, changes, progress.newChild( 250 ) );
}
}
+ public void flushDependencyState() {
+ synchronized(this) {
+ lastReqs.clear();
+ }
+ }
+
private void processRequirementsChanges(IProgressMonitor monitor) throws CoreException
{
SubMonitor progress = SubMonitor.convert( monitor, 100 );
@@ -220,9 +229,6 @@
}
}
- private List<IRequirementModelElement> lastReqs = new LinkedList<IRequirementModelElement>();
- private List<ICapabilityModelElement> lastCaps = new LinkedList<ICapabilityModelElement>();
-
private void checkChanges(IProgressMonitor monitor, final List<IRequirementModelElement> reqs, final List<ICapabilityModelElement> caps)
{
visit(new IModelWalker()
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/SigilRepositoryManager.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/SigilRepositoryManager.java
index 0ce36d1..8a29575 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/SigilRepositoryManager.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/SigilRepositoryManager.java
@@ -103,7 +103,8 @@
ArrayList<IBundleRepository> repos = new ArrayList<IBundleRepository>();
HashSet<String> ids = new HashSet<String>();
- for ( IRepositoryModel repo : findRepositories() )
+ IRepositoryModel[] models = findRepositories();
+ for ( IRepositoryModel repo : models )
{
try
{
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepository.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepository.java
index 80df5df..2e95b44 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepository.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepository.java
@@ -39,7 +39,6 @@
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceVisitor;
-import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
@@ -49,7 +48,9 @@
public class WorkspaceRepository extends AbstractBundleRepository implements IResourceChangeListener
{
- private static final int UPDATE_MASK = IResourceDelta.CONTENT | IResourceDelta.DESCRIPTION | IResourceDelta.OPEN;
+ private static final int UPDATE_MASK = IResourceDelta.CONTENT | IResourceDelta.OPEN;
+
+ static final int EVENT_MASKS = IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_REFRESH;
public WorkspaceRepository( String id )
{
@@ -147,6 +148,9 @@
try
{
switch (event.getType()) {
+ case IResourceChangeEvent.PRE_DELETE:
+ handleDelete(event);
+ break;
case IResourceChangeEvent.PRE_REFRESH:
handleRefresh(event);
break;
@@ -161,6 +165,19 @@
}
}
+ private HashSet<IProject> deleted = new HashSet<IProject>();
+
+ private void handleDelete(IResourceChangeEvent event)
+ {
+ if ( event.getResource() instanceof IProject ) {
+ IProject project = (IProject) event.getResource();
+ if ( isSigilProject(project) )
+ {
+ deleted.add(project);
+ }
+ }
+ }
+
private void handleRefresh(IResourceChangeEvent event)
{
@@ -171,26 +188,25 @@
private void handleChange(IResourceChangeEvent event) throws CoreException
{
+ final boolean[] notify = new boolean[1];
+
event.getDelta().accept( new IResourceDeltaVisitor()
{
public boolean visit( IResourceDelta delta ) throws CoreException
{
- boolean result;
+ boolean checkMembers = true;
IResource resource = delta.getResource();
- if ( resource instanceof IWorkspaceRoot )
- {
- result = true;
- }
- else if ( resource instanceof IProject )
+ if ( resource instanceof IProject )
{
IProject project = ( IProject ) resource;
- if ( SigilCore.isSigilProject( project ) )
+ if ( isSigilProject(project) )
{
switch ( delta.getKind() )
{
case IResourceDelta.CHANGED:
- if ( ( delta.getFlags() & UPDATE_MASK ) == 0 )
+ int flag = delta.getFlags();
+ if ( ( flag & UPDATE_MASK ) == 0 )
{
break;
}
@@ -198,14 +214,14 @@
// fall through on purpose
case IResourceDelta.ADDED: // fall through on purpose
case IResourceDelta.REMOVED: // fall through on purpose
- notifyChange();
+ notify[0] = true;
break;
}
- result = true;
+ checkMembers = true;
}
else
{
- result = false;
+ checkMembers = false;
}
}
else if ( resource.getName().equals( SigilCore.SIGIL_PROJECT_FILE ) )
@@ -215,17 +231,23 @@
case IResourceDelta.CHANGED:
case IResourceDelta.ADDED:
case IResourceDelta.REMOVED:
- notifyChange();
+ notify[0] = true;
}
- result = false;
+ checkMembers = false;
}
- else
- {
- result = false;
- }
- return result;
+ return checkMembers && !notify[0];
}
} );
+
+ if (notify[0]) {
+ notifyChange();
+ }
+ }
+
+
+ private boolean isSigilProject(IProject project)
+ {
+ return SigilCore.isSigilProject( project ) || deleted.remove(project);
}
}
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepositoryProvider.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepositoryProvider.java
index 140fe5a..7b3be0d 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepositoryProvider.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepositoryProvider.java
@@ -24,7 +24,6 @@
import org.apache.felix.sigil.repository.IBundleRepository;
import org.apache.felix.sigil.repository.IRepositoryProvider;
-import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.ResourcesPlugin;
@@ -44,7 +43,7 @@
if ( repository == null )
{
repository = new WorkspaceRepository( id );
- ResourcesPlugin.getWorkspace().addResourceChangeListener( repository, IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_REFRESH );
+ ResourcesPlugin.getWorkspace().addResourceChangeListener( repository, WorkspaceRepository.EVENT_MASKS );
}
return repository;
}
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 dbd69fb..ee31d12 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
@@ -26,14 +26,14 @@
import org.apache.felix.sigil.eclipse.SigilCore;
import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
-import org.eclipse.core.runtime.jobs.Job;
-public class ResolveProjectsJob extends Job
+public class ResolveProjectsJob extends WorkspaceJob
{
final Collection<ISigilProjectModel> sigilProjects;
@@ -54,14 +54,17 @@
@Override
- protected IStatus run( IProgressMonitor monitor )
+ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException
{
MultiStatus status = new MultiStatus( SigilCore.PLUGIN_ID, 0, "Error resolving Sigil projects", null );
+ boolean flush = sigilProjects.size() > 0;
+
for ( ISigilProjectModel sigilProject : sigilProjects )
{
try
{
+ if ( flush ) sigilProject.flushDependencyState();
sigilProject.rebuildDependencies(monitor);
}
catch ( CoreException e )
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilProjectModel.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilProjectModel.java
index 4b3445c..21638cb 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilProjectModel.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilProjectModel.java
@@ -83,6 +83,8 @@
void save( IProgressMonitor monitor, boolean rebuildDependencies ) throws CoreException;
void rebuildDependencies(IProgressMonitor monitor) throws CoreException;
+
+ void flushDependencyState();
/**
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 a0e4d6d..7e0015a 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
@@ -34,28 +34,16 @@
public void earlyStartup()
{
- // Create a task to run the resolver
- final Runnable resolver = new Runnable()
+ // Register a repository change listener to re-run the resolver when repository changes
+ SigilCore.getGlobalRepositoryManager().addRepositoryChangeListener( new IRepositoryChangeListener()
{
- public void run()
+ public void repositoryChanged( RepositoryChangeEvent event )
{
IWorkspace workspace = ResourcesPlugin.getWorkspace();
ResolveProjectsJob job = new ResolveProjectsJob( workspace );
job.setSystem( true );
job.schedule();
}
- };
-
- // Register a repository change listener to re-run the resolver when repository changes
- SigilCore.getGlobalRepositoryManager().addRepositoryChangeListener( new IRepositoryChangeListener()
- {
- public void repositoryChanged( RepositoryChangeEvent event )
- {
- resolver.run();
- }
} );
-
- // Run the resolver now
- resolver.run();
}
}
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 852574a..104363c 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
@@ -46,7 +46,6 @@
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
@@ -236,15 +235,30 @@
public void resourceChanged( IResourceChangeEvent event )
{
- switch (event.getType()) {
- case IResourceChangeEvent.PRE_REFRESH:
- handleRefresh(event);
- break;
- case IResourceChangeEvent.POST_CHANGE:
- handleChange(event);
- break;
+ try
+ {
+ switch (event.getType()) {
+ case IResourceChangeEvent.PRE_REFRESH:
+ handleRefresh(event);
+ break;
+ case IResourceChangeEvent.POST_BUILD:
+ handleBuild(event);
+ break;
+ case IResourceChangeEvent.POST_CHANGE:
+ handleChange(event);
+ break;
+ }
}
+ catch ( CoreException e )
+ {
+ ErrorDialog.openError( getSite().getShell(), "Error", null, e.getStatus() );
+ }
+ }
+
+ private void handleBuild(IResourceChangeEvent event) throws CoreException
+ {
+ refreshView();
}
@@ -255,39 +269,32 @@
}
- private void handleChange(IResourceChangeEvent event)
+ private void handleChange(IResourceChangeEvent event) throws CoreException
{
IResourceDelta delta = event.getDelta();
final IFile editorFile = ( ( IFileEditorInput ) getEditorInput() ).getFile();
- try
+ delta.accept( new IResourceDeltaVisitor()
{
- delta.accept( new IResourceDeltaVisitor()
+ public boolean visit( IResourceDelta delta ) throws CoreException
{
- public boolean visit( IResourceDelta delta ) throws CoreException
+ int kind = delta.getKind();
+ IResource resource = delta.getResource();
+ if ( resource instanceof IProject )
{
- int kind = delta.getKind();
- IResource resource = delta.getResource();
- if ( resource instanceof IProject )
- {
- int flags = delta.getFlags();
- return handleProjectChange(editorFile, (IProject) resource, kind, flags);
- }
-
- if ( resource instanceof IFile )
- {
- handleFileChange(editorFile, (IFile) resource, kind);
- // Recurse no more
- return false;
- }
-
- return true;
+ int flags = delta.getFlags();
+ return handleProjectChange(editorFile, (IProject) resource, kind, flags);
}
- } );
- }
- catch ( CoreException e )
- {
- ErrorDialog.openError( getSite().getShell(), "Error", null, e.getStatus() );
- }
+
+ if ( resource instanceof IFile )
+ {
+ handleFileChange(editorFile, (IFile) resource, kind);
+ // Recurse no more
+ return false;
+ }
+
+ return true;
+ }
+ } );
}
@@ -324,15 +331,24 @@
{
return false;
}
- if ( kind == IResourceDelta.CHANGED && ( flags & IResourceDelta.MARKERS ) > 0 )
+ if ( kind == IResourceDelta.CHANGED )
{
- loadUnresolvedDependencies();
- refreshAllPages();
+ int mask = flags & (IResourceDelta.MARKERS);
+ if ( mask > 0 ) {
+ refreshView();
+ }
}
return true;
}
+ private void refreshView() throws CoreException
+ {
+ loadUnresolvedDependencies();
+ refreshAllPages();
+ }
+
+
protected void refreshAllPages()
{
Runnable op = new Runnable()
@@ -370,14 +386,8 @@
tempProject.setBundle(null);
project.setBundle( null );
refreshAllPages();
- try
- {
- project.rebuildDependencies(Job.getJobManager().createProgressGroup());
- }
- catch (CoreException e)
- {
- SigilCore.error( "Failed to update depedencies " + this, e );
- }
+ ResolveProjectsJob job = new ResolveProjectsJob(project);
+ job.schedule();
}
@@ -397,7 +407,7 @@
}
ResourcesPlugin.getWorkspace().addResourceChangeListener( this, IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_REFRESH );
-
+
if ( input instanceof IFileEditorInput )
{
try