Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.gradle.api.internalivyservice.dependencysubstitution.DefaultDependencySubstitutions Maven / Gradle / Ivy
/*
* Copyright 2015 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.api.internal.artifacts.ivyservice.dependencysubstitution;
import org.gradle.api.Action;
import org.gradle.api.artifacts.ArtifactSelectionDetails;
import org.gradle.api.artifacts.DependencyResolveDetails;
import org.gradle.api.artifacts.DependencySubstitution;
import org.gradle.api.artifacts.DependencySubstitutions;
import org.gradle.api.artifacts.ModuleDependencyCapabilitiesHandler;
import org.gradle.api.artifacts.ModuleIdentifier;
import org.gradle.api.artifacts.ModuleVersionSelector;
import org.gradle.api.artifacts.VariantSelectionDetails;
import org.gradle.api.artifacts.component.ComponentSelector;
import org.gradle.api.artifacts.component.ModuleComponentSelector;
import org.gradle.api.artifacts.component.ProjectComponentIdentifier;
import org.gradle.api.artifacts.component.ProjectComponentSelector;
import org.gradle.api.artifacts.result.ComponentSelectionDescriptor;
import org.gradle.api.attributes.AttributeContainer;
import org.gradle.api.attributes.Category;
import org.gradle.api.capabilities.Capability;
import org.gradle.api.internal.artifacts.ComponentSelectorConverter;
import org.gradle.api.internal.artifacts.DependencySubstitutionInternal;
import org.gradle.api.internal.artifacts.component.ComponentIdentifierFactory;
import org.gradle.api.internal.artifacts.configurations.MutationValidator;
import org.gradle.api.internal.artifacts.dependencies.DefaultMutableModuleDependencyCapabilitiesHandler;
import org.gradle.api.internal.artifacts.dependencies.ModuleDependencyCapabilitiesInternal;
import org.gradle.api.internal.artifacts.ivyservice.resolveengine.result.ComponentSelectionDescriptorInternal;
import org.gradle.api.internal.artifacts.ivyservice.resolveengine.result.ComponentSelectionReasons;
import org.gradle.api.internal.attributes.AttributeContainerInternal;
import org.gradle.api.internal.attributes.ImmutableAttributesFactory;
import org.gradle.api.model.ObjectFactory;
import org.gradle.internal.Actions;
import org.gradle.internal.Describables;
import org.gradle.internal.build.IncludedBuildState;
import org.gradle.internal.component.external.model.DefaultModuleComponentSelector;
import org.gradle.internal.component.local.model.DefaultProjectComponentSelector;
import org.gradle.internal.exceptions.DiagnosticsVisitor;
import org.gradle.internal.reflect.Instantiator;
import org.gradle.internal.typeconversion.NotationConvertResult;
import org.gradle.internal.typeconversion.NotationConverter;
import org.gradle.internal.typeconversion.NotationParser;
import org.gradle.internal.typeconversion.NotationParserBuilder;
import org.gradle.internal.typeconversion.TypeConversionException;
import org.gradle.util.Path;
import javax.inject.Inject;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
public class DefaultDependencySubstitutions implements DependencySubstitutionsInternal {
private final Set> substitutionRules;
private final NotationParser moduleSelectorNotationParser;
private final NotationParser projectSelectorNotationParser;
private final ComponentSelectionDescriptor reason;
private final Instantiator instantiator;
private final ObjectFactory objectFactory;
private final ImmutableAttributesFactory attributesFactory;
private final NotationParser capabilityNotationParser;
private MutationValidator mutationValidator = MutationValidator.IGNORE;
private boolean rulesMayAddProjectDependency;
public static DefaultDependencySubstitutions forResolutionStrategy(ComponentIdentifierFactory componentIdentifierFactory,
NotationParser moduleSelectorNotationParser,
Instantiator instantiator,
ObjectFactory objectFactory,
ImmutableAttributesFactory attributesFactory,
NotationParser capabilityNotationParser) {
NotationParser projectSelectorNotationParser = NotationParserBuilder
.toType(ComponentSelector.class)
.fromCharSequence(new ProjectPathConverter(componentIdentifierFactory))
.toComposite();
return instantiator.newInstance(DefaultDependencySubstitutions.class,
ComponentSelectionReasons.SELECTED_BY_RULE,
projectSelectorNotationParser,
moduleSelectorNotationParser,
instantiator,
objectFactory,
attributesFactory,
capabilityNotationParser);
}
public static DefaultDependencySubstitutions forIncludedBuild(IncludedBuildState build,
Instantiator instantiator,
ObjectFactory objectFactory,
ImmutableAttributesFactory attributesFactory,
NotationParser moduleSelectorNotationParser,
NotationParser capabilityNotationParser) {
NotationParser projectSelectorNotationParser = NotationParserBuilder
.toType(ComponentSelector.class)
.fromCharSequence(new CompositeProjectPathConverter(build))
.toComposite();
return instantiator.newInstance(CompositeBuildAwareSubstitutions.class, projectSelectorNotationParser, moduleSelectorNotationParser, instantiator, objectFactory, attributesFactory, capabilityNotationParser, build);
}
@Inject
public DefaultDependencySubstitutions(ComponentSelectionDescriptor reason,
NotationParser projectSelectorNotationParser,
NotationParser moduleSelectorNotationParser,
Instantiator instantiator,
ObjectFactory objectFactory,
ImmutableAttributesFactory attributesFactory,
NotationParser capabilityNotationParser) {
this(reason, new LinkedHashSet<>(), moduleSelectorNotationParser, projectSelectorNotationParser, instantiator, objectFactory, attributesFactory, capabilityNotationParser);
}
private DefaultDependencySubstitutions(ComponentSelectionDescriptor reason,
Set> substitutionRules,
NotationParser moduleSelectorNotationParser,
NotationParser projectSelectorNotationParser,
Instantiator instantiator,
ObjectFactory objectFactory,
ImmutableAttributesFactory attributesFactory,
NotationParser capabilityNotationParser) {
this.reason = reason;
this.substitutionRules = substitutionRules;
this.moduleSelectorNotationParser = moduleSelectorNotationParser;
this.projectSelectorNotationParser = projectSelectorNotationParser;
this.instantiator = instantiator;
this.objectFactory = objectFactory;
this.attributesFactory = attributesFactory;
this.capabilityNotationParser = capabilityNotationParser;
}
@Override
public boolean rulesMayAddProjectDependency() {
return rulesMayAddProjectDependency;
}
@Override
public Action getRuleAction() {
return Actions.composite(substitutionRules);
}
protected void addSubstitution(Action rule, boolean projectInvolved) {
addRule(rule);
if (projectInvolved) {
rulesMayAddProjectDependency = true;
}
}
private void addRule(Action rule) {
mutationValidator.validateMutation(MutationValidator.MutationType.STRATEGY);
substitutionRules.add(rule);
}
@Override
public DependencySubstitutions all(Action rule) {
addRule(rule);
rulesMayAddProjectDependency = true;
return this;
}
@Override
public DependencySubstitutions allWithDependencyResolveDetails(Action rule, ComponentSelectorConverter componentSelectorConverter) {
addRule(new DependencyResolveDetailsWrapperAction(rule, componentSelectorConverter, Actions::doNothing, instantiator));
return this;
}
@Override
public ComponentSelector module(String notation) {
return moduleSelectorNotationParser.parseNotation(notation);
}
@Override
public ComponentSelector project(final String path) {
return projectSelectorNotationParser.parseNotation(path);
}
@Override
public ComponentSelector platform(ComponentSelector selector) {
return variant(selector, VariantSelectionDetails::platform);
}
@Override
public ComponentSelector variant(ComponentSelector selector, Action detailsAction) {
DefaultVariantSelectionDetails details = instantiator.newInstance(DefaultVariantSelectionDetails.class,
attributesFactory,
objectFactory,
capabilityNotationParser,
instantiator,
selector);
detailsAction.execute(details);
return details.selector;
}
@Override
public Substitution substitute(final ComponentSelector substituted) {
return new Substitution() {
Action artifactAction = Actions.doNothing();
ComponentSelectionDescriptorInternal substitutionReason = (ComponentSelectionDescriptorInternal) reason;
@Override
public Substitution because(String description) {
substitutionReason = substitutionReason.withDescription(Describables.of(description));
return this;
}
@Override
public Substitution withClassifier(String classifier) {
artifactAction = Actions.composite(artifactAction, new SetClassifier(classifier));
return this;
}
@Override
public Substitution withoutClassifier() {
artifactAction = Actions.composite(artifactAction, NoClassifier.INSTANCE);
return this;
}
@Override
public Substitution withoutArtifactSelectors() {
artifactAction = Actions.composite(artifactAction, NoArtifactSelector.INSTANCE);
return this;
}
@Override
public Substitution using(ComponentSelector notation) {
with(notation);
return this;
}
@Override
public void with(ComponentSelector substitute) {
DefaultDependencySubstitution.validateTarget(substitute);
boolean projectInvolved = false;
if (substituted instanceof ProjectComponentSelector || substitute instanceof ProjectComponentSelector) {
// A project is involved, need to be aware of it
projectInvolved = true;
}
if (substituted instanceof UnversionedModuleComponentSelector) {
final ModuleIdentifier moduleId = ((UnversionedModuleComponentSelector) substituted).getModuleIdentifier();
if (substitute instanceof ModuleComponentSelector) {
if (((ModuleComponentSelector) substitute).getModuleIdentifier().equals(moduleId)) {
// This substitution is effectively a force
substitutionReason = substitutionReason.markAsEquivalentToForce();
}
}
addSubstitution(new ModuleMatchDependencySubstitutionAction(substitutionReason, moduleId, substitute, () -> artifactAction), projectInvolved);
} else {
addSubstitution(new ExactMatchDependencySubstitutionAction(substitutionReason, substituted, substitute, () -> artifactAction), projectInvolved);
}
}
};
}
@Override
public void setMutationValidator(MutationValidator validator) {
mutationValidator = validator;
}
@Override
public DependencySubstitutionsInternal copy() {
return new DefaultDependencySubstitutions(
reason,
new LinkedHashSet<>(substitutionRules),
moduleSelectorNotationParser,
projectSelectorNotationParser,
instantiator,
objectFactory,
attributesFactory,
capabilityNotationParser);
}
private static class ProjectPathConverter implements NotationConverter {
private final ComponentIdentifierFactory componentIdentifierFactory;
private ProjectPathConverter(ComponentIdentifierFactory componentIdentifierFactory) {
this.componentIdentifierFactory = componentIdentifierFactory;
}
@Override
public void describe(DiagnosticsVisitor visitor) {
visitor.example("Project paths, e.g. ':api'.");
}
@Override
public void convert(String notation, NotationConvertResult result) throws TypeConversionException {
result.converted(componentIdentifierFactory.createProjectComponentSelector(notation));
}
}
private static class CompositeProjectPathConverter implements NotationConverter {
private final IncludedBuildState build;
private CompositeProjectPathConverter(IncludedBuildState build) {
this.build = build;
}
@Override
public void describe(DiagnosticsVisitor visitor) {
visitor.example("Project paths, e.g. ':api'.");
}
@Override
public void convert(String notation, NotationConvertResult result) throws TypeConversionException {
result.converted(DefaultProjectComponentSelector.newSelector(identifierForProject(build, notation)));
}
static ProjectComponentIdentifier identifierForProject(IncludedBuildState build, String notation) {
return build.getIdentifierForProject(Path.path(notation));
}
}
private static class CompositeBuildSubstitutionAction implements Action {
private final Action delegate;
private final IncludedBuildState build;
private CompositeBuildSubstitutionAction(Action delegate, IncludedBuildState build) {
this.delegate = delegate;
this.build = build;
}
@Override
public void execute(DependencySubstitution dependencySubstitution) {
DependencySubstitutionInternal ds = (DependencySubstitutionInternal) dependencySubstitution;
delegate.execute(new DependencySubstitutionInternal() {
@Override
public ComponentSelector getTarget() {
return ds.getTarget();
}
@Override
public List getRuleDescriptors() {
return ds.getRuleDescriptors();
}
@Override
public boolean isUpdated() {
return ds.isUpdated();
}
@Override
public ArtifactSelectionDetailsInternal getArtifactSelectionDetails() {
return ds.getArtifactSelectionDetails();
}
@Override
public ComponentSelector getRequested() {
return ds.getRequested();
}
// Implicitly set the substituted dependency attributes as the target dependency attributes
private Object addImplicitRequestAttributesAndCapabilities(Object notation) {
if (notation instanceof ProjectComponentSelector) {
ProjectComponentIdentifier id = CompositeProjectPathConverter.identifierForProject(build, ((ProjectComponentSelector) notation).getProjectPath());
ComponentSelector requested = getRequested();
return DefaultProjectComponentSelector.newSelector(
id,
((AttributeContainerInternal) requested.getAttributes()).asImmutable(),
requested.getRequestedCapabilities()
);
}
return notation;
}
@Override
public void useTarget(Object notation, ComponentSelectionDescriptor ruleDescriptor) {
ds.useTarget(addImplicitRequestAttributesAndCapabilities(notation), ruleDescriptor);
}
@Override
public void useTarget(Object notation) {
ds.useTarget(addImplicitRequestAttributesAndCapabilities(notation));
}
@Override
public void useTarget(Object notation, String reason) {
ds.useTarget(addImplicitRequestAttributesAndCapabilities(notation), reason);
}
@Override
public void artifactSelection(Action action) {
ds.artifactSelection(action);
}
});
}
}
private abstract static class AbstractDependencySubstitutionAction implements Action {
private final Supplier> artifactSelectionAction;
protected AbstractDependencySubstitutionAction(Supplier> artifactSelectionAction) {
this.artifactSelectionAction = artifactSelectionAction;
}
@Override
public void execute(DependencySubstitution dependencySubstitution) {
dependencySubstitution.artifactSelection(artifactSelectionAction.get());
}
}
private static class ExactMatchDependencySubstitutionAction extends AbstractDependencySubstitutionAction {
private final ComponentSelectionDescriptorInternal selectionReason;
private final ComponentSelector substituted;
private final ComponentSelector substitute;
public ExactMatchDependencySubstitutionAction(ComponentSelectionDescriptorInternal selectionReason, ComponentSelector substituted, ComponentSelector substitute, Supplier> artifactSelectionAction) {
super(artifactSelectionAction);
this.selectionReason = selectionReason;
this.substituted = substituted;
this.substitute = substitute;
}
@Override
public void execute(DependencySubstitution dependencySubstitution) {
if (substituted.equals(dependencySubstitution.getRequested())) {
super.execute(dependencySubstitution);
((DependencySubstitutionInternal) dependencySubstitution).useTarget(substitute, selectionReason);
}
}
}
private static class ModuleMatchDependencySubstitutionAction extends AbstractDependencySubstitutionAction {
private final ComponentSelectionDescriptorInternal selectionReason;
private final ModuleIdentifier moduleId;
private final ComponentSelector substitute;
public ModuleMatchDependencySubstitutionAction(ComponentSelectionDescriptorInternal selectionReason, ModuleIdentifier moduleId, ComponentSelector substitute, Supplier> artifactSelectionAction) {
super(artifactSelectionAction);
this.selectionReason = selectionReason;
this.moduleId = moduleId;
this.substitute = substitute;
}
@Override
public void execute(DependencySubstitution dependencySubstitution) {
if (dependencySubstitution.getRequested() instanceof ModuleComponentSelector) {
ModuleComponentSelector requested = (ModuleComponentSelector) dependencySubstitution.getRequested();
if (moduleId.equals(requested.getModuleIdentifier())) {
super.execute(dependencySubstitution);
((DependencySubstitutionInternal) dependencySubstitution).useTarget(substitute, selectionReason);
}
}
}
}
private static class DependencyResolveDetailsWrapperAction extends AbstractDependencySubstitutionAction {
private final Action delegate;
private final ComponentSelectorConverter componentSelectorConverter;
private final Instantiator instantiator;
public DependencyResolveDetailsWrapperAction(Action delegate, ComponentSelectorConverter componentSelectorConverter, Supplier> artifactSelectionAction, Instantiator instantiator) {
super(artifactSelectionAction);
this.delegate = delegate;
this.componentSelectorConverter = componentSelectorConverter;
this.instantiator = instantiator;
}
@Override
public void execute(DependencySubstitution substitution) {
super.execute(substitution);
ModuleVersionSelector requested = componentSelectorConverter.getSelector(substitution.getRequested());
DefaultDependencyResolveDetails details = instantiator.newInstance(DefaultDependencyResolveDetails.class, substitution, requested);
delegate.execute(details);
details.complete();
}
}
private static class SetClassifier implements Action {
private final String classifier;
public SetClassifier(String classifier) {
this.classifier = classifier;
}
@Override
public void execute(ArtifactSelectionDetails artifactSelectionDetails) {
artifactSelectionDetails.selectArtifact("jar", null, classifier);
}
}
private static class NoClassifier implements Action {
private static final NoClassifier INSTANCE = new NoClassifier();
@Override
public void execute(ArtifactSelectionDetails artifactSelectionDetails) {
artifactSelectionDetails.selectArtifact("jar", null, null);
}
}
private static class NoArtifactSelector implements Action {
private static final NoArtifactSelector INSTANCE = new NoArtifactSelector();
@Override
public void execute(ArtifactSelectionDetails artifactSelectionDetails) {
artifactSelectionDetails.withoutArtifactSelectors();
}
}
public static class DefaultVariantSelectionDetails implements VariantSelectionDetails {
private final ImmutableAttributesFactory attributesFactory;
private final ObjectFactory objectFactory;
private final NotationParser capabilityNotationParser;
private final Instantiator instantatior;
private ComponentSelector selector;
@Inject
public DefaultVariantSelectionDetails(ImmutableAttributesFactory attributesFactory,
ObjectFactory objectFactory,
NotationParser capabilityNotationParser,
Instantiator instantatior,
ComponentSelector selector) {
this.attributesFactory = attributesFactory;
this.objectFactory = objectFactory;
this.capabilityNotationParser = capabilityNotationParser;
this.instantatior = instantatior;
this.selector = selector;
}
private void createComponentOfCategory(String category) {
if (selector instanceof ProjectComponentSelector) {
AttributeContainerInternal container = createCategory(category);
selector = DefaultProjectComponentSelector.withAttributes((ProjectComponentSelector) selector, container.asImmutable());
} else if (selector instanceof ModuleComponentSelector) {
AttributeContainerInternal container = createCategory(category);
selector = DefaultModuleComponentSelector.withAttributes((ModuleComponentSelector) selector, container.asImmutable());
}
}
private AttributeContainerInternal createCategory(String category) {
return (AttributeContainerInternal) attributesFactory.mutable()
.attribute(Category.CATEGORY_ATTRIBUTE, objectFactory.named(Category.class, category));
}
@Override
public void platform() {
createComponentOfCategory(Category.REGULAR_PLATFORM);
}
@Override
public void enforcedPlatform() {
createComponentOfCategory(Category.ENFORCED_PLATFORM);
}
@Override
public void library() {
createComponentOfCategory(Category.LIBRARY);
}
@Override
public void attributes(Action configurationAction) {
AttributeContainerInternal container = attributesFactory.mutable();
configurationAction.execute(container);
if (selector instanceof ProjectComponentSelector) {
selector = DefaultProjectComponentSelector.withAttributes((ProjectComponentSelector) selector, container.asImmutable());
} else if (selector instanceof ModuleComponentSelector) {
selector = DefaultModuleComponentSelector.withAttributes((ModuleComponentSelector) selector, container.asImmutable());
}
}
@Override
public void capabilities(Action configurationAction) {
ModuleDependencyCapabilitiesInternal handler = instantatior.newInstance(DefaultMutableModuleDependencyCapabilitiesHandler.class,
capabilityNotationParser
);
configurationAction.execute(handler);
if (selector instanceof ProjectComponentSelector) {
selector = DefaultProjectComponentSelector.withCapabilities((ProjectComponentSelector) selector, handler.getRequestedCapabilities());
} else if (selector instanceof ModuleComponentSelector) {
selector = DefaultModuleComponentSelector.withCapabilities((ModuleComponentSelector) selector, handler.getRequestedCapabilities());
}
}
}
public static class CompositeBuildAwareSubstitutions extends DefaultDependencySubstitutions {
private final IncludedBuildState build;
@Inject
public CompositeBuildAwareSubstitutions(NotationParser projectSelectorNotationParser, NotationParser moduleIdentifierFactory, Instantiator instantiator, ObjectFactory objectFactory, ImmutableAttributesFactory attributesFactory, NotationParser capabilityNotationParser, IncludedBuildState build) {
super(ComponentSelectionReasons.COMPOSITE_BUILD, projectSelectorNotationParser, moduleIdentifierFactory, instantiator, objectFactory, attributesFactory, capabilityNotationParser);
this.build = build;
}
@Override
protected void addSubstitution(Action rule, boolean projectInvolved) {
CompositeBuildSubstitutionAction decorated = new CompositeBuildSubstitutionAction(rule, build);
super.addSubstitution(decorated, projectInvolved);
}
}
}