org.gradle.api.publication.maven.internal.pom.DefaultPomDependenciesConverter 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 2010 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.publication.maven.internal.pom;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Exclusion;
import org.gradle.api.GradleException;
import org.gradle.api.artifacts.*;
import org.gradle.api.artifacts.maven.Conf2ScopeMapping;
import org.gradle.api.artifacts.maven.Conf2ScopeMappingContainer;
import org.gradle.api.publication.maven.internal.VersionRangeMapper;
import java.util.*;
import static com.google.common.base.Strings.emptyToNull;
class DefaultPomDependenciesConverter implements PomDependenciesConverter {
private static final List EXCLUDE_ALL = initExcludeAll();
private ExcludeRuleConverter excludeRuleConverter;
private VersionRangeMapper versionRangeMapper;
public DefaultPomDependenciesConverter(ExcludeRuleConverter excludeRuleConverter, VersionRangeMapper versionRangeMapper) {
this.excludeRuleConverter = excludeRuleConverter;
this.versionRangeMapper = versionRangeMapper;
}
public List convert(Conf2ScopeMappingContainer conf2ScopeMappingContainer, Set configurations) {
Map> dependencyToConfigurations = createDependencyToConfigurationsMap(configurations);
Map dependenciesMap = createDependencyToScopeMap(conf2ScopeMappingContainer, dependencyToConfigurations);
Map dependenciesWithPriorities = new LinkedHashMap();
for (ModuleDependency dependency : dependenciesMap.keySet()) {
Conf2ScopeMapping conf2ScopeMapping = dependenciesMap.get(dependency);
String scope = conf2ScopeMapping.getScope();
Integer priority = conf2ScopeMapping.getPriority() == null ? 0 : conf2ScopeMapping.getPriority();
Set dependencyConfigurations = dependencyToConfigurations.get(dependency);
if (dependency.getArtifacts().size() == 0) {
addFromDependencyDescriptor(dependenciesWithPriorities, dependency, scope, priority, dependencyConfigurations);
} else {
addFromArtifactDescriptor(dependenciesWithPriorities, dependency, scope, priority, dependencyConfigurations);
}
}
return new ArrayList(dependenciesWithPriorities.keySet());
}
private Map createDependencyToScopeMap(Conf2ScopeMappingContainer conf2ScopeMappingContainer,
Map> dependencyToConfigurations) {
Map dependencyToScope = new LinkedHashMap();
for (ModuleDependency dependency : dependencyToConfigurations.keySet()) {
Conf2ScopeMapping conf2ScopeDependencyMapping = conf2ScopeMappingContainer.getMapping(dependencyToConfigurations.get(dependency));
if (!useScope(conf2ScopeMappingContainer, conf2ScopeDependencyMapping)) {
continue;
}
dependencyToScope.put(findDependency(dependency, conf2ScopeDependencyMapping.getConfiguration()), conf2ScopeDependencyMapping);
}
return dependencyToScope;
}
private ModuleDependency findDependency(ModuleDependency dependency, Configuration configuration) {
for (ModuleDependency configurationDependency : configuration.getDependencies().withType(ModuleDependency.class)) {
if (dependency.equals(configurationDependency)) {
return configurationDependency;
}
}
throw new GradleException("Dependency could not be found. We should never get here!");
}
private boolean useScope(Conf2ScopeMappingContainer conf2ScopeMappingContainer, Conf2ScopeMapping conf2ScopeMapping) {
return conf2ScopeMapping.getScope() != null || !conf2ScopeMappingContainer.isSkipUnmappedConfs();
}
private Map> createDependencyToConfigurationsMap(Set configurations) {
Map> dependencySetMap = new LinkedHashMap>();
for (Configuration configuration : configurations) {
for (ModuleDependency dependency : configuration.getDependencies().withType(ModuleDependency.class)) {
if (dependencySetMap.get(dependency) == null) {
dependencySetMap.put(dependency, new HashSet());
}
dependencySetMap.get(dependency).add(configuration);
}
}
return dependencySetMap;
}
private void addFromArtifactDescriptor(Map dependenciesPriorityMap,
ModuleDependency dependency, String scope, Integer priority,
Set configurations) {
for (DependencyArtifact artifact : dependency.getArtifacts()) {
addMavenDependencies(dependenciesPriorityMap, dependency, artifact.getName(), artifact.getType(), scope, artifact.getClassifier(), priority, configurations);
}
}
private void addFromDependencyDescriptor(Map dependenciesPriorityMap,
ModuleDependency dependency, String scope, Integer priority,
Set configurations) {
addMavenDependencies(dependenciesPriorityMap, dependency, dependency.getName(), null, scope, null, priority, configurations);
}
private static Configuration getTargetConfiguration(ProjectDependency dependency) {
// todo CC: check that it ok to do this if configurations have attributes
String targetConfiguration = dependency.getTargetConfiguration();
if (targetConfiguration == null) {
targetConfiguration = org.gradle.api.artifacts.Dependency.DEFAULT_CONFIGURATION;
}
return dependency.getDependencyProject().getConfigurations().getByName(targetConfiguration);
}
private void addMavenDependencies(Map dependenciesWithPriorities,
ModuleDependency dependency, String name, String type, String scope, String classifier, Integer priority,
Set configurations) {
List mavenDependencies = new ArrayList();
if (dependency instanceof ProjectDependency) {
ProjectDependency projectDependency = (ProjectDependency) dependency;
final String artifactId = determineProjectDependencyArtifactId((ProjectDependency) dependency);
Configuration dependencyConfig = getTargetConfiguration(projectDependency);
for (PublishArtifact artifactToPublish : dependencyConfig.getAllArtifacts()) {
Dependency mavenDependency = new Dependency();
mavenDependency.setArtifactId(artifactId);
if (artifactToPublish.getClassifier() != null && !artifactToPublish.getClassifier().equals("")) {
mavenDependency.setClassifier(artifactToPublish.getClassifier());
}
mavenDependencies.add(mavenDependency);
}
} else {
Dependency mavenDependency = new Dependency();
mavenDependency.setArtifactId(name);
mavenDependency.setClassifier(classifier);
mavenDependencies.add(mavenDependency);
}
for (Dependency mavenDependency : mavenDependencies) {
mavenDependency.setGroupId(dependency.getGroup());
mavenDependency.setVersion(mapToMavenSyntax(dependency.getVersion()));
mavenDependency.setType(type);
mavenDependency.setScope(scope);
mavenDependency.setExclusions(getExclusions(dependency, configurations));
// Dependencies de-duplication
Optional duplicateDependency = findEqualIgnoreScopeVersionAndExclusions(dependenciesWithPriorities.keySet(), mavenDependency);
if (!duplicateDependency.isPresent()) {
// Add if absent
dependenciesWithPriorities.put(mavenDependency, priority);
} else {
// Use highest version on highest scope, keep highest scope exclusions only
int duplicatePriority = dependenciesWithPriorities.get(duplicateDependency.get());
boolean samePriority = priority == duplicatePriority;
boolean higherPriority = priority > duplicatePriority;
boolean higherVersion = compareMavenVersionStrings(mavenDependency.getVersion(), duplicateDependency.get().getVersion()) > 0;
if (higherPriority || higherVersion) {
// Replace if higher priority or version with highest priority and version
dependenciesWithPriorities.remove(duplicateDependency.get());
if (!higherPriority) {
// Lower or equal priority but higher version, keep higher scope and exclusions
mavenDependency.setScope(duplicateDependency.get().getScope());
if (!samePriority) {
mavenDependency.setExclusions(duplicateDependency.get().getExclusions());
}
}
int highestPriority = higherPriority ? priority : duplicatePriority;
dependenciesWithPriorities.put(mavenDependency, highestPriority);
}
}
}
}
private int compareMavenVersionStrings(String dependencyVersionString, String duplicateVersionString) {
String dependencyVersion = emptyToNull(dependencyVersionString);
String duplicateVersion = emptyToNull(duplicateVersionString);
if (dependencyVersion == null && duplicateVersion == null) {
return 0;
}
if (dependencyVersion == null) {
return -1;
}
if (duplicateVersion == null) {
return 1;
}
ArtifactVersion dependencyArtifactVersion = new DefaultArtifactVersion(dependencyVersion);
ArtifactVersion duplicateArtifactVersion = new DefaultArtifactVersion(duplicateVersion);
return dependencyArtifactVersion.compareTo(duplicateArtifactVersion);
}
private Optional findEqualIgnoreScopeVersionAndExclusions(Collection dependencies, Dependency candidate) {
// For project dependencies de-duplication
// Ignore scope on purpose
// Ignore version because Maven doesn't support dependencies with different versions on different scopes
// Ignore exclusions because we don't know how to choose/merge them
// Consequence is that we use the highest version and the exclusions of highest priority dependency when de-duplicating
// Use Maven Dependency "Management Key" as discriminator: groupId:artifactId:type:classifier
final String candidateManagementKey = candidate.getManagementKey();
return Iterables.tryFind(dependencies, new Predicate() {
@Override
public boolean apply(Dependency dependency) {
return dependency.getManagementKey().equals(candidateManagementKey);
}
});
}
private String mapToMavenSyntax(String version) {
return versionRangeMapper.map(version);
}
protected String determineProjectDependencyArtifactId(ProjectDependency dependency) {
return new ProjectDependencyArtifactIdExtractorHack(dependency).extract();
}
private List getExclusions(ModuleDependency dependency, Set configurations) {
if (!dependency.isTransitive()) {
return EXCLUDE_ALL;
}
List mavenExclusions = new ArrayList();
Set excludeRules = new HashSet(dependency.getExcludeRules());
for (Configuration configuration : configurations) {
excludeRules.addAll(configuration.getExcludeRules());
}
for (ExcludeRule excludeRule : excludeRules) {
Exclusion mavenExclusion = (Exclusion) excludeRuleConverter.convert(excludeRule);
if (mavenExclusion != null) {
mavenExclusions.add(mavenExclusion);
}
}
return mavenExclusions;
}
private static List initExcludeAll() {
Exclusion excludeAll = new Exclusion();
excludeAll.setGroupId("*");
excludeAll.setArtifactId("*");
return Collections.singletonList(excludeAll);
}
public ExcludeRuleConverter getExcludeRuleConverter() {
return excludeRuleConverter;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy