Progress towards fixing bundle import resolution on project import FELIX-1349

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@918784 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 484ca83..d5cadfa 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
@@ -27,8 +27,6 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.Locale;
 import java.util.ResourceBundle;
 import java.util.Set;
@@ -43,6 +41,7 @@
 import org.apache.felix.sigil.eclipse.internal.model.repository.RepositoryConfiguration;
 import org.apache.felix.sigil.eclipse.internal.repository.eclipse.GlobalRepositoryManager;
 import org.apache.felix.sigil.eclipse.internal.repository.eclipse.SigilRepositoryManager;
+import org.apache.felix.sigil.eclipse.internal.resources.ProjectResourceListener;
 import org.apache.felix.sigil.eclipse.model.project.ISigilModelRoot;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryConfiguration;
@@ -57,11 +56,6 @@
 import org.eclipse.core.resources.ICommand;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectDescription;
-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.IResourceDeltaVisitor;
 import org.eclipse.core.resources.IncrementalProjectBuilder;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
@@ -417,55 +411,13 @@
 
     private void registerResourceListeners()
     {
-        final IResourceChangeListener listener = new IResourceChangeListener()
-        {
-            public void resourceChanged( IResourceChangeEvent event )
-            {
-                IResourceDelta delta = event.getDelta();
-                if ( delta != null )
-                {
-                    try
-                    {
-                        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 ) )
-                                    {
-                                        switch ( delta.getKind() )
-                                        {
-                                            case IResourceDelta.REMOVED:
-                                            case IResourceDelta.ADDED:
-                                                rebuildAllBundleDependencies( Job.getJobManager().createProgressGroup() );
-                                                break;
-                                        }
-                                    }
-                                    // Recurse no more
-                                    return false;
-                                }
-                                return true;
-                            }
-                        } );
-                    }
-                    catch ( CoreException e )
-                    {
-                        error( "Failed to update after change", e );
-                    }
-                }
-            }
-        };
-
         Job job = new Job( "Initialising sigil resource listeners" )
         {
             @Override
             protected IStatus run( IProgressMonitor monitor )
             {
-                ResourcesPlugin.getWorkspace().addResourceChangeListener( listener,
-                    IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.POST_CHANGE );
+                ResourcesPlugin.getWorkspace().addResourceChangeListener( new ProjectResourceListener(),
+                    ProjectResourceListener.EVENT_MASKS );
                 return Status.OK_STATUS;
             }
         };
@@ -573,7 +525,9 @@
     {
         Set<ISigilProjectModel> affected = SigilCore.getRoot().resolveDependentProjects( caps, monitor );
 
-        affected.add( project );
+        if ( project != null ) {
+            affected.add( project );
+        }
 
         SubMonitor progress = SubMonitor.convert( monitor, affected.size() * 20 );
         for ( ISigilProjectModel dependent : affected )
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
new file mode 100644
index 0000000..8a51e6a
--- /dev/null
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/resources/ProjectResourceListener.java
@@ -0,0 +1,127 @@
+package org.apache.felix.sigil.eclipse.internal.resources;
+
+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.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.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;
+
+public class ProjectResourceListener implements IResourceChangeListener
+{
+    public static final int EVENT_MASKS = IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.POST_CHANGE;
+
+    public void resourceChanged( IResourceChangeEvent event )
+    {
+        try
+        {
+            switch ( event.getType() ) {
+                case IResourceChangeEvent.PRE_DELETE:
+                    handlePreDelete(event);
+                    break;
+                case IResourceChangeEvent.POST_CHANGE:
+                    handlePostChange(event);
+                    break;
+            }
+        }
+        catch (CoreException e)
+        {
+            SigilCore.error( "Failed to process resource change", e );
+        }
+    }
+
+    private LinkedList<ICapabilityModelElement> capabilities = new LinkedList<ICapabilityModelElement>();
+    
+    private void handlePostChange(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 ) )
+                        {
+                            switch ( delta.getKind() )
+                            {
+                                case IResourceDelta.REMOVED:
+                                case IResourceDelta.ADDED:
+                                    readCapabilities(project);
+                                    break;
+                            }
+                        }
+                        // Recurse no more
+                        return false;
+                    }
+                    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();
+            }
+        }
+    }
+
+    protected void handlePreDelete(IResourceChangeEvent event) throws CoreException
+    {
+        IResource resource = event.getResource();
+        if ( resource instanceof IProject )
+        {
+            IProject project = ( IProject ) resource;
+            if ( SigilCore.isSigilProject( project ) )
+            {
+                readCapabilities(project);
+            }
+        }
+    }
+
+    private void readCapabilities(IProject project) throws CoreException
+    {
+        ISigilProjectModel sigil = SigilCore.create(project);
+        sigil.visit(new IModelWalker()
+        { 
+            public boolean visit(IModelElement element)
+            {
+                if ( element instanceof ICapabilityModelElement ) {
+                    capabilities.add((ICapabilityModelElement) element);
+                }
+                return true;
+            }
+        });
+    }
+
+
+}