/* * Copyright 2011 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.plugins.ide.idea.model.internal; import com.google.common.collect.Sets; import org.gradle.api.artifacts.Configuration; import org.gradle.composite.internal.CompositeBuildIdeProjectResolver; import org.gradle.internal.service.ServiceRegistry; import org.gradle.plugins.ide.idea.model.Dependency; import org.gradle.plugins.ide.idea.model.FilePath; import org.gradle.plugins.ide.idea.model.IdeaModule; import org.gradle.plugins.ide.idea.model.SingleEntryModuleLibrary; import org.gradle.plugins.ide.internal.IdeDependenciesExtractor; import org.gradle.plugins.ide.internal.resolver.model.IdeExtendedRepoFileDependency; import org.gradle.plugins.ide.internal.resolver.model.IdeLocalFileDependency; import org.gradle.plugins.ide.internal.resolver.model.IdeProjectDependency; import org.gradle.plugins.ide.internal.resolver.model.UnresolvedIdeRepoFileDependency; import java.io.File; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Map; import java.util.Set; public class IdeaDependenciesProvider { public static final String SCOPE_PLUS = "plus"; public static final String SCOPE_MINUS = "minus"; private final IdeDependenciesExtractor dependenciesExtractor; private final ModuleDependencyBuilder moduleDependencyBuilder; public IdeaDependenciesProvider(ServiceRegistry serviceRegistry) { this(new IdeDependenciesExtractor(), serviceRegistry); } IdeaDependenciesProvider(IdeDependenciesExtractor dependenciesExtractor, ServiceRegistry serviceRegistry) { this.dependenciesExtractor = dependenciesExtractor; moduleDependencyBuilder = new ModuleDependencyBuilder(CompositeBuildIdeProjectResolver.from(serviceRegistry)); } public Set<Dependency> provide(final IdeaModule ideaModule) { Set<Dependency> result = Sets.newLinkedHashSet(); result.addAll(getOutputLocations(ideaModule)); result.addAll(getDependencies(ideaModule)); return result; } private Set<SingleEntryModuleLibrary> getOutputLocations(IdeaModule ideaModule) { if (ideaModule.getSingleEntryLibraries() == null) { return Collections.emptySet(); } Set<SingleEntryModuleLibrary> outputLocations = Sets.newLinkedHashSet(); for (Map.Entry<String, Iterable<File>> outputLocation : ideaModule.getSingleEntryLibraries().entrySet()) { String scope = outputLocation.getKey(); for (File file : outputLocation.getValue()) { if (file != null && file.isDirectory()) { outputLocations.add(new SingleEntryModuleLibrary(toPath(ideaModule, file), scope)); } } } return outputLocations; } private Set<Dependency> getDependencies(IdeaModule ideaModule) { Set<Dependency> dependencies = Sets.newLinkedHashSet(); for (GeneratedIdeaScope scope : GeneratedIdeaScope.values()) { dependencies.addAll(getProjectDependencies(ideaModule, scope)); dependencies.addAll(getExternalDependencies(ideaModule, scope)); dependencies.addAll(getFileDependencies(ideaModule, scope)); } return dependencies; } private Set<Dependency> getProjectDependencies(IdeaModule ideaModule, GeneratedIdeaScope scope) { Collection<Configuration> plusConfigurations = getPlusConfigurations(ideaModule, scope); Collection<Configuration> minusConfigurations = getMinusConfigurations(ideaModule, scope); Collection<IdeProjectDependency> extractedDependencies = dependenciesExtractor.extractProjectDependencies(ideaModule.getProject(), plusConfigurations, minusConfigurations); Set<Dependency> dependencies = Sets.newLinkedHashSet(); for (IdeProjectDependency ideProjectDependency : extractedDependencies) { dependencies.add(moduleDependencyBuilder.create(ideProjectDependency, scope.name())); } return dependencies; } private Set<Dependency> getExternalDependencies(IdeaModule ideaModule, GeneratedIdeaScope scope) { if (ideaModule.isOffline()) { return Collections.emptySet(); } Collection<Configuration> plusConfigurations = getPlusConfigurations(ideaModule, scope); Collection<Configuration> minusConfigurations = getMinusConfigurations(ideaModule, scope); Set<Dependency> dependencies = Sets.newLinkedHashSet(); Collection<IdeExtendedRepoFileDependency> ideRepoFileDependencies = dependenciesExtractor.extractRepoFileDependencies( ideaModule.getProject().getDependencies(), plusConfigurations, minusConfigurations, ideaModule.isDownloadSources(), ideaModule.isDownloadJavadoc()); for (IdeExtendedRepoFileDependency dependency : ideRepoFileDependencies) { dependencies.add(toLibraryDependency(dependency, ideaModule, scope)); } return dependencies; } private SingleEntryModuleLibrary toLibraryDependency(IdeExtendedRepoFileDependency dependency, IdeaModule ideaModule, GeneratedIdeaScope scope) { Set<FilePath> javadoc = Sets.newLinkedHashSet(); for (File javaDocFile : dependency.getJavadocFiles()) { javadoc.add(toPath(ideaModule, javaDocFile)); } Set<FilePath> source = Sets.newLinkedHashSet(); for (File sourceFile : dependency.getSourceFiles()) { source.add(toPath(ideaModule, sourceFile)); } SingleEntryModuleLibrary library = new SingleEntryModuleLibrary(toPath(ideaModule, dependency.getFile()), javadoc, source, scope.name()); library.setModuleVersion(dependency.getId()); return library; } private Set<Dependency> getFileDependencies(IdeaModule ideaModule, GeneratedIdeaScope scope) { Collection<Configuration> plusConfigurations = getPlusConfigurations(ideaModule, scope); Collection<Configuration> minusConfigurations = getMinusConfigurations(ideaModule, scope); Set<Dependency> dependencies = Sets.newLinkedHashSet(); Collection<IdeLocalFileDependency> ideLocalFileDependencies = dependenciesExtractor.extractLocalFileDependencies(plusConfigurations, minusConfigurations); for (IdeLocalFileDependency fileDependency : ideLocalFileDependencies) { dependencies.add(toLibraryDependency(fileDependency, ideaModule, scope)); } return dependencies; } private SingleEntryModuleLibrary toLibraryDependency(IdeLocalFileDependency fileDependency, IdeaModule ideaModule, GeneratedIdeaScope scope) { return new SingleEntryModuleLibrary(toPath(ideaModule, fileDependency.getFile()), scope.name()); } public Collection<UnresolvedIdeRepoFileDependency> getUnresolvedDependencies(IdeaModule ideaModule) { Set<UnresolvedIdeRepoFileDependency> usedUnresolvedDependencies = Sets.newTreeSet(new Comparator<UnresolvedIdeRepoFileDependency>() { @Override public int compare(UnresolvedIdeRepoFileDependency left, UnresolvedIdeRepoFileDependency right) { return left.getDisplayName().compareTo(right.getDisplayName()); } }); for (GeneratedIdeaScope scope : GeneratedIdeaScope.values()) { Collection<Configuration> plusConfigurations = getPlusConfigurations(ideaModule, scope); Collection<Configuration> minusConfigurations = getMinusConfigurations(ideaModule, scope); usedUnresolvedDependencies.addAll(dependenciesExtractor.unresolvedExternalDependencies(plusConfigurations, minusConfigurations)); } return usedUnresolvedDependencies; } private Collection<Configuration> getPlusConfigurations(IdeaModule ideaModule, GeneratedIdeaScope scope) { return getConfigurations(ideaModule, scope, SCOPE_PLUS); } private Collection<Configuration> getMinusConfigurations(IdeaModule ideaModule, GeneratedIdeaScope scope) { return getConfigurations(ideaModule, scope, SCOPE_MINUS); } private Collection<Configuration> getConfigurations(IdeaModule ideaModule, GeneratedIdeaScope scope, String plusMinus) { Map<String, Collection<Configuration>> plusMinusConfigurations = getPlusMinusConfigurations(ideaModule, scope); return plusMinusConfigurations.containsKey(plusMinus) ? plusMinusConfigurations.get(plusMinus) : Collections.<Configuration>emptyList(); } private Map<String, Collection<Configuration>> getPlusMinusConfigurations(IdeaModule ideaModule, GeneratedIdeaScope scope) { Map<String, Collection<Configuration>> plusMinusConfigurations = ideaModule.getScopes().get(scope.name()); return plusMinusConfigurations != null ? plusMinusConfigurations : Collections.<String, Collection<Configuration>>emptyMap(); } private FilePath toPath(IdeaModule ideaModule, File file) { return file != null ? ideaModule.getPathFactory().path(file) : null; } }