Patch to improve IDE performance - avoid recalculating dependencies if no requirements or capabilities have changed (FELIX-2164)
Also as part of this patch have generalised the req/cap model with the addition of IRequirementModelElement and ICapabilityModelElement interfaces
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@918577 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/BundleCapability.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/BundleCapability.java
new file mode 100644
index 0000000..5f18d8f
--- /dev/null
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/BundleCapability.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+ package org.apache.felix.sigil.core.internal.model.eclipse;
+
+import org.apache.felix.sigil.model.AbstractModelElement;
+import org.apache.felix.sigil.model.eclipse.IBundleCapability;
+import org.apache.felix.sigil.model.osgi.IBundleModelElement;
+import org.osgi.framework.Version;
+
+public class BundleCapability extends AbstractModelElement implements IBundleCapability
+{
+
+ private final String bsn;
+ private final Version version;
+
+ public BundleCapability(IBundleModelElement bundle)
+ {
+ super("Bundle Capability");
+ this.bsn = bundle.getSymbolicName();
+ this.version = bundle.getVersion();
+ setParent(bundle.getParent());
+ }
+
+ public String getSymbolicName()
+ {
+ return bsn;
+ }
+
+ public Version getVersion()
+ {
+ return version;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if ( obj == this ) return true;
+ if ( obj == null ) return false;
+
+ if ( obj instanceof BundleCapability ) {
+ BundleCapability bc = (BundleCapability) obj;
+ return (bsn == null ? bc.bsn == null : bsn.equals(bc.bsn)) &&
+ (version == null ? bc.version == null : version.equals(bc.version));
+ }
+ else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hc = 11;
+
+ if ( bsn!= null ) {
+ hc *= bsn.hashCode();
+ }
+
+ if ( version != null ) {
+ hc *= version.hashCode();
+ }
+
+ return hc;
+ }
+}
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/SigilBundle.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/SigilBundle.java
index 47d4eab..f2ff433 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/SigilBundle.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/SigilBundle.java
@@ -38,6 +38,7 @@
import org.apache.felix.sigil.core.BldCore;
import org.apache.felix.sigil.core.util.ManifestUtil;
import org.apache.felix.sigil.model.AbstractCompoundModelElement;
+import org.apache.felix.sigil.model.eclipse.IBundleCapability;
import org.apache.felix.sigil.model.eclipse.ISigilBundle;
import org.apache.felix.sigil.model.osgi.IBundleModelElement;
import org.apache.felix.sigil.model.osgi.IPackageExport;
@@ -455,5 +456,11 @@
b.packages = tmp;
return b;
+ }
+
+
+ public IBundleCapability getBundleCapability()
+ {
+ return new BundleCapability(bundle);
}
}
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageExport.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageExport.java
index 1a1942e..2e72d23 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageExport.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageExport.java
@@ -171,14 +171,17 @@
@Override
public boolean equals(Object obj)
{
- if ( obj == null ) return false;
if ( obj == this ) return true;
- try {
+ if ( obj == null ) return false;
+
+ if ( obj instanceof PackageExport )
+ {
PackageExport e = (PackageExport) obj;
return (name == null ? e.name == null : name.equals( e.name )) &&
(version == null ? e.version == null : version.equals( e.version ));
}
- catch (ClassCastException e) {
+ else
+ {
return false;
}
}
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageImport.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageImport.java
index f6cfdaf..2c391ad 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageImport.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageImport.java
@@ -22,7 +22,7 @@
import org.apache.felix.sigil.common.osgi.VersionRange;
import org.apache.felix.sigil.model.AbstractModelElement;
-import org.apache.felix.sigil.model.IModelElement;
+import org.apache.felix.sigil.model.ICapabilityModelElement;
import org.apache.felix.sigil.model.InvalidModelException;
import org.apache.felix.sigil.model.osgi.IPackageExport;
import org.apache.felix.sigil.model.osgi.IPackageImport;
@@ -159,7 +159,7 @@
}
- public boolean accepts( IModelElement provider )
+ public boolean accepts( ICapabilityModelElement provider )
{
if ( provider instanceof IPackageExport )
{
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/RequiredBundle.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/RequiredBundle.java
index 3cd7aa8..e765a17 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/RequiredBundle.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/RequiredBundle.java
@@ -22,8 +22,8 @@
import org.apache.felix.sigil.common.osgi.VersionRange;
import org.apache.felix.sigil.model.AbstractModelElement;
-import org.apache.felix.sigil.model.IModelElement;
-import org.apache.felix.sigil.model.osgi.IBundleModelElement;
+import org.apache.felix.sigil.model.ICapabilityModelElement;
+import org.apache.felix.sigil.model.eclipse.IBundleCapability;
import org.apache.felix.sigil.model.osgi.IRequiredBundle;
@@ -119,11 +119,11 @@
}
- public boolean accepts( IModelElement provider )
+ public boolean accepts( ICapabilityModelElement provider )
{
- if ( provider instanceof IBundleModelElement )
+ if ( provider instanceof IBundleCapability )
{
- IBundleModelElement bndl = ( IBundleModelElement ) provider;
+ IBundleCapability bndl = ( IBundleCapability ) provider;
return symbolicName.equals( bndl.getSymbolicName() ) && versions.contains( bndl.getVersion() );
}
else
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/repository/BundleResolver.java b/sigil/common/core/src/org/apache/felix/sigil/core/repository/BundleResolver.java
index 701212a..a35466a 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/repository/BundleResolver.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/repository/BundleResolver.java
@@ -33,6 +33,7 @@
import java.util.Set;
import org.apache.felix.sigil.core.BldCore;
+import org.apache.felix.sigil.model.ICapabilityModelElement;
import org.apache.felix.sigil.model.ICompoundModelElement;
import org.apache.felix.sigil.model.IModelElement;
import org.apache.felix.sigil.model.IModelWalker;
@@ -490,9 +491,11 @@
{
public boolean visit(IModelElement element)
{
- if ( requirement.accepts(element) ) {
- ctx.resolution.addProvider( requirement, b );
- return false;
+ if ( element instanceof ICapabilityModelElement ) {
+ if ( requirement.accepts((ICapabilityModelElement) element) ) {
+ ctx.resolution.addProvider( requirement, b );
+ return false;
+ }
}
return !ctx.monitor.isCanceled();
}
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/ICapabilityModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/ICapabilityModelElement.java
new file mode 100644
index 0000000..0327644
--- /dev/null
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/ICapabilityModelElement.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.sigil.model;
+
+public interface ICapabilityModelElement extends IModelElement
+{
+
+}
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/IRequirementModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/IRequirementModelElement.java
index 0f73b66..ef3f720 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/IRequirementModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/IRequirementModelElement.java
@@ -22,7 +22,7 @@
public interface IRequirementModelElement extends IModelElement
{
- boolean accepts( IModelElement provider );
+ boolean accepts( ICapabilityModelElement provider );
/**
* indicates whether the OSGi attribute "resolution=optional" is specified.
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/IBundleCapability.java b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/IBundleCapability.java
new file mode 100644
index 0000000..263fa6b
--- /dev/null
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/IBundleCapability.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.sigil.model.eclipse;
+
+import org.apache.felix.sigil.model.ICapabilityModelElement;
+import org.osgi.framework.Version;
+
+public interface IBundleCapability extends ICapabilityModelElement
+{
+ String getSymbolicName();
+ Version getVersion();
+}
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISigilBundle.java b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISigilBundle.java
index 05c9a3d..14c81ff 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISigilBundle.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISigilBundle.java
@@ -132,4 +132,7 @@
* @return
*/
IPackageImport findImport( String packageName );
+
+
+ IBundleCapability getBundleCapability();
}
\ No newline at end of file
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageExport.java b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageExport.java
index 271774c..fbfd9ca 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageExport.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageExport.java
@@ -22,10 +22,11 @@
import java.util.Collection;
+import org.apache.felix.sigil.model.ICapabilityModelElement;
import org.osgi.framework.Version;
-public interface IPackageExport extends IPackageModelElement, IVersionedModelElement, Comparable<IPackageExport>
+public interface IPackageExport extends IPackageModelElement, IVersionedModelElement, Comparable<IPackageExport>, ICapabilityModelElement
{
void addUse( String uses );
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 2a8bc75..484ca83 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
@@ -28,8 +28,10 @@
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;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.felix.sigil.config.IBldProject;
@@ -45,6 +47,7 @@
import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
import org.apache.felix.sigil.eclipse.model.repository.IRepositoryConfiguration;
import org.apache.felix.sigil.eclipse.model.util.JavaHelper;
+import org.apache.felix.sigil.model.ICapabilityModelElement;
import org.apache.felix.sigil.model.ModelElementFactory;
import org.apache.felix.sigil.model.eclipse.ISigilBundle;
import org.apache.felix.sigil.repository.IBundleRepository;
@@ -566,9 +569,10 @@
}
- public static void rebuildBundleDependencies( ISigilProjectModel project, IProgressMonitor monitor )
+ public static void rebuildBundleDependencies( ISigilProjectModel project, Collection<ICapabilityModelElement> caps, IProgressMonitor monitor )
{
- HashSet<ISigilProjectModel> affected = new HashSet<ISigilProjectModel>( project.findDependentProjects( monitor ) );
+ Set<ISigilProjectModel> affected = SigilCore.getRoot().resolveDependentProjects( caps, monitor );
+
affected.add( project );
SubMonitor progress = SubMonitor.convert( monitor, affected.size() * 20 );
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilModelRoot.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilModelRoot.java
index c521808..2abf169 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilModelRoot.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilModelRoot.java
@@ -24,17 +24,19 @@
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.apache.felix.sigil.eclipse.SigilCore;
import org.apache.felix.sigil.eclipse.model.project.ISigilModelRoot;
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.ILibrary;
import org.apache.felix.sigil.model.eclipse.ILibraryImport;
import org.apache.felix.sigil.model.eclipse.ISigilBundle;
-import org.apache.felix.sigil.model.osgi.IPackageExport;
import org.apache.felix.sigil.model.osgi.IPackageImport;
-import org.apache.felix.sigil.model.osgi.IRequiredBundle;
import org.apache.felix.sigil.repository.IBundleResolver;
import org.apache.felix.sigil.repository.IResolution;
import org.apache.felix.sigil.repository.ResolutionConfig;
@@ -72,56 +74,93 @@
}
- public Collection<ISigilProjectModel> resolveDependentProjects( ISigilProjectModel sigil, IProgressMonitor monitor )
+ public Set<ISigilProjectModel> resolveDependentProjects( Collection<ICapabilityModelElement> caps, IProgressMonitor monitor )
{
- HashSet<ISigilProjectModel> dependents = new HashSet<ISigilProjectModel>();
+ final HashSet<ISigilProjectModel> dependents = new HashSet<ISigilProjectModel>();
- for ( ISigilProjectModel n : getProjects() )
+ for ( final ISigilProjectModel n : getProjects() )
{
- if ( !sigil.equals( n ) )
- {
- for ( IPackageExport pe : sigil.getBundle().getBundleInfo().getExports() )
+ for (final ICapabilityModelElement cap : caps ) {
+ final ISigilProjectModel sigil = cap.getAncestor(ISigilProjectModel.class);
+
+ n.visit(new IModelWalker()
{
- for ( IPackageImport i : n.getBundle().getBundleInfo().getImports() )
+ public boolean visit(IModelElement element)
{
- if ( pe.getPackageName().equals( i.getPackageName() )
- && i.getVersions().contains( pe.getVersion() ) )
- {
- dependents.add( n );
- }
- }
-
- for ( ILibraryImport l : n.getBundle().getBundleInfo().getLibraryImports() )
- {
- ILibrary lib = SigilCore.getRepositoryManager( sigil ).resolveLibrary( l );
-
- if ( lib != null )
- {
- for ( IPackageImport i : lib.getImports() )
- {
- if ( pe.getPackageName().equals( i.getPackageName() )
- && i.getVersions().contains( pe.getVersion() ) )
- {
- dependents.add( n );
- }
+ if ( element instanceof IRequirementModelElement ) {
+ IRequirementModelElement req = (IRequirementModelElement) element;
+ if ( req.accepts(cap) ) {
+ dependents.add(n);
+ return false;
}
}
- else
- {
- SigilCore.error( "No library found for " + l );
- }
- }
- }
+ else if ( element instanceof ILibraryImport ) {
+ ILibraryImport l = (ILibraryImport) element;
+ ILibrary lib = SigilCore.getRepositoryManager( sigil ).resolveLibrary( l );
- for ( IRequiredBundle r : n.getBundle().getBundleInfo().getRequiredBundles() )
- {
- if ( sigil.getSymbolicName().equals( r.getSymbolicName() )
- && r.getVersions().contains( sigil.getVersion() ) )
- {
- dependents.add( n );
+ if ( lib != null )
+ {
+ for ( IPackageImport i : lib.getImports() )
+ {
+ if ( i.accepts(cap))
+ {
+ dependents.add( n );
+ }
+ }
+ }
+ else
+ {
+ SigilCore.error( "No library found for " + l );
+ }
+ }
+ return true;
}
- }
+ });
}
+// if ( !sigil.equals( n ) )
+// {
+// for ( IPackageExport pe : sigil.getBundle().getBundleInfo().getExports() )
+// {
+// for ( IPackageImport i : n.getBundle().getBundleInfo().getImports() )
+// {
+// if ( pe.getPackageName().equals( i.getPackageName() )
+// && i.getVersions().contains( pe.getVersion() ) )
+// {
+// dependents.add( n );
+// }
+// }
+//
+// for ( ILibraryImport l : n.getBundle().getBundleInfo().getLibraryImports() )
+// {
+// ILibrary lib = SigilCore.getRepositoryManager( sigil ).resolveLibrary( l );
+//
+// if ( lib != null )
+// {
+// for ( IPackageImport i : lib.getImports() )
+// {
+// if ( pe.getPackageName().equals( i.getPackageName() )
+// && i.getVersions().contains( pe.getVersion() ) )
+// {
+// dependents.add( n );
+// }
+// }
+// }
+// else
+// {
+// SigilCore.error( "No library found for " + l );
+// }
+// }
+// }
+//
+// for ( IRequiredBundle r : n.getBundle().getBundleInfo().getRequiredBundles() )
+// {
+// if ( sigil.getSymbolicName().equals( r.getSymbolicName() )
+// && r.getVersions().contains( sigil.getVersion() ) )
+// {
+// dependents.add( n );
+// }
+// }
+// }
}
return dependents;
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 755fa02..6bdef9e 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
@@ -27,6 +27,9 @@
import java.net.URI;
import java.util.Arrays;
import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
import java.util.regex.Matcher;
import org.apache.felix.sigil.config.BldFactory;
@@ -36,8 +39,10 @@
import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
import org.apache.felix.sigil.eclipse.model.util.JavaHelper;
import org.apache.felix.sigil.model.AbstractCompoundModelElement;
+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.ModelElementFactory;
import org.apache.felix.sigil.model.eclipse.ISigilBundle;
import org.apache.felix.sigil.model.osgi.IBundleModelElement;
@@ -116,28 +121,75 @@
public void save( IProgressMonitor monitor, boolean rebuildDependencies ) throws CoreException
{
- SubMonitor progress = SubMonitor.convert( monitor, 100 );
+ SubMonitor progress = SubMonitor.convert( monitor, 1000 );
bldProjectFile.setContents( buildContents(), IFile.KEEP_HISTORY, progress.newChild( 10 ) );
if ( rebuildDependencies ) {
- rebuildDependencies(progress.newChild(90));
+ rebuildDependencies(progress.newChild(900));
}
}
public void rebuildDependencies(IProgressMonitor monitor) throws CoreException {
+ SubMonitor progress = SubMonitor.convert( monitor, 1000 );
+
+ HashSet<ICapabilityModelElement> changes = new HashSet<ICapabilityModelElement>(lastCaps);
+
+ LinkedList<IRequirementModelElement> reqs = new LinkedList<IRequirementModelElement>();
+ LinkedList<ICapabilityModelElement> caps = new LinkedList<ICapabilityModelElement>();
+
+ checkChanges(progress.newChild(100), reqs, caps);
+
+ boolean reqsChanged;
+ boolean capsChanged;
+
+ synchronized(this) {
+ reqsChanged = isRequirementsChanged(reqs);
+ capsChanged = isCapabilitiesChanged(caps);
+ }
+
+ if ( reqsChanged ) {
+ processRequirementsChanges(progress.newChild(600));
+ }
+
+ progress.setWorkRemaining( 300 );
+
+ if ( capsChanged ) {
+ changes.addAll(caps);
+ SigilCore.rebuildBundleDependencies( this, changes, progress.newChild( 300 ) );
+ }
+ }
+
+ private void processRequirementsChanges(IProgressMonitor monitor) throws CoreException
+ {
SubMonitor progress = SubMonitor.convert( monitor, 100 );
- calculateUses();
-
IRepositoryManager manager = SigilCore.getRepositoryManager( this );
ResolutionConfig config = new ResolutionConfig( ResolutionConfig.INCLUDE_OPTIONAL | ResolutionConfig.IGNORE_ERRORS );
try
{
IResolution resolution = manager.getBundleResolver().resolve( this, config,
- new ResolutionMonitorAdapter( progress.newChild( 10 ) ) );
+ new ResolutionMonitorAdapter( progress.newChild( 20 ) ) );
+ markProblems(resolution);
+
+ // pull remote bundles from repositories to be added to classpath
+ if ( !resolution.isSynchronized() )
+ {
+ resolution.synchronize( progress.newChild( 80 ) );
+ }
+ }
+ catch ( ResolutionException e )
+ {
+ throw SigilCore.newCoreException( "Failed to resolve dependencies", e );
+ }
+ }
+
+ private void markProblems(IResolution resolution)
+ {
+ try
+ {
getProject().deleteMarkers( SigilCore.MARKER_UNRESOLVED_DEPENDENCY, true,
IResource.DEPTH_ONE );
@@ -161,25 +213,70 @@
markMissingRequiredBundle( requiredBundle, getProject() );
}
}
-
- if ( !resolution.isSynchronized() )
- {
- resolution.synchronize( progress.newChild( 60 ) );
- }
-
-
}
- catch ( ResolutionException e )
+ catch (CoreException e)
{
- throw SigilCore.newCoreException( "Failed to resolve dependencies", e );
+ SigilCore.error("Failed to update problems", e);
}
-
- progress.setWorkRemaining( 30 );
-
- SigilCore.rebuildBundleDependencies( this, progress.newChild( 30 ) );
}
-
+ 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()
+ {
+ public boolean visit(IModelElement element)
+ {
+ if ( element instanceof IRequirementModelElement ) {
+ reqs.add((IRequirementModelElement) element);
+ }
+ else if ( element instanceof ICapabilityModelElement ) {
+ // also calculate uses during this pass to save multi pass on model
+ if ( element instanceof IPackageExport )
+ {
+ IPackageExport pe = ( IPackageExport ) element;
+ try
+ {
+ pe.setUses( Arrays.asList( JavaHelper.findUses( pe.getPackageName(), SigilProject.this ) ) );
+ }
+ catch ( CoreException e )
+ {
+ SigilCore.error( "Failed to build uses list for " + pe, e );
+ }
+ }
+
+ caps.add((ICapabilityModelElement) element);
+ }
+ return true;
+ }
+ });
+
+ }
+
+
+ private boolean isRequirementsChanged(List<IRequirementModelElement> dependencies)
+ {
+ if ( lastReqs.equals(dependencies) ) {
+ return false;
+ }
+ else {
+ lastReqs = dependencies;
+ return true;
+ }
+ }
+
+ private boolean isCapabilitiesChanged(List<ICapabilityModelElement> capabilites)
+ {
+ if ( lastCaps.equals(capabilites) ) {
+ return false;
+ }
+ else {
+ lastCaps = capabilites;
+ return true;
+ }
+ }
private static void markMissingImport( IPackageImport pkgImport, IProject project ) throws CoreException
{
@@ -266,37 +363,6 @@
return JavaHelper.resolveClasspathEntrys( this, monitor );
}
-
- private void calculateUses()
- {
- visit( new IModelWalker()
- {
- public boolean visit( IModelElement element )
- {
- if ( element instanceof IPackageExport )
- {
- IPackageExport pe = ( IPackageExport ) element;
- try
- {
- pe.setUses( Arrays.asList( JavaHelper.findUses( pe.getPackageName(), SigilProject.this ) ) );
- }
- catch ( CoreException e )
- {
- SigilCore.error( "Failed to build uses list for " + pe, e );
- }
- }
- return true;
- }
- } );
- }
-
-
- public Collection<ISigilProjectModel> findDependentProjects( IProgressMonitor monitor )
- {
- return SigilCore.getRoot().resolveDependentProjects( this, monitor );
- }
-
-
public Version getVersion()
{
ISigilBundle bundle = getBundle();
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 b2efef0..dbd69fb 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
@@ -48,7 +48,7 @@
public ResolveProjectsJob(ISigilProjectModel project)
{
super( "Resolving Sigil project" );
- setRule( project.getProject() );
+ setRule( project.getProject().getWorkspace().getRoot() );
sigilProjects = Collections.singleton(project);
}
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilModelRoot.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilModelRoot.java
index 4b9ca00..5b2fab7 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilModelRoot.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilModelRoot.java
@@ -22,7 +22,9 @@
import java.util.Collection;
import java.util.List;
+import java.util.Set;
+import org.apache.felix.sigil.model.ICapabilityModelElement;
import org.apache.felix.sigil.model.IModelElement;
import org.apache.felix.sigil.model.eclipse.ISigilBundle;
import org.eclipse.core.runtime.CoreException;
@@ -34,7 +36,7 @@
List<ISigilProjectModel> getProjects();
- Collection<ISigilProjectModel> resolveDependentProjects( ISigilProjectModel sigil, IProgressMonitor monitor );
+ Set<ISigilProjectModel> resolveDependentProjects( Collection<ICapabilityModelElement> caps, IProgressMonitor monitor );
Collection<ISigilBundle> resolveBundles( ISigilProjectModel sigil, IModelElement element, boolean includeOptional,
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 29c2d8f..4b3445c 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
@@ -106,9 +106,6 @@
IJavaProject getJavaModel();
- Collection<ISigilProjectModel> findDependentProjects( IProgressMonitor monitor );
-
-
void resetClasspath( IProgressMonitor monitor ) throws CoreException;
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/JavaHelper.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/JavaHelper.java
index 23b4a73..b0121c6 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/JavaHelper.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/JavaHelper.java
@@ -791,7 +791,7 @@
{
for ( ISigilBundle b : all )
{
- if ( host.accepts( b.getBundleInfo() ) )
+ if ( host.accepts( b.getBundleCapability() ) )
{
exports.addAll( b.getBundleInfo().getExports() );
break;
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/ModelHelper.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/ModelHelper.java
index bea3a14..4f70900 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/ModelHelper.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/ModelHelper.java
@@ -24,13 +24,11 @@
import java.util.List;
import org.apache.felix.sigil.eclipse.SigilCore;
+import org.apache.felix.sigil.model.ICapabilityModelElement;
import org.apache.felix.sigil.model.ICompoundModelElement;
import org.apache.felix.sigil.model.IModelElement;
import org.apache.felix.sigil.model.IModelWalker;
-import org.apache.felix.sigil.model.osgi.IBundleModelElement;
-import org.apache.felix.sigil.model.osgi.IPackageExport;
-import org.apache.felix.sigil.model.osgi.IPackageImport;
-import org.apache.felix.sigil.model.osgi.IRequiredBundle;
+import org.apache.felix.sigil.model.IRequirementModelElement;
public class ModelHelper
@@ -47,49 +45,28 @@
private static void findUsers( IModelElement e, final LinkedList<IModelElement> users )
{
- if ( e instanceof IPackageExport )
+ if ( e instanceof ICapabilityModelElement )
{
- final IPackageExport pe = ( IPackageExport ) e;
+ final ICapabilityModelElement cap = ( ICapabilityModelElement ) e;
SigilCore.getGlobalRepositoryManager().visit( new IModelWalker()
{
public boolean visit( IModelElement element )
{
- if ( element instanceof IPackageImport )
+ if ( element instanceof IRequirementModelElement )
{
- IPackageImport pi = ( IPackageImport ) element;
- if ( pi.accepts( pe ) )
- {
- users.add( pi );
- }
- return false;
- }
-
- return true;
- }
- } );
- }
- else if ( e instanceof IBundleModelElement )
- {
- final IBundleModelElement bndl = ( IBundleModelElement ) e;
-
- SigilCore.getGlobalRepositoryManager().visit( new IModelWalker()
- {
- public boolean visit( IModelElement element )
- {
- if ( element instanceof IRequiredBundle )
- {
- IRequiredBundle req = ( IRequiredBundle ) element;
- if ( req.accepts( bndl ) )
+ IRequirementModelElement req = ( IRequirementModelElement ) element;
+ if ( req.accepts( cap ) )
{
users.add( req );
}
return false;
}
+
return true;
}
} );
}
-
+
if ( e instanceof ICompoundModelElement )
{
ICompoundModelElement c = ( ICompoundModelElement ) e;
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 eb8c58a..852574a 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,6 +46,7 @@
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;
@@ -369,6 +370,14 @@
tempProject.setBundle(null);
project.setBundle( null );
refreshAllPages();
+ try
+ {
+ project.rebuildDependencies(Job.getJobManager().createProgressGroup());
+ }
+ catch (CoreException e)
+ {
+ SigilCore.error( "Failed to update depedencies " + this, e );
+ }
}