diff options
5 files changed, 79 insertions, 33 deletions
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/DefaultMavenDependencyResolver.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/DefaultMavenDependencyResolver.java index 059e100b..6728d013 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/DefaultMavenDependencyResolver.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/DefaultMavenDependencyResolver.java @@ -71,10 +71,25 @@ public class DefaultMavenDependencyResolver extends AbstractMavenDependencyResol // dependencies + // missing dependencies + // should be added before dependencies from MavenProject#getArtifacts() since those + // will be added with resolved flag set to true + DependencyResolutionResult resolutionResult = mavenResult.getDependencyResolutionResult(); + if(resolutionResult != null && resolutionResult.getUnresolvedDependencies() != null) { + for(Dependency dependency : resolutionResult.getUnresolvedDependencies()) { + org.eclipse.aether.artifact.Artifact artifact = dependency.getArtifact(); + ArtifactKey dependencyKey = new ArtifactKey(artifact.getGroupId(), artifact.getArtifactId(), + artifact.getVersion(), null); + MavenRequiredCapability req = MavenRequiredCapability.createMavenArtifact(dependencyKey, dependency.getScope(), + dependency.isOptional()); + requirements.add(req); + } + } + // resolved dependencies for(Artifact artifact : mavenProject.getArtifacts()) { - requirements.add(MavenRequiredCapability.createMavenArtifact(new ArtifactKey(artifact), artifact.getScope(), - artifact.isOptional())); + requirements.add(MavenRequiredCapability.createResolvedMavenArtifact(new ArtifactKey(artifact), + artifact.getScope(), artifact.isOptional())); } // extension plugins (affect packaging type calculation) @@ -86,25 +101,13 @@ public class DefaultMavenDependencyResolver extends AbstractMavenDependencyResol } } - // missing dependencies - DependencyResolutionResult resolutionResult = mavenResult.getDependencyResolutionResult(); - if(resolutionResult != null && resolutionResult.getUnresolvedDependencies() != null) { - for(Dependency dependency : resolutionResult.getUnresolvedDependencies()) { - org.eclipse.aether.artifact.Artifact artifact = dependency.getArtifact(); - ArtifactKey dependencyKey = new ArtifactKey(artifact.getGroupId(), artifact.getArtifactId(), - artifact.getVersion(), null); - requirements.add(MavenRequiredCapability.createMavenArtifact(dependencyKey, dependency.getScope(), - dependency.isOptional())); - } - } - log.debug("Resolved dependencies for {} in {} ms", facade.toString(), System.currentTimeMillis() - start); //$NON-NLS-1$ } public static void addParentRequirements(Set<RequiredCapability> requirements, MavenProject mavenProject) { Artifact parentArtifact = mavenProject.getParentArtifact(); if(parentArtifact != null) { - requirements.add(MavenRequiredCapability.createMavenParent(new ArtifactKey(parentArtifact))); + requirements.add(MavenRequiredCapability.createResolvedMavenParent(new ArtifactKey(parentArtifact))); } } } diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MavenRequiredCapability.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MavenRequiredCapability.java index 9ef9fde7..bb8b976d 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MavenRequiredCapability.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MavenRequiredCapability.java @@ -11,7 +11,6 @@ package org.eclipse.m2e.core.internal.project.registry; -import org.apache.maven.artifact.versioning.ArtifactVersion; import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.VersionRange; @@ -29,7 +28,10 @@ public class MavenRequiredCapability extends RequiredCapability { private final boolean optional; - private MavenRequiredCapability(String namespace, String id, String versionRange, String scope, boolean optional) { + private final boolean resolved; + + private MavenRequiredCapability(String namespace, String id, String versionRange, String scope, boolean optional, + boolean resolved) { super(namespace, id); if(versionRange == null) { @@ -39,25 +41,42 @@ public class MavenRequiredCapability extends RequiredCapability { this.versionRange = versionRange; this.scope = scope; this.optional = optional; + this.resolved = resolved; + } + + public static MavenRequiredCapability createResolvedMavenArtifact(ArtifactKey key, String scope, boolean optional) { + return new MavenRequiredCapability(MavenCapability.NS_MAVEN_ARTIFACT, MavenCapability.getId(key), key.getVersion(), + scope, optional, true); } public static MavenRequiredCapability createMavenArtifact(ArtifactKey key, String scope, boolean optional) { return new MavenRequiredCapability(MavenCapability.NS_MAVEN_ARTIFACT, MavenCapability.getId(key), key.getVersion(), - scope, optional); + scope, optional, false); } public static MavenRequiredCapability createMavenParent(ArtifactKey key) { return new MavenRequiredCapability(MavenCapability.NS_MAVEN_PARENT, MavenCapability.getId(key), key.getVersion(), - null, false); + null, false, false); + } + + public static MavenRequiredCapability createResolvedMavenParent(ArtifactKey key) { + return new MavenRequiredCapability(MavenCapability.NS_MAVEN_PARENT, MavenCapability.getId(key), key.getVersion(), + null, false, true); } - public boolean isPotentialMatch(Capability capability) { + public boolean isPotentialMatch(Capability capability, boolean narrowMatch) { if(capability instanceof MavenCapability && getVersionlessKey().equals(capability.getVersionlessKey())) { + String version = ((MavenCapability) capability).getVersion(); + + // not interested in any version, but just in the resolved one + if(resolved && narrowMatch) { + return versionRange.equals(version); + } + try { // TODO may need to cache parsed version and versionRange for performance reasons - ArtifactVersion version = new DefaultArtifactVersion(((MavenCapability) capability).getVersion()); VersionRange range = VersionRange.createFromVersionSpec(versionRange); - return range.containsVersion(version); + return range.containsVersion(new DefaultArtifactVersion(version)); } catch(InvalidVersionSpecificationException ex) { return true; // better safe than sorry } diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MutableProjectRegistry.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MutableProjectRegistry.java index a2526c98..d7666cc9 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MutableProjectRegistry.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MutableProjectRegistry.java @@ -150,6 +150,17 @@ public class MutableProjectRegistry extends BasicProjectRegistry implements IPro * Returns all workspace projects that require given Capability. */ public Set<IFile> getDependents(Capability capability, boolean remove) { + return getDependents(capability, false, remove); + } + + /** + * Returns all workspace projects that require given Capability of a certain version, if available + */ + public Set<IFile> getVersionedDependents(Capability capability, boolean remove) { + return getDependents(capability, true, remove); + } + + private Set<IFile> getDependents(Capability capability, boolean versionMatch, boolean remove) { Map<RequiredCapability, Set<IFile>> rs = requiredCapabilities.get(capability.getVersionlessKey()); if(rs == null) { return Collections.emptySet(); @@ -158,7 +169,7 @@ public class MutableProjectRegistry extends BasicProjectRegistry implements IPro Iterator<Entry<RequiredCapability, Set<IFile>>> iter = rs.entrySet().iterator(); while(iter.hasNext()) { Entry<RequiredCapability, Set<IFile>> entry = iter.next(); - if(entry.getKey().isPotentialMatch(capability)) { + if(entry.getKey().isPotentialMatch(capability, versionMatch)) { result.addAll(entry.getValue()); if(remove) { iter.remove(); diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/ProjectRegistryManager.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/ProjectRegistryManager.java index 68070024..70ef883d 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/ProjectRegistryManager.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/ProjectRegistryManager.java @@ -317,12 +317,12 @@ public class ProjectRegistryManager { // TODO remove=false? Set<IFile> refresh = new LinkedHashSet<IFile>(); if(installedArtifacts.add(artifact)) { - refresh.addAll(newState.getDependents(MavenCapability.createMavenParent(artifact), true)); - refresh.addAll(newState.getDependents(MavenCapability.createMavenArtifact(artifact), true)); + refresh.addAll(newState.getVersionedDependents(MavenCapability.createMavenParent(artifact), true)); + refresh.addAll(newState.getVersionedDependents(MavenCapability.createMavenArtifact(artifact), true)); } if(installedArtifacts.add(baseArtifact)) { - refresh.addAll(newState.getDependents(MavenCapability.createMavenParent(baseArtifact), true)); - refresh.addAll(newState.getDependents(MavenCapability.createMavenArtifact(baseArtifact), true)); + refresh.addAll(newState.getVersionedDependents(MavenCapability.createMavenParent(baseArtifact), true)); + refresh.addAll(newState.getVersionedDependents(MavenCapability.createMavenArtifact(baseArtifact), true)); } if(!refresh.isEmpty()) { log.debug("Automatic refresh. artifact={}/{}. projects={}", new Object[] {baseArtifact, artifact, refresh}); @@ -371,7 +371,7 @@ public class ProjectRegistryManager { if(oldFacade != null) { // refresh old child modules MavenCapability mavenParentCapability = MavenCapability.createMavenParent(oldFacade.getArtifactKey()); - context.forcePomFiles(newState.getDependents(mavenParentCapability, true)); + context.forcePomFiles(newState.getVersionedDependents(mavenParentCapability, true)); } newFacade = readMavenProjectFacade(pom, context, newState, monitor); @@ -388,7 +388,7 @@ public class ProjectRegistryManager { if(newFacade != null) { // refresh new child modules MavenCapability mavenParentCapability = MavenCapability.createMavenParent(newFacade.getArtifactKey()); - context.forcePomFiles(newState.getDependents(mavenParentCapability, true)); + context.forcePomFiles(newState.getVersionedDependents(mavenParentCapability, true)); Set<Capability> capabilities = new LinkedHashSet<Capability>(); capabilities.add(mavenParentCapability); @@ -531,8 +531,18 @@ public class ProjectRegistryManager { } // if our capabilities changed, recalculate everyone who depends on new/changed/removed capabilities Set<Capability> changedCapabilities = diff(oldCapabilities, capabilities); + + // refresh versioned dependents if only parent capability has changed + boolean versionedCapabilitiesOnly = true; + for(Capability capability : changedCapabilities) { + if(MavenCapability.NS_MAVEN_ARTIFACT.equals(capability.getVersionlessKey().getNamespace())) { + versionedCapabilitiesOnly = false; + break; + } + } for(Capability capability : changedCapabilities) { - context.forcePomFiles(newState.getDependents(capability, true)); + context.forcePomFiles(versionedCapabilitiesOnly ? newState.getVersionedDependents(capability, true) : newState + .getDependents(capability, true)); } Set<RequiredCapability> oldRequirements = newState.setRequirements(pom, requirements); @@ -543,7 +553,7 @@ public class ProjectRegistryManager { // this is needed to deal with transitive dependency resolution in maven if(oldCapabilities != null && hasDiff(oldRequirements, requirements)) { for(Capability capability : oldCapabilities) { - context.forcePomFiles(newState.getDependents(capability.getVersionlessKey(), true)); + context.forcePomFiles(newState.getVersionedDependents(capability, true)); } } diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/RequiredCapability.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/RequiredCapability.java index 0adf2681..1a4ecd57 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/RequiredCapability.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/RequiredCapability.java @@ -40,9 +40,12 @@ public abstract class RequiredCapability implements Serializable { * Returns true if provided capability *potentially* satisfies this requirement. Capability/requirement match will be * used to check if workspace project changes (new/changed/remove projects and metadata changes) affect other * projects. isPotentialMatch Implementations should be good enough to avoid obviously pointless project dependency - * refreshes, but does not have to be perfectly precise. + * refreshes, but does not have to be perfectly precise.<br/> + * + * @param matchResolved is a hint that defines whether requirements can be narrowed down to a certain version of + * capability, e.g. resolved dependency */ - public abstract boolean isPotentialMatch(Capability capability); + public abstract boolean isPotentialMatch(Capability capability, boolean versionMatch); protected static <T> boolean eq(T a, T b) { return a != null ? a.equals(b) : b == null; |