<commit_before>/*
 * Copyright 2019, TeamDev. All rights reserved.
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package io.spine.tools.gradle.project;

import com.google.common.collect.ImmutableMap;
import io.spine.tools.gradle.ConfigurationName;
import io.spine.tools.gradle.Dependency;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.artifacts.ModuleVersionSelector;
import org.gradle.api.artifacts.dsl.DependencyHandler;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;

import static com.google.common.base.Preconditions.checkNotNull;
import static io.spine.tools.gradle.ConfigurationName.runtimeClasspath;
import static io.spine.tools.gradle.ConfigurationName.testRuntimeClasspath;
import static org.gradle.api.artifacts.ExcludeRule.GROUP_KEY;
import static org.gradle.api.artifacts.ExcludeRule.MODULE_KEY;

/**
 * A {@link Dependant} implemented on top of a {@link DependencyHandler} of a project.
 */
public final class DependantProject implements Dependant {

    private final DependencyHandler dependencies;
    private final ConfigurationContainer configurations;

    private DependantProject(DependencyHandler dependencies,
                             ConfigurationContainer configurations) {
        this.dependencies = dependencies;
        this.configurations = configurations;
    }

    /**
     * Creates a new instance of {@code DependantProject} for the given project.
     */
    public static DependantProject from(Project project) {
        checkNotNull(project);
        return new DependantProject(project.getDependencies(),
                                    project.getConfigurations());
    }

    @Override
    public void depend(ConfigurationName configurationName, String notation) {
        dependencies.add(configurationName.value(), notation);
    }

    @Override
    public void exclude(Dependency dependency) {
        Configuration mainConfig = configurations.getByName(runtimeClasspath.value());
        exclude(mainConfig, dependency);

        Configuration testConfig = configurations.getByName(testRuntimeClasspath.value());
        exclude(testConfig, dependency);
    }

    @Override
    public void force(Dependency dependency, String version) {
        String dependencyNotation = dependency.ofVersion(version)
                                              .notation();
        configurations.all(config -> config.getResolutionStrategy()
                                           .force(dependencyNotation));
    }

    @Override
    public void removeForcedDependency(Dependency dependency) {
        configurations.all(config -> removeForcedDependency(config, dependency));
    }

    /**
     * Excludes the given dependency from the given configuration.
     *
     * @param configuration
     *         the configuration to exclude from
     * @param dependency
     *         the dependency to exclude
     */
    private static void exclude(Configuration configuration, Dependency dependency) {
        configuration.exclude(ImmutableMap.of(
                GROUP_KEY, dependency.groupId(),
                MODULE_KEY, dependency.name()
        ));
    }

    private static void removeForcedDependency(Configuration config, Dependency dependency) {
        Set<ModuleVersionSelector> forcedModules = config.getResolutionStrategy()
                                                         .getForcedModules();
        Collection<ModuleVersionSelector> newForcedModules = new HashSet<>(forcedModules);
        newForcedModules.removeIf(equalsTo(dependency));

        config.getResolutionStrategy()
              .setForcedModules(newForcedModules);
    }

    private static Predicate<ModuleVersionSelector> equalsTo(Dependency dependency) {
        return selector -> {
            boolean groupEquals = dependency.groupId()
                                            .equals(selector.getGroup());
            boolean nameEquals = dependency.name()
                                           .equals(selector.getName());
            return groupEquals && nameEquals;
        };
    }
}<commit_msg>Add doc to `DependantProject` new private methods<commit_after>/*
 * Copyright 2019, TeamDev. All rights reserved.
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package io.spine.tools.gradle.project;

import com.google.common.collect.ImmutableMap;
import io.spine.tools.gradle.ConfigurationName;
import io.spine.tools.gradle.Dependency;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.artifacts.ModuleVersionSelector;
import org.gradle.api.artifacts.dsl.DependencyHandler;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;

import static com.google.common.base.Preconditions.checkNotNull;
import static io.spine.tools.gradle.ConfigurationName.runtimeClasspath;
import static io.spine.tools.gradle.ConfigurationName.testRuntimeClasspath;
import static org.gradle.api.artifacts.ExcludeRule.GROUP_KEY;
import static org.gradle.api.artifacts.ExcludeRule.MODULE_KEY;

/**
 * A {@link Dependant} implemented on top of a {@link DependencyHandler} of a project.
 */
public final class DependantProject implements Dependant {

    private final DependencyHandler dependencies;
    private final ConfigurationContainer configurations;

    private DependantProject(DependencyHandler dependencies,
                             ConfigurationContainer configurations) {
        this.dependencies = dependencies;
        this.configurations = configurations;
    }

    /**
     * Creates a new instance of {@code DependantProject} for the given project.
     */
    public static DependantProject from(Project project) {
        checkNotNull(project);
        return new DependantProject(project.getDependencies(),
                                    project.getConfigurations());
    }

    @Override
    public void depend(ConfigurationName configurationName, String notation) {
        dependencies.add(configurationName.value(), notation);
    }

    @Override
    public void exclude(Dependency dependency) {
        Configuration mainConfig = configurations.getByName(runtimeClasspath.value());
        exclude(mainConfig, dependency);

        Configuration testConfig = configurations.getByName(testRuntimeClasspath.value());
        exclude(testConfig, dependency);
    }

    @Override
    public void force(Dependency dependency, String version) {
        String dependencyNotation = dependency.ofVersion(version)
                                              .notation();
        configurations.all(config -> config.getResolutionStrategy()
                                           .force(dependencyNotation));
    }

    @Override
    public void removeForcedDependency(Dependency dependency) {
        configurations.all(config -> removeForcedDependency(config, dependency));
    }

    /**
     * Excludes the given dependency from the given configuration.
     *
     * @param configuration
     *         the configuration to exclude from
     * @param dependency
     *         the dependency to exclude
     */
    private static void exclude(Configuration configuration, Dependency dependency) {
        configuration.exclude(ImmutableMap.of(
                GROUP_KEY, dependency.groupId(),
                MODULE_KEY, dependency.name()
        ));
    }

    /**
     * Removes a forced dependency from the resolution strategy of a given configuration.
     *
     * @param configuration
     *         the configuration to remove a forced dependency from
     * @param dependency
     *         the forced dependency
     */
    private static void
    removeForcedDependency(Configuration configuration, Dependency dependency) {
        Set<ModuleVersionSelector> forcedModules = configuration.getResolutionStrategy()
                                                         .getForcedModules();
        Collection<ModuleVersionSelector> newForcedModules = new HashSet<>(forcedModules);
        newForcedModules.removeIf(equalsTo(dependency));

        configuration.getResolutionStrategy()
              .setForcedModules(newForcedModules);
    }

    /**
     * Returns a predicate which compares the given {@link ModuleVersionSelector} to
     * a Spine {@link Dependency}.
     */
    private static Predicate<ModuleVersionSelector> equalsTo(Dependency dependency) {
        return selector -> {
            boolean groupEquals = dependency.groupId()
                                            .equals(selector.getGroup());
            boolean nameEquals = dependency.name()
                                           .equals(selector.getName());
            return groupEquals && nameEquals;
        };
    }
}
{'fraction_non_alphanumeric': 0.07525083612040134, 'fraction_numerical': 0.0007432181345224824, 'mean_word_length': 2.957720588235294, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2374546', 'n_tokens_mistral': 2591, 'n_tokens_neox': 2426, 'n_words': 763}