org.gradle.plugins.ide.internal.resolver.IdeDependencySet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-api Show documentation
Show all versions of gradle-api Show documentation
Gradle 6.9.1 API redistribution.
/*
* Copyright 2017 the original author or authors.
*
* Licensed 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.gradle.plugins.ide.internal.resolver;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
import org.gradle.api.Action;
import org.gradle.api.artifacts.ArtifactCollection;
import org.gradle.api.artifacts.ArtifactView;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.component.ComponentArtifactIdentifier;
import org.gradle.api.artifacts.component.ComponentIdentifier;
import org.gradle.api.artifacts.component.ComponentSelector;
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
import org.gradle.api.artifacts.component.ProjectComponentIdentifier;
import org.gradle.api.artifacts.dsl.DependencyHandler;
import org.gradle.api.artifacts.result.ArtifactResolutionResult;
import org.gradle.api.artifacts.result.ArtifactResult;
import org.gradle.api.artifacts.result.ComponentArtifactsResult;
import org.gradle.api.artifacts.result.ResolvedArtifactResult;
import org.gradle.api.artifacts.result.UnresolvedDependencyResult;
import org.gradle.api.component.Artifact;
import org.gradle.api.specs.Spec;
import org.gradle.api.specs.Specs;
import org.gradle.jvm.JvmLibrary;
import org.gradle.language.base.artifact.SourcesArtifact;
import org.gradle.language.java.artifact.JavadocArtifact;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Adapts Gradle's dependency resolution engine to the special needs of the IDE plugins.
* Allows adding and subtracting {@link Configuration}s, working in offline mode and downloading sources/javadoc.
*/
public class IdeDependencySet {
private final DependencyHandler dependencyHandler;
private final Collection plusConfigurations;
private final Collection minusConfigurations;
public IdeDependencySet(DependencyHandler dependencyHandler, Collection plusConfigurations, Collection minusConfigurations) {
this.dependencyHandler = dependencyHandler;
this.plusConfigurations = plusConfigurations;
this.minusConfigurations = minusConfigurations;
}
public void visit(IdeDependencyVisitor visitor) {
if (plusConfigurations.isEmpty()) {
return;
}
new IdeDependencyResult().visit(visitor);
}
/*
* Tries to minimize the number of requests to the resolution engine by batching up requests
* for sources/javadoc.
*
* There is still some inefficiency because the ArtifactCollection interface does not provide
* detailed failure results, so we have to fall back to the more expensive ResolutionResult API.
* We should fix this, as other IDE vendors will face the same problem.
*/
private class IdeDependencyResult {
private final Map resolvedArtifacts = Maps.newLinkedHashMap();
private final Map unresolvedDependencies = Maps.newLinkedHashMap();
private final Table, Set> auxiliaryArtifacts = HashBasedTable.create();
public void visit(IdeDependencyVisitor visitor) {
resolvePlusConfigurations(visitor);
resolveMinusConfigurations(visitor);
resolveAuxiliaryArtifacts(visitor);
visitArtifacts(visitor);
visitUnresolvedDependencies(visitor);
}
private void resolvePlusConfigurations(IdeDependencyVisitor visitor) {
for (Configuration configuration : plusConfigurations) {
ArtifactCollection artifacts = getResolvedArtifacts(configuration, visitor);
for (ResolvedArtifactResult resolvedArtifact : artifacts) {
resolvedArtifacts.put(resolvedArtifact.getId(), resolvedArtifact);
}
if (artifacts.getFailures().isEmpty()) {
continue;
}
for (UnresolvedDependencyResult unresolvedDependency : getUnresolvedDependencies(configuration, visitor)) {
unresolvedDependencies.put(unresolvedDependency.getAttempted(), unresolvedDependency);
}
}
}
private void resolveMinusConfigurations(IdeDependencyVisitor visitor) {
for (Configuration configuration : minusConfigurations) {
ArtifactCollection artifacts = getResolvedArtifacts(configuration, visitor);
for (ResolvedArtifactResult resolvedArtifact : artifacts) {
resolvedArtifacts.remove(resolvedArtifact.getId());
}
if (artifacts.getFailures().isEmpty()) {
continue;
}
for (UnresolvedDependencyResult unresolvedDependency : getUnresolvedDependencies(configuration, visitor)) {
unresolvedDependencies.remove(unresolvedDependency.getAttempted());
}
}
}
private ArtifactCollection getResolvedArtifacts(Configuration configuration, final IdeDependencyVisitor visitor) {
return configuration.getIncoming().artifactView(new Action() {
@Override
public void execute(ArtifactView.ViewConfiguration viewConfiguration) {
viewConfiguration.lenient(true);
viewConfiguration.componentFilter(getComponentFilter(visitor));
}
}).getArtifacts();
}
private Spec getComponentFilter(IdeDependencyVisitor visitor) {
return visitor.isOffline() ? NOT_A_MODULE : Specs.satisfyAll();
}
private Iterable getUnresolvedDependencies(Configuration configuration, IdeDependencyVisitor visitor) {
if (visitor.isOffline()) {
return Collections.emptySet();
}
return Iterables.filter(configuration.getIncoming().getResolutionResult().getRoot().getDependencies(), UnresolvedDependencyResult.class);
}
private void resolveAuxiliaryArtifacts(IdeDependencyVisitor visitor) {
if (visitor.isOffline()) {
return;
}
Set componentIdentifiers = getModuleComponentIdentifiers();
if (componentIdentifiers.isEmpty()) {
return;
}
List> types = getAuxiliaryArtifactTypes(visitor);
if (types.isEmpty()) {
return;
}
ArtifactResolutionResult result = dependencyHandler.createArtifactResolutionQuery()
.forComponents(componentIdentifiers)
.withArtifacts(JvmLibrary.class, types)
.execute();
for (ComponentArtifactsResult artifactsResult : result.getResolvedComponents()) {
for (Class extends Artifact> type : types) {
Set resolvedArtifactResults = Sets.newLinkedHashSet();
for (ArtifactResult artifactResult : artifactsResult.getArtifacts(type)) {
if (artifactResult instanceof ResolvedArtifactResult) {
resolvedArtifactResults.add((ResolvedArtifactResult) artifactResult);
}
}
auxiliaryArtifacts.put((ModuleComponentIdentifier) artifactsResult.getId(), type, resolvedArtifactResults);
}
}
}
private Set getModuleComponentIdentifiers() {
Set componentIdentifiers = Sets.newLinkedHashSet();
for (ComponentArtifactIdentifier identifier : resolvedArtifacts.keySet()) {
ComponentIdentifier componentIdentifier = identifier.getComponentIdentifier();
if (componentIdentifier instanceof ModuleComponentIdentifier) {
componentIdentifiers.add((ModuleComponentIdentifier) componentIdentifier);
}
}
return componentIdentifiers;
}
private List> getAuxiliaryArtifactTypes(IdeDependencyVisitor visitor) {
List> types = Lists.newArrayListWithCapacity(2);
if (visitor.downloadSources()) {
types.add(SourcesArtifact.class);
}
if (visitor.downloadJavaDoc()) {
types.add(JavadocArtifact.class);
}
return types;
}
private void visitArtifacts(IdeDependencyVisitor visitor) {
for (ResolvedArtifactResult artifact : resolvedArtifacts.values()) {
ComponentIdentifier componentIdentifier = artifact.getId().getComponentIdentifier();
if (componentIdentifier instanceof ProjectComponentIdentifier) {
visitor.visitProjectDependency(artifact);
} else if (componentIdentifier instanceof ModuleComponentIdentifier) {
Set sources = auxiliaryArtifacts.get(componentIdentifier, SourcesArtifact.class);
sources = sources != null ? sources : Collections.emptySet();
Set javaDoc = auxiliaryArtifacts.get(componentIdentifier, JavadocArtifact.class);
javaDoc = javaDoc != null ? javaDoc : Collections.emptySet();
visitor.visitModuleDependency(artifact, sources, javaDoc);
} else {
visitor.visitFileDependency(artifact);
}
}
}
private void visitUnresolvedDependencies(IdeDependencyVisitor visitor) {
for (UnresolvedDependencyResult unresolvedDependency : unresolvedDependencies.values()) {
visitor.visitUnresolvedDependency(unresolvedDependency);
}
}
}
private static final Spec NOT_A_MODULE = new Spec() {
@Override
public boolean isSatisfiedBy(ComponentIdentifier id) {
return !(id instanceof ModuleComponentIdentifier);
}
};
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy