org.gradle.internal.component.external.model.maven.DefaultMavenModuleResolveMetadata 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 2018 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.internal.component.external.model.maven;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
import org.gradle.api.internal.artifacts.repositories.metadata.MavenImmutableAttributesFactory;
import org.gradle.api.internal.model.NamedObjectInstantiator;
import org.gradle.internal.Factory;
import org.gradle.internal.component.external.descriptor.Configuration;
import org.gradle.internal.component.external.descriptor.MavenScope;
import org.gradle.internal.component.external.model.AbstractLazyModuleComponentResolveMetadata;
import org.gradle.internal.component.external.model.ConfigurationBoundExternalDependencyMetadata;
import org.gradle.internal.component.external.model.DefaultConfigurationMetadata;
import org.gradle.internal.component.external.model.ModuleComponentArtifactMetadata;
import org.gradle.internal.component.external.model.ModuleComponentResolveMetadata;
import org.gradle.internal.component.external.model.ModuleDependencyMetadata;
import org.gradle.internal.component.external.model.VariantDerivationStrategy;
import org.gradle.internal.component.external.model.VariantMetadataRules;
import org.gradle.internal.component.model.ConfigurationMetadata;
import org.gradle.internal.component.model.IvyArtifactName;
import org.gradle.internal.component.model.ModuleSources;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* {@link AbstractLazyModuleComponentResolveMetadata Lazy version} of a {@link MavenModuleResolveMetadata}.
*
* @see RealisedMavenModuleResolveMetadata
*/
public class DefaultMavenModuleResolveMetadata extends AbstractLazyModuleComponentResolveMetadata implements MavenModuleResolveMetadata {
public static final String POM_PACKAGING = "pom";
static final Set JAR_PACKAGINGS = ImmutableSet.of("jar", "ejb", "bundle", "maven-plugin", "eclipse-plugin");
private final NamedObjectInstantiator objectInstantiator;
private final MavenImmutableAttributesFactory mavenImmutableAttributesFactory;
private final ImmutableList dependencies;
private final String packaging;
private final boolean relocated;
private final String snapshotTimestamp;
private ImmutableList extends ConfigurationMetadata> derivedVariants;
private boolean filterConstraints = true;
private MavenDependencyDescriptor[] dependenciesAsArray;
DefaultMavenModuleResolveMetadata(DefaultMutableMavenModuleResolveMetadata metadata) {
super(metadata);
this.objectInstantiator = metadata.getObjectInstantiator();
this.mavenImmutableAttributesFactory = (MavenImmutableAttributesFactory) metadata.getAttributesFactory();
packaging = metadata.getPackaging();
relocated = metadata.isRelocated();
snapshotTimestamp = metadata.getSnapshotTimestamp();
dependencies = metadata.getDependencies();
}
private DefaultMavenModuleResolveMetadata(DefaultMavenModuleResolveMetadata metadata, ModuleSources sources, VariantDerivationStrategy derivationStrategy) {
super(metadata, sources, derivationStrategy);
this.objectInstantiator = metadata.objectInstantiator;
this.mavenImmutableAttributesFactory = metadata.mavenImmutableAttributesFactory;
packaging = metadata.packaging;
relocated = metadata.relocated;
snapshotTimestamp = metadata.snapshotTimestamp;
dependencies = metadata.dependencies;
copyCachedState(metadata, metadata.getVariantDerivationStrategy() != derivationStrategy);
}
@Override
protected DefaultConfigurationMetadata createConfiguration(ModuleComponentIdentifier componentId, String name, boolean transitive, boolean visible, ImmutableSet parents, VariantMetadataRules componentMetadataRules) {
ImmutableList extends ModuleComponentArtifactMetadata> artifacts = getArtifactsForConfiguration();
final DefaultConfigurationMetadata configuration = new DefaultConfigurationMetadata(componentId, name, transitive, visible, parents, artifacts, componentMetadataRules, ImmutableList.of(), getAttributes(), false);
configuration.setConfigDependenciesFactory(new Factory>() {
@Nullable
@Override
public List create() {
return filterDependencies(configuration);
}
});
return configuration;
}
@Override
protected Optional> maybeDeriveVariants() {
return Optional.fromNullable(getDerivedVariants());
}
private ImmutableList extends ConfigurationMetadata> getDerivedVariants() {
VariantDerivationStrategy strategy = getVariantDerivationStrategy();
if (derivedVariants == null && strategy.derivesVariants()) {
filterConstraints = false;
derivedVariants = strategy.derive(this);
}
return derivedVariants;
}
@Override
protected ConfigurationMetadata populateConfigurationFromDescriptor(String name, Map configurationDefinitions) {
DefaultConfigurationMetadata md = (DefaultConfigurationMetadata) super.populateConfigurationFromDescriptor(name, configurationDefinitions);
if (filterConstraints && md != null) {
// if the first call to getConfiguration is done before getDerivedVariants() is called
// then it means we're using the legacy matching, without attributes, and that the metadata
// we construct should _not_ include the constraints. We keep the constraints in the descriptors
// because if we actually use attribute matching, we can select the platform variant which
// does use constraints.
return md.mutate().withoutConstraints().build();
}
return md;
}
private ImmutableList extends ModuleComponentArtifactMetadata> getArtifactsForConfiguration() {
return RealisedMavenModuleResolveMetadata.getArtifactsForConfiguration(this);
}
private ImmutableList filterDependencies(DefaultConfigurationMetadata config) {
if (dependencies.isEmpty()) {
return ImmutableList.of();
}
int size = dependencies.size();
// If we're reaching this point, we're very likely going to iterate on the dependencies
// several times. It appears that iterating using `dependencies` is expensive because of
// the creation of an iterator and checking bounds. Iterating an array is faster.
if (dependenciesAsArray == null) {
dependenciesAsArray = dependencies.toArray(new MavenDependencyDescriptor[0]);
}
ImmutableList.Builder filteredDependencies = null;
boolean isOptionalConfiguration = "optional".equals(config.getName());
ImmutableSet hierarchy = config.getHierarchy();
for (MavenDependencyDescriptor dependency : dependenciesAsArray) {
if (isOptionalConfiguration && includeInOptionalConfiguration(dependency)) {
ModuleDependencyMetadata element = new OptionalConfigurationDependencyMetadata(config, getId(), dependency);
if (size == 1) {
return ImmutableList.of(element);
}
if (filteredDependencies == null) {
filteredDependencies = ImmutableList.builder();
}
filteredDependencies.add(element);
} else if (include(dependency, hierarchy)) {
ModuleDependencyMetadata element = contextualize(config, getId(), dependency);
if (size == 1) {
return ImmutableList.of(element);
}
if (filteredDependencies == null) {
filteredDependencies = ImmutableList.builder();
}
filteredDependencies.add(element);
}
}
return filteredDependencies == null ? ImmutableList.of() : filteredDependencies.build();
}
private ModuleDependencyMetadata contextualize(ConfigurationMetadata config, ModuleComponentIdentifier componentId, MavenDependencyDescriptor incoming) {
ConfigurationBoundExternalDependencyMetadata dependency = new ConfigurationBoundExternalDependencyMetadata(config, componentId, incoming);
dependency.alwaysUseAttributeMatching();
return dependency;
}
private boolean includeInOptionalConfiguration(MavenDependencyDescriptor dependency) {
MavenScope dependencyScope = dependency.getScope();
// Include all 'optional' dependencies in "optional" configuration
return dependency.isOptional()
&& dependencyScope != MavenScope.Test
&& dependencyScope != MavenScope.System;
}
private boolean include(MavenDependencyDescriptor dependency, Collection hierarchy) {
if (dependency.isOptional()) {
return false;
}
return hierarchy.contains(dependency.getScope().getLowerName());
}
@Override
public MutableMavenModuleResolveMetadata asMutable() {
return new DefaultMutableMavenModuleResolveMetadata(this, objectInstantiator);
}
@Override
public DefaultMavenModuleResolveMetadata withSources(ModuleSources sources) {
return new DefaultMavenModuleResolveMetadata(this, sources, getVariantDerivationStrategy());
}
@Override
public ModuleComponentResolveMetadata withDerivationStrategy(VariantDerivationStrategy derivationStrategy) {
if (getVariantDerivationStrategy() == derivationStrategy) {
return this;
}
return new DefaultMavenModuleResolveMetadata(this, getSources(), derivationStrategy);
}
@Override
public String getPackaging() {
return packaging;
}
@Override
public boolean isRelocated() {
return relocated;
}
@Override
public boolean isPomPackaging() {
return POM_PACKAGING.equals(packaging);
}
@Override
public boolean isKnownJarPackaging() {
return JAR_PACKAGINGS.contains(packaging);
}
public NamedObjectInstantiator getObjectInstantiator() {
return objectInstantiator;
}
@Override
@Nullable
public String getSnapshotTimestamp() {
return snapshotTimestamp;
}
@Override
public ImmutableList getDependencies() {
return dependencies;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}
DefaultMavenModuleResolveMetadata that = (DefaultMavenModuleResolveMetadata) o;
return relocated == that.relocated
&& Objects.equal(dependencies, that.dependencies)
&& Objects.equal(packaging, that.packaging)
&& Objects.equal(snapshotTimestamp, that.snapshotTimestamp);
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(),
dependencies,
packaging,
relocated,
snapshotTimestamp);
}
/**
* Adapts a MavenDependencyDescriptor to `DependencyMetadata` for the magic "optional" configuration.
*
* This configuration has special semantics:
* - Dependencies in the "optional" configuration are _never_ themselves optional (ie not 'pending')
* - Dependencies in the "optional" configuration can have dependency artifacts, even if the dependency is flagged as 'optional'.
* (For a standard configuration, any dependency flagged as 'optional' will have no dependency artifacts).
*/
static class OptionalConfigurationDependencyMetadata extends ConfigurationBoundExternalDependencyMetadata {
private final MavenDependencyDescriptor dependencyDescriptor;
OptionalConfigurationDependencyMetadata(ConfigurationMetadata configuration, ModuleComponentIdentifier componentId, MavenDependencyDescriptor delegate) {
super(configuration, componentId, delegate);
this.dependencyDescriptor = delegate;
}
/**
* Dependencies marked as optional/pending in the "optional" configuration _can_ have dependency artifacts.
*/
@Override
public List getArtifacts() {
IvyArtifactName dependencyArtifact = dependencyDescriptor.getDependencyArtifact();
return dependencyArtifact == null ? ImmutableList.of() : ImmutableList.of(dependencyArtifact);
}
/**
* Dependencies in the "optional" configuration are never 'pending'.
*/
@Override
public boolean isConstraint() {
return false;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy