Package org.gradle.api.internal.artifacts.configurations

Source Code of org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection

/*
* 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.internal.artifacts.configurations;

import groovy.lang.Closure;
import org.apache.ivy.plugins.resolver.DependencyResolver;
import org.gradle.api.Action;
import org.gradle.api.InvalidUserDataException;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.*;
import org.gradle.api.file.FileCollection;
import org.gradle.api.internal.DefaultDomainObjectContainer;
import org.gradle.api.internal.artifacts.DefaultExcludeRule;
import org.gradle.api.internal.artifacts.IvyService;
import org.gradle.api.internal.file.AbstractFileCollection;
import org.gradle.api.internal.tasks.AbstractTaskDependency;
import org.gradle.api.internal.tasks.TaskDependencyInternal;
import org.gradle.api.internal.tasks.TaskDependencyResolveContext;
import org.gradle.api.specs.Spec;
import org.gradle.api.specs.Specs;
import org.gradle.api.tasks.TaskDependency;
import org.gradle.util.WrapUtil;

import java.io.File;
import java.util.*;

import static org.apache.ivy.core.module.descriptor.Configuration.Visibility;

public class DefaultConfiguration extends AbstractFileCollection implements Configuration {
    private final String path;
    private final String name;

    private Visibility visibility = Visibility.PUBLIC;
    private boolean transitive = true;
    private Set<Configuration> extendsFrom = new LinkedHashSet<Configuration>();
    private String description;
    private ConfigurationsProvider configurationsProvider;

    private IvyService ivyService;

    private DefaultDomainObjectContainer<Dependency> dependencies =
            new DefaultDomainObjectContainer<Dependency>(Dependency.class);

    private Set<PublishArtifact> artifacts = new LinkedHashSet<PublishArtifact>();

    private Set<ExcludeRule> excludeRules = new LinkedHashSet<ExcludeRule>();

    private final ConfigurationTaskDependency taskDependency = new ConfigurationTaskDependency();

    // This lock only protects the following fields
    private final Object lock = new Object();
    private State state = State.UNRESOLVED;
    private ResolvedConfiguration cachedResolvedConfiguration;

    public DefaultConfiguration(String path, String name, ConfigurationsProvider configurationsProvider,
                                IvyService ivyService) {
        this.path = path;
        this.name = name;
        this.configurationsProvider = configurationsProvider;
        this.ivyService = ivyService;
    }

    public String getName() {
        return name;
    }

    public State getState() {
        synchronized (lock) {
            return state;
        }
    }

    public boolean isVisible() {
        return visibility == Visibility.PUBLIC;
    }

    public Configuration setVisible(boolean visible) {
        throwExceptionIfNotInUnresolvedState();
        this.visibility = visible ? Visibility.PUBLIC : Visibility.PRIVATE;
        return this;
    }

    public Set<Configuration> getExtendsFrom() {
        return Collections.unmodifiableSet(extendsFrom);
    }

    public Configuration setExtendsFrom(Set<Configuration> extendsFrom) {
        throwExceptionIfNotInUnresolvedState();
        this.extendsFrom = new HashSet<Configuration>();
        for (Configuration configuration : extendsFrom) {
            extendsFrom(configuration);
        }
        return this;
    }

    public Configuration extendsFrom(Configuration... extendsFrom) {
        throwExceptionIfNotInUnresolvedState();
        for (Configuration configuration : extendsFrom) {
            if (configuration.getHierarchy().contains(this)) {
                throw new InvalidUserDataException(String.format(
                        "Cyclic extendsFrom from %s and %s is not allowed. See existing hierarchy: %s", this,
                        configuration, configuration.getHierarchy()));
            }
            this.extendsFrom.add(configuration);
        }
        return this;
    }

    public boolean isTransitive() {
        return transitive;
    }

    public Configuration setTransitive(boolean transitive) {
        throwExceptionIfNotInUnresolvedState();
        this.transitive = transitive;
        return this;
    }

    public String getDescription() {
        return description;
    }

    public Configuration setDescription(String description) {
        throwExceptionIfNotInUnresolvedState();
        this.description = description;
        return this;
    }

    public Set<Configuration> getHierarchy() {
        Set<Configuration> result = WrapUtil.<Configuration>toLinkedSet(this);
        collectSuperConfigs(this, result);
        return result;
    }

    private void collectSuperConfigs(Configuration configuration, Set<Configuration> result) {
        for (Configuration superConfig : configuration.getExtendsFrom()) {
            if (result.contains(superConfig)) {
                result.remove(superConfig);
            }
            result.add(superConfig);
            collectSuperConfigs(superConfig, result);
        }
    }

    public Set<Configuration> getAll() {
        return configurationsProvider.getAll();
    }

    public Set<File> resolve() {
        return getFiles();
    }

    public Set<File> getFiles() {
        return fileCollection(Specs.SATISFIES_ALL).getFiles();
    }

    public Set<File> files(Dependency... dependencies) {
        return fileCollection(dependencies).getFiles();
    }

    public Set<File> files(Closure dependencySpecClosure) {
        return fileCollection(dependencySpecClosure).getFiles();
    }

    public Set<File> files(Spec<Dependency> dependencySpec) {
        return fileCollection(dependencySpec).getFiles();
    }

    public FileCollection fileCollection(Spec<Dependency> dependencySpec) {
        return new ConfigurationFileCollection(dependencySpec);
    }

    public FileCollection fileCollection(Closure dependencySpecClosure) {
        return new ConfigurationFileCollection(dependencySpecClosure);
    }

    public FileCollection fileCollection(Dependency... dependencies) {
        return new ConfigurationFileCollection(WrapUtil.toLinkedSet(dependencies));
    }

    public ResolvedConfiguration getResolvedConfiguration() {
        synchronized (lock) {
            if (state == State.UNRESOLVED) {
                cachedResolvedConfiguration = ivyService.resolve(this);
                if (cachedResolvedConfiguration.hasError()) {
                    state = State.RESOLVED_WITH_FAILURES;
                } else {
                    state = State.RESOLVED;
                }
            }
            return cachedResolvedConfiguration;
        }
    }

    public void publish(List<DependencyResolver> publishResolvers, File descriptorDestination) {
        ivyService.publish(getHierarchy(), descriptorDestination, publishResolvers);
    }

    public TaskDependency getBuildDependencies() {
        return taskDependency;
    }

    /**
     * {@inheritDoc}
     */
    public TaskDependency getTaskDependencyFromProjectDependency(final boolean useDependedOn, final String taskName) {
        return new AbstractTaskDependency() {
            public void resolve(TaskDependencyResolveContext context) {
                if (useDependedOn) {
                    addTaskDependenciesFromProjectsIDependOn(taskName, context);
                } else {
                    Project thisProject = context.getTask().getProject();
                    addTaskDependenciesFromProjectsDependingOnMe(thisProject, taskName, context);
                }
            }

            private void addTaskDependenciesFromProjectsIDependOn(final String taskName,
                                                                  final TaskDependencyResolveContext context) {
                Set<ProjectDependency> projectDependencies = getAllDependencies(ProjectDependency.class);
                for (ProjectDependency projectDependency : projectDependencies) {
                    Task nextTask = projectDependency.getDependencyProject().getTasks().findByName(taskName);
                    if (nextTask != null) {
                        context.add(nextTask);
                    }
                }
            }

            private void addTaskDependenciesFromProjectsDependingOnMe(final Project thisProject, final String taskName,
                                                                      final TaskDependencyResolveContext context) {
                Set<Task> tasksWithName = thisProject.getRootProject().getTasksByName(taskName, true);
                for (Task nextTask : tasksWithName) {
                    Configuration configuration = nextTask.getProject().getConfigurations().findByName(getName());
                    if (configuration != null && doesConfigurationDependOnProject(configuration, thisProject)) {
                        context.add(nextTask);
                    }
                }
            }
        };
    }

    private static boolean doesConfigurationDependOnProject(Configuration configuration, Project project) {
        Set<ProjectDependency> projectDependencies = configuration.getAllDependencies(ProjectDependency.class);
        for (ProjectDependency projectDependency : projectDependencies) {
            if (projectDependency.getDependencyProject().equals(project)) {
                return true;
            }
        }
        return false;
    }

    public TaskDependency getBuildArtifacts() {
        return getAllArtifactFiles().getBuildDependencies();
    }

    public Set<Dependency> getDependencies() {
        return dependencies.getAll();
    }

    public Set<Dependency> getAllDependencies() {
        return Configurations.getDependencies(getHierarchy(), Specs.<Dependency>satisfyAll());
    }

    public <T extends Dependency> Set<T> getDependencies(Class<T> type) {
        return filter(type, getDependencies());
    }

    private <T extends Dependency> Set<T> filter(Class<T> type, Set<Dependency> dependencySet) {
        Set<T> matches = new LinkedHashSet<T>();
        for (Dependency dependency : dependencySet) {
            if (type.isInstance(dependency)) {
                matches.add(type.cast(dependency));
            }
        }
        return matches;
    }

    public <T extends Dependency> Set<T> getAllDependencies(Class<T> type) {
        return filter(type, getAllDependencies());
    }

    public void addDependency(Dependency dependency) {
        throwExceptionIfNotInUnresolvedState();
        dependencies.addObject(dependency);
    }

    public Configuration addArtifact(PublishArtifact artifact) {
        throwExceptionIfNotInUnresolvedState();
        artifacts.add(artifact);
        return this;
    }

    public Configuration removeArtifact(PublishArtifact artifact) {
        throwExceptionIfNotInUnresolvedState();
        artifacts.remove(artifact);
        return this;
    }

    public Set<PublishArtifact> getArtifacts() {
        return Collections.unmodifiableSet(artifacts);
    }

    public Set<PublishArtifact> getAllArtifacts() {
        return Configurations.getArtifacts(this.getHierarchy(), Specs.SATISFIES_ALL);
    }

    public FileCollection getAllArtifactFiles() {
        return new ArtifactsFileCollection();
    }

    public Set<ExcludeRule> getExcludeRules() {
        return Collections.unmodifiableSet(excludeRules);
    }

    public void setExcludeRules(Set<ExcludeRule> excludeRules) {
        throwExceptionIfNotInUnresolvedState();
        this.excludeRules = excludeRules;
    }

    public DefaultConfiguration exclude(Map<String, String> excludeRuleArgs) {
        throwExceptionIfNotInUnresolvedState();
        excludeRules.add(new DefaultExcludeRule(excludeRuleArgs));
        return this;
    }

    public String getUploadTaskName() {
        return Configurations.uploadTaskName(getName());
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        DefaultConfiguration that = (DefaultConfiguration) o;
        return path.equals(that.path);
    }

    @Override
    public int hashCode() {
        return path.hashCode();
    }

    public String getDisplayName() {
        return String.format("configuration '%s'", path);
    }

    public Configuration getConfiguration(Dependency dependency) {
        for (Configuration configuration : getHierarchy()) {
            if (configuration.getDependencies().contains(dependency)) {
                return configuration;
            }
        }
        return null;
    }

    public Configuration copy() {
        return createCopy(getDependencies());
    }

    public Configuration copyRecursive() {
        return createCopy(getAllDependencies());
    }

    public Configuration copy(Spec<Dependency> dependencySpec) {
        return createCopy(Specs.filterIterable(getDependencies(), dependencySpec));
    }

    public Configuration copyRecursive(Spec<Dependency> dependencySpec) {
        return createCopy(Specs.filterIterable(getAllDependencies(), dependencySpec));
    }

    private DefaultConfiguration createCopy(Set<Dependency> dependencies) {
        DetachedConfigurationsProvider configurationsProvider = new DetachedConfigurationsProvider();
        DefaultConfiguration copiedConfiguration = new DefaultConfiguration(path + "Copy", name + "Copy",
                configurationsProvider, ivyService);
        configurationsProvider.setTheOnlyConfiguration(copiedConfiguration);
        // state, cachedResolvedConfiguration, and extendsFrom intentionally not copied - must re-resolve copy
        // copying extendsFrom could mess up dependencies when copy was re-resolved

        copiedConfiguration.visibility = visibility;
        copiedConfiguration.transitive = transitive;
        copiedConfiguration.description = description;

        for (PublishArtifact artifact : getAllArtifacts()) {
            copiedConfiguration.addArtifact(artifact);
        }

        // todo An ExcludeRule is a value object but we don't enforce immutability for DefaultExcludeRule as strong as we
        // should (we expose the Map). We should provide a better API for ExcludeRule (I don't want to use unmodifiable Map).
        // As soon as DefaultExcludeRule is truly immutable, we don't need to create a new instance of DefaultExcludeRule.
        for (ExcludeRule excludeRule : getExcludeRules()) {
            copiedConfiguration.excludeRules.add(new DefaultExcludeRule(excludeRule.getExcludeArgs()));
        }

        for (Dependency dependency : dependencies) {
            copiedConfiguration.addDependency(dependency.copy());
        }
        return copiedConfiguration;
    }

    public Configuration copy(Closure dependencySpec) {
        return copy(Specs.<Dependency>convertClosureToSpec(dependencySpec));
    }

    public Configuration copyRecursive(Closure dependencySpec) {
        return copyRecursive(Specs.<Dependency>convertClosureToSpec(dependencySpec));
    }

    private void throwExceptionIfNotInUnresolvedState() {
        if (getState() != State.UNRESOLVED) {
            throw new InvalidUserDataException("You can't change a configuration which is not in unresolved state!");
        }
    }

    class ArtifactsFileCollection extends AbstractFileCollection {
        private final TaskDependencyInternal taskDependency = new AbstractTaskDependency() {
            public void resolve(TaskDependencyResolveContext context) {
                for (Configuration configuration : getExtendsFrom()) {
                    context.add(configuration.getBuildArtifacts());
                }
                for (PublishArtifact publishArtifact : getArtifacts()) {
                    context.add(publishArtifact);
                }
            }
        };

        public String getDisplayName() {
            return String.format("%s artifacts", DefaultConfiguration.this);
        }

        @Override
        public TaskDependency getBuildDependencies() {
            return taskDependency;
        }

        public Set<File> getFiles() {
            Set<File> files = new LinkedHashSet<File>();
            for (PublishArtifact artifact : getAllArtifacts()) {
                files.add(artifact.getFile());
            }
            return files;
        }
    }

    class ConfigurationFileCollection extends AbstractFileCollection {
        private Spec<Dependency> dependencySpec;

        private ConfigurationFileCollection(Spec<Dependency> dependencySpec) {
            this.dependencySpec = dependencySpec;
        }

        public ConfigurationFileCollection(Closure dependencySpecClosure) {
            this.dependencySpec = Specs.convertClosureToSpec(dependencySpecClosure);
        }

        public ConfigurationFileCollection(final Set<Dependency> dependencies) {
            this.dependencySpec = new Spec<Dependency>() {
                public boolean isSatisfiedBy(Dependency element) {
                    return dependencies.contains(element);
                }
            };
        }

        public Spec<Dependency> getDependencySpec() {
            return dependencySpec;
        }

        public String getDisplayName() {
            return String.format("%s dependencies", DefaultConfiguration.this);
        }

        public Set<File> getFiles() {
            synchronized (lock) {
                ResolvedConfiguration resolvedConfiguration = getResolvedConfiguration();
                if (getState() == State.RESOLVED_WITH_FAILURES) {
                    resolvedConfiguration.rethrowFailure();
                }
                return resolvedConfiguration.getFiles(dependencySpec);
            }
        }
    }

    public Action<? super Dependency> whenDependencyAdded(Action<? super Dependency> action) {
        return dependencies.whenObjectAdded(action);
    }

    public void whenDependencyAdded(Closure closure) {
        dependencies.whenObjectAdded(closure);
    }

    public void allDependencies(Action<? super Dependency> action) {
        dependencies.allObjects(action);
    }

    public void allDependencies(Closure action) {
        dependencies.allObjects(action);
    }

    private class ConfigurationTaskDependency extends AbstractTaskDependency {
        @Override
        public String toString() {
            return String.format("build dependencies %s", DefaultConfiguration.this);
        }

        public void resolve(TaskDependencyResolveContext context) {
            for (Configuration configuration : getExtendsFrom()) {
                context.add(configuration);
            }
            for (SelfResolvingDependency dependency : DefaultConfiguration.this.getDependencies(
                    SelfResolvingDependency.class)) {
                context.add(dependency);
            }
        }
    }
}
TOP

Related Classes of org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.