All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.gradle.internal.component.external.model.ivy.RealisedIvyModuleResolveMetadata Maven / Gradle / Ivy

There is a newer version: 8.11.1
Show newest version
/*
 * 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.ivy;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import org.gradle.api.InvalidUserDataException;
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
import org.gradle.api.artifacts.component.ModuleComponentSelector;
import org.gradle.api.capabilities.CapabilitiesMetadata;
import org.gradle.api.internal.artifacts.ivyservice.NamespaceId;
import org.gradle.api.internal.attributes.ImmutableAttributes;
import org.gradle.internal.Cast;
import org.gradle.internal.component.external.descriptor.Artifact;
import org.gradle.internal.component.external.descriptor.Configuration;
import org.gradle.internal.component.external.model.AbstractRealisedModuleComponentResolveMetadata;
import org.gradle.internal.component.external.model.AdditionalVariant;
import org.gradle.internal.component.external.model.ComponentVariant;
import org.gradle.internal.component.external.model.ConfigurationBoundExternalDependencyMetadata;
import org.gradle.internal.component.external.model.DefaultModuleComponentSelector;
import org.gradle.internal.component.external.model.ImmutableCapabilities;
import org.gradle.internal.component.external.model.LazyToRealisedModuleComponentResolveMetadataHelper;
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.RealisedConfigurationMetadata;
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.DependencyMetadata;
import org.gradle.internal.component.model.Exclude;
import org.gradle.internal.component.model.ExcludeMetadata;
import org.gradle.internal.component.model.ModuleConfigurationMetadata;
import org.gradle.internal.component.model.ModuleSources;

import javax.annotation.Nullable;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * {@link AbstractRealisedModuleComponentResolveMetadata Realised version} of a {@link IvyModuleResolveMetadata}.
 *
 * @see DefaultIvyModuleResolveMetadata
 */
public class RealisedIvyModuleResolveMetadata extends AbstractRealisedModuleComponentResolveMetadata implements IvyModuleResolveMetadata {

    public static RealisedIvyModuleResolveMetadata transform(DefaultIvyModuleResolveMetadata metadata) {
        VariantMetadataRules variantMetadataRules = metadata.getVariantMetadataRules();

        ImmutableList variants = LazyToRealisedModuleComponentResolveMetadataHelper.realiseVariants(metadata, variantMetadataRules, metadata.getVariants());

        Map configurations = realiseConfigurations(metadata, variantMetadataRules);

        if (variants.isEmpty()) {
            addVariantsFromRules(metadata, configurations, variantMetadataRules);
        }

        return new RealisedIvyModuleResolveMetadata(metadata, variants, configurations);
    }

    private static Map realiseConfigurations(DefaultIvyModuleResolveMetadata metadata, VariantMetadataRules variantMetadataRules) {
        Map configurations = Maps.newHashMapWithExpectedSize(metadata.getConfigurationNames().size());
        for (String configurationName : metadata.getConfigurationNames()) {
            configurations.put(configurationName, applyRules(metadata, variantMetadataRules, configurationName));
        }
        return configurations;
    }

    private static void addVariantsFromRules(DefaultIvyModuleResolveMetadata componentMetadata, Map declaredConfigurations, VariantMetadataRules variantMetadataRules) {
        List additionalVariants = variantMetadataRules.getAdditionalVariants();
        if (additionalVariants.isEmpty()) {
            return;
        }

        for (AdditionalVariant additionalVariant : additionalVariants) {
            String name = additionalVariant.getName();
            String baseName = additionalVariant.getBase();
            ImmutableAttributes attributes;
            ImmutableCapabilities capabilities;
            List dependencies;
            ImmutableList artifacts;
            ImmutableList excludes;

            ModuleConfigurationMetadata baseConf = (ModuleConfigurationMetadata) declaredConfigurations.get(baseName);
            if (baseConf == null) {
                attributes = componentMetadata.getAttributes();
                capabilities = ImmutableCapabilities.EMPTY;
                dependencies = ImmutableList.of();
                artifacts = ImmutableList.of();
                excludes = ImmutableList.of();
            } else {
                attributes = baseConf.getAttributes();
                capabilities = (ImmutableCapabilities) baseConf.getCapabilities();
                dependencies = Cast.uncheckedCast(baseConf.getDependencies());
                artifacts = Cast.uncheckedCast(baseConf.getArtifacts());
                excludes = Cast.uncheckedCast(baseConf.getExcludes());
            }

            if (baseName == null || baseConf != null) {
                declaredConfigurations.put(name, applyRules(componentMetadata.getId(),
                    name, variantMetadataRules, attributes, capabilities,
                    artifacts, excludes, true, true,
                    ImmutableSet.of(), null, dependencies, true, false));
            } else if (!additionalVariant.isLenient()) {
                throw new InvalidUserDataException("Configuration '" + baseName + "' not defined in module " + componentMetadata.getId().getDisplayName());
            }
        }
    }

    private static RealisedConfigurationMetadata applyRules(DefaultIvyModuleResolveMetadata metadata, VariantMetadataRules variantMetadataRules, String configurationName) {
        ImmutableMap configurationDefinitions = metadata.getConfigurationDefinitions();
        Configuration configuration = configurationDefinitions.get(configurationName);
        IvyConfigurationHelper configurationHelper = new IvyConfigurationHelper(metadata.getArtifactDefinitions(), new IdentityHashMap<>(), metadata.getExcludes(), metadata.getDependencies(), metadata.getId());
        ImmutableSet hierarchy = LazyToRealisedModuleComponentResolveMetadataHelper.constructHierarchy(configuration, configurationDefinitions);
        ImmutableList excludes = configurationHelper.filterExcludes(hierarchy);

        ImmutableList artifacts = configurationHelper.filterArtifacts(configurationName, hierarchy);

        return applyRules(metadata.getId(), configurationName, variantMetadataRules, metadata.getAttributes(), ImmutableCapabilities.EMPTY, artifacts, excludes, configuration.isTransitive(), configuration.isVisible(), hierarchy, configurationHelper, null, false, metadata.isExternalVariant());
    }

    private static RealisedConfigurationMetadata applyRules(ModuleComponentIdentifier id,
                                                            String configurationName,
                                                            VariantMetadataRules variantMetadataRules,
                                                            ImmutableAttributes attributes,
                                                            ImmutableCapabilities capabilities,
                                                            ImmutableList artifacts,
                                                            ImmutableList excludes,
                                                            boolean transitive,
                                                            boolean visible,
                                                            ImmutableSet hierarchy,
                                                            IvyConfigurationHelper configurationHelper,
                                                            @Nullable List dependenciesOverride,
                                                            boolean addedByRule,
                                                            boolean isExternalVariant) {
        NameOnlyVariantResolveMetadata variant = new NameOnlyVariantResolveMetadata(configurationName);
        ImmutableAttributes variantAttributes = variantMetadataRules.applyVariantAttributeRules(variant, attributes);
        CapabilitiesMetadata capabilitiesMetadata = variantMetadataRules.applyCapabilitiesRules(variant, capabilities);
        ImmutableList artifactsMetadata = variantMetadataRules.applyVariantFilesMetadataRulesToArtifacts(variant, artifacts, id);
        return createConfiguration(id, configurationName, transitive, visible, hierarchy,
            artifactsMetadata, excludes, variantAttributes, ImmutableCapabilities.of(capabilitiesMetadata.getCapabilities()), variantMetadataRules, configurationHelper, dependenciesOverride, addedByRule, isExternalVariant);
    }

    private final ImmutableMap configurationDefinitions;
    private final ImmutableList dependencies;
    private final ImmutableList artifactDefinitions;
    private final ImmutableList excludes;
    private final ImmutableMap extraAttributes;
    private final DefaultIvyModuleResolveMetadata metadata;
    private final String branch;

    private Optional> derivedVariants;

    private RealisedIvyModuleResolveMetadata(RealisedIvyModuleResolveMetadata metadata, List dependencies, Map transformedConfigurations) {
        super(metadata, metadata.getVariants(), transformedConfigurations);
        this.configurationDefinitions = metadata.getConfigurationDefinitions();
        this.branch = metadata.getBranch();
        this.artifactDefinitions = metadata.getArtifactDefinitions();
        this.dependencies = ImmutableList.copyOf(dependencies);
        this.excludes = metadata.getExcludes();
        this.extraAttributes = metadata.getExtraAttributes();
        this.metadata = metadata.metadata;
    }

    private RealisedIvyModuleResolveMetadata(RealisedIvyModuleResolveMetadata metadata, ModuleSources sources, VariantDerivationStrategy derivationStrategy) {
        super(metadata, sources, derivationStrategy);
        this.configurationDefinitions = metadata.configurationDefinitions;
        this.branch = metadata.branch;
        this.artifactDefinitions = metadata.artifactDefinitions;
        this.dependencies = metadata.dependencies;
        this.excludes = metadata.excludes;
        this.extraAttributes = metadata.extraAttributes;
        this.metadata = metadata.metadata;
    }

    RealisedIvyModuleResolveMetadata(DefaultIvyModuleResolveMetadata metadata,
                                     ImmutableList variants,
                                     Map configurations) {
        super(metadata, variants, configurations);
        this.configurationDefinitions = metadata.getConfigurationDefinitions();
        this.branch = metadata.getBranch();
        this.artifactDefinitions = metadata.getArtifactDefinitions();
        this.dependencies = metadata.getDependencies();
        this.excludes = metadata.getExcludes();
        this.extraAttributes = metadata.getExtraAttributes();
        this.metadata = metadata;
    }

    private static RealisedConfigurationMetadata createConfiguration(ModuleComponentIdentifier componentId,
                                                                     String name,
                                                                     boolean transitive,
                                                                     boolean visible,
                                                                     ImmutableSet hierarchy,
                                                                     ImmutableList artifacts,
                                                                     ImmutableList excludes,
                                                                     ImmutableAttributes componentLevelAttributes,
                                                                     ImmutableCapabilities capabilities,
                                                                     VariantMetadataRules variantMetadataRules,
                                                                     IvyConfigurationHelper configurationHelper,
                                                                     List dependenciesFromRule,
                                                                     boolean addedByRule,
                                                                     boolean externalVariant) {
        RealisedConfigurationMetadata configuration = new RealisedConfigurationMetadata(componentId, name, transitive, visible, hierarchy, artifacts, excludes, componentLevelAttributes, capabilities, false, addedByRule, externalVariant);
        List dependencyMetadata;
        if (configurationHelper != null) {
            dependencyMetadata = configurationHelper.filterDependencies(configuration);
        } else {
            dependencyMetadata = dependenciesFromRule;
        }
        configuration.setDependencies(ImmutableList.copyOf(variantMetadataRules.applyDependencyMetadataRules(new NameOnlyVariantResolveMetadata(name), dependencyMetadata)));
        return configuration;
    }

    @Override
    protected Optional> maybeDeriveVariants() {
        if (derivedVariants == null && getConfigurationNames().size() != configurationDefinitions.size()) {
            // if there are more configurations than definitions, configurations have been added by rules and thus they are variants
            derivedVariants = Optional.of(allConfigurationsThatAreVariants());
        } else {
            derivedVariants = Optional.absent();
        }
        return derivedVariants;
    }

    private ImmutableList allConfigurationsThatAreVariants() {
        ImmutableList.Builder builder = new ImmutableList.Builder<>();
        for (String potentialVariantName : getConfigurationNames()) {
            if (!configurationDefinitions.containsKey(potentialVariantName)) {
                builder.add(getConfiguration(potentialVariantName));
            }
        }
        return builder.build();
    }

    @Override
    public MutableIvyModuleResolveMetadata asMutable() {
        return metadata.asMutable();
    }

    @Override
    public RealisedIvyModuleResolveMetadata withSources(ModuleSources sources) {
        return new RealisedIvyModuleResolveMetadata(this, sources, getVariantDerivationStrategy());
    }

    @Override
    public ModuleComponentResolveMetadata withDerivationStrategy(VariantDerivationStrategy derivationStrategy) {
        if (getVariantDerivationStrategy() == derivationStrategy) {
            return this;
        }
        return new RealisedIvyModuleResolveMetadata(this, getSources(), derivationStrategy);
    }

    @Nullable
    @Override
    public String getBranch() {
        return branch;
    }

    @Override
    public ImmutableMap getConfigurationDefinitions() {
        return configurationDefinitions;
    }

    @Override
    public ImmutableList getArtifactDefinitions() {
        return artifactDefinitions;
    }

    @Override
    public ImmutableList getExcludes() {
        return excludes;
    }

    @Override
    public ImmutableMap getExtraAttributes() {
        return extraAttributes;
    }

    @Override
    public IvyModuleResolveMetadata withDynamicConstraintVersions() {
        ImmutableList descriptors = getDependencies();
        if (descriptors.isEmpty()) {
            return this;
        }
        Map transformedDescriptors = Maps.newHashMapWithExpectedSize(descriptors.size());
        for (IvyDependencyDescriptor dependency : descriptors) {
            ModuleComponentSelector selector = dependency.getSelector();
            String dynamicConstraintVersion = dependency.getDynamicConstraintVersion();
            ModuleComponentSelector newSelector = DefaultModuleComponentSelector.newSelector(selector.getModuleIdentifier(), dynamicConstraintVersion);
            transformedDescriptors.put(dependency, dependency.withRequested(newSelector));
        }
        return this.withDependencies(transformedDescriptors);
    }

    @Override
    public ImmutableList getDependencies() {
        return dependencies;
    }

    private IvyModuleResolveMetadata withDependencies(Map transformed) {
        ImmutableList transformedDescriptors = ImmutableList.copyOf(transformed.values());
        Set configurationNames = getConfigurationNames();
        Map transformedConfigurations = Maps.newHashMapWithExpectedSize(configurationNames.size());
        for (String name : configurationNames) {
            RealisedConfigurationMetadata configuration = (RealisedConfigurationMetadata) getConfiguration(name);
            List dependencies = configuration.getDependencies();
            ImmutableList.Builder transformedConfigurationDependencies = ImmutableList.builder();
            for (DependencyMetadata dependency : dependencies) {
                if (dependency instanceof ConfigurationBoundExternalDependencyMetadata) {
                    transformedConfigurationDependencies.add(((ConfigurationBoundExternalDependencyMetadata) dependency).withDescriptor(transformed.get(((ConfigurationBoundExternalDependencyMetadata) dependency).getDependencyDescriptor())));
                } else {
                    transformedConfigurationDependencies.add((ModuleDependencyMetadata) dependency);
                }
            }
            transformedConfigurations.put(name, configuration.withDependencies(transformedConfigurationDependencies.build()));
        }
        return new RealisedIvyModuleResolveMetadata(this, transformedDescriptors, transformedConfigurations);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy