/** * Traverses the dependency graph, resolving conflicts and building the paths from the root * configuration. */ private void traverseGraph(ResolveState resolveState) { Set<ModuleIdentifier> conflicts = new LinkedHashSet<ModuleIdentifier>(); resolveState.onMoreSelected(resolveState.root); List<DependencyEdge> dependencies = new ArrayList<DependencyEdge>(); while (resolveState.peek() != null || !conflicts.isEmpty()) { if (resolveState.peek() != null) { ConfigurationNode node = resolveState.pop(); LOGGER.debug("Visiting configuration {}.", node); // Calculate the outgoing edges of this configuration dependencies.clear(); node.visitOutgoingDependencies(dependencies); for (DependencyEdge dependency : dependencies) { LOGGER.debug("Visiting dependency {}", dependency); // Resolve dependency to a particular revision ModuleVersionResolveState moduleRevision = dependency.resolveModuleRevisionId(); if (moduleRevision == null) { // Failed to resolve. continue; } ModuleIdentifier moduleId = moduleRevision.id.getModule(); // Check for a new conflict if (moduleRevision.state == ModuleState.New) { ModuleResolveState module = resolveState.getModule(moduleId); // A new module revision. Check for conflict Collection<ModuleVersionResolveState> versions = module.getVersions(); if (versions.size() == 1) { // First version of this module. Select it for now LOGGER.debug("Selecting new module version {}", moduleRevision); module.select(moduleRevision); } else { // Not the first version of this module. We have a new conflict LOGGER.debug("Found new conflicting module version {}", moduleRevision); conflicts.add(moduleId); // Deselect the currently selected version, and remove all outgoing edges from the // version // This will propagate through the graph and prune configurations that are no longer // required ModuleVersionResolveState previouslySelected = module.clearSelection(); if (previouslySelected != null) { for (ConfigurationNode configuration : previouslySelected.configurations) { configuration.removeOutgoingEdges(); } } } } dependency.attachToTargetConfigurations(); } } else { // We have some batched up conflicts. Resolve the first, and continue traversing the graph ModuleIdentifier moduleId = conflicts.iterator().next(); conflicts.remove(moduleId); ModuleResolveState module = resolveState.getModule(moduleId); ModuleVersionResolveState selected = conflictResolver.select(module.getVersions(), resolveState.root.moduleRevision); LOGGER.debug("Selected {} from conflicting modules {}.", selected, module.getVersions()); // Restart each configuration. For the evicted configuration, this means moving incoming // dependencies across to the // matching selected configuration. For the select configuration, this mean traversing its // dependencies. module.restart(selected); } } }
public void removeUnattachedDependency(DependencyEdge edge) { unattachedDependencies.remove(edge); }
public void removeIncomingEdge(DependencyEdge dependencyEdge) { incomingEdges.remove(dependencyEdge); resolveState.onFewerSelected(this); }
public ConfigurationNode pop() { ConfigurationNode next = queue.removeFirst(); queued.remove(next); return next; }