/** Populates the result from the graph traversal state. */ private void assembleResult(ResolveState resolveState, DependencyGraphVisitor listener) { listener.start(resolveState.root); // Visit the nodes for (ConfigurationNode resolvedConfiguration : resolveState.getConfigurationNodes()) { if (resolvedConfiguration.isSelected()) { resolvedConfiguration.validate(); listener.visitNode(resolvedConfiguration); } } // Visit the edges for (ConfigurationNode resolvedConfiguration : resolveState.getConfigurationNodes()) { if (resolvedConfiguration.isSelected()) { listener.visitEdge(resolvedConfiguration); } } listener.finish(resolveState.root); }
public DependencyEdge( ConfigurationNode from, DependencyMetaData dependencyMetaData, ModuleResolutionFilter resolutionFilter, ResolveState resolveState) { this.from = from; this.dependencyMetaData = dependencyMetaData; this.resolutionFilter = resolutionFilter; this.resolveState = resolveState; selector = resolveState.getSelector(dependencyMetaData); }
public DependencyEdge( ConfigurationNode from, DependencyMetaData dependencyMetaData, ModuleVersionSpec selectorSpec, ResolveState resolveState) { this.from = from; this.dependencyMetaData = dependencyMetaData; this.dependencyDescriptor = dependencyMetaData.getDescriptor(); this.selectorSpec = selectorSpec; this.resolveState = resolveState; selector = resolveState.getSelector(dependencyMetaData); }
private ModuleVersionSelectorResolveState( DependencyMetaData dependencyMetaData, DependencyToModuleVersionIdResolver resolver, ResolveState resolveState) { this.dependencyMetaData = dependencyMetaData; this.resolver = resolver; this.resolveState = resolveState; targetModule = resolveState.getModule( new DefaultModuleIdentifier( dependencyMetaData.getRequested().getGroup(), dependencyMetaData.getRequested().getName())); }
public void restart(ModuleVersionResolveState selected) { // Restarting this configuration after conflict resolution. // If this configuration belongs to the select version, queue ourselves up for traversal. // If not, then move our incoming edges across to the selected configuration if (moduleRevision == selected) { resolveState.onMoreSelected(this); } else { for (DependencyEdge dependency : incomingEdges) { dependency.restart(selected); } incomingEdges.clear(); } }
/** Populates the result from the graph traversal state. */ private void assembleResult( ResolveState resolveState, ResolvedConfigurationBuilder result, ResolvedConfigurationListener listener) { FailureState failureState = new FailureState(resolveState.root); ModuleVersionIdentifier root = resolveState.root.toId(); listener.start(root); for (ConfigurationNode resolvedConfiguration : resolveState.getConfigurationNodes()) { if (resolvedConfiguration.isSelected()) { resolvedConfiguration.attachToParents(result); resolvedConfiguration.collectFailures(failureState); listener.resolvedModuleVersion(resolvedConfiguration.moduleRevision); } } for (ConfigurationNode resolvedConfiguration : resolveState.getConfigurationNodes()) { if (resolvedConfiguration.isSelected()) { listener.resolvedConfiguration( resolvedConfiguration.toId(), resolvedConfiguration.outgoingEdges); } } failureState.attachFailures(result); result.done(resolveState.root.getResult()); }
private void calculateTargetConfigurations() { targetConfigurations.clear(); ModuleVersionMetaData targetModuleVersion = targetModuleRevision.getMetaData(); if (targetModuleVersion == null) { // Broken version return; } Set<ConfigurationMetaData> targetConfigurations = resolveState.dependencyToConfigurationResolver.resolveTargetConfigurations( dependencyMetaData, from.metaData, targetModuleVersion); for (ConfigurationMetaData targetConfiguration : targetConfigurations) { ConfigurationNode targetConfigurationNode = resolveState.getConfigurationNode(targetModuleRevision, targetConfiguration.getName()); this.targetConfigurations.add(targetConfigurationNode); } }
/** @return The module version, or null if there is a failure to resolve this selector. */ public ModuleVersionResolveState resolveModuleRevisionId() { if (targetModuleRevision != null) { return targetModuleRevision; } if (failure != null) { return null; } idResolveResult = resolver.resolve(dependencyMetaData); if (idResolveResult.getFailure() != null) { failure = idResolveResult.getFailure(); return null; } targetModuleRevision = resolveState.getRevision(idResolveResult.getId()); targetModuleRevision.addResolver(this); targetModuleRevision.selectionReason = idResolveResult.getSelectionReason(); targetModule = targetModuleRevision.module; return targetModuleRevision; }
/** @return The module version, or null if there is a failure to resolve this selector. */ public ModuleVersionResolveState resolveModuleRevisionId() { if (targetModuleRevision != null) { return targetModuleRevision; } if (failure != null) { return null; } idResolveResult = new DefaultBuildableComponentIdResolveResult(); resolver.resolve(dependencyMetaData, idResolveResult); if (idResolveResult.getFailure() != null) { failure = idResolveResult.getFailure(); return null; } targetModuleRevision = resolveState.getRevision(idResolveResult.getModuleVersionId()); targetModuleRevision.addResolver(this); targetModuleRevision.selectionReason = idResolveResult.getSelectionReason(); targetModule = targetModuleRevision.module; targetModule.addSelector(this); return targetModuleRevision; }
/** * 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 removeIncomingEdge(DependencyEdge dependencyEdge) { incomingEdges.remove(dependencyEdge); resolveState.onFewerSelected(this); }
public void addIncomingEdge(DependencyEdge dependencyEdge) { incomingEdges.add(dependencyEdge); resolveState.onMoreSelected(this); }
/** * Traverses the dependency graph, resolving conflicts and building the paths from the root * configuration. */ private void traverseGraph( final ResolveState resolveState, final ConflictHandler conflictHandler) { resolveState.onMoreSelected(resolveState.root); List<DependencyEdge> dependencies = new ArrayList<DependencyEdge>(); while (resolveState.peek() != null || conflictHandler.hasConflicts()) { 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 PotentialConflict c = conflictHandler.registerModule(module); if (!c.conflictExists()) { // No conflict. Select it for now LOGGER.debug("Selecting new module version {}", moduleRevision); module.select(moduleRevision); } else { // We have a conflict LOGGER.debug("Found new conflicting module version {}", moduleRevision); // 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 // For each module participating in the conflict (many times there is only one // participating module that has multiple versions) c.withParticipatingModules( new Action<ModuleIdentifier>() { public void execute(ModuleIdentifier module) { ModuleVersionResolveState previouslySelected = resolveState.getModule(module).clearSelection(); if (previouslySelected != null) { for (ConfigurationNode configuration : previouslySelected.configurations) { configuration.deselect(); } } } }); } } dependency.attachToTargetConfigurations(); } } else { // We have some batched up conflicts. Resolve the first, and continue traversing the graph conflictHandler.resolveNextConflict( new Action<ConflictResolutionResult>() { public void execute(final ConflictResolutionResult result) { result .getConflict() .withParticipatingModules( new Action<ModuleIdentifier>() { public void execute(ModuleIdentifier moduleIdentifier) { ModuleVersionResolveState selected = result.getSelected(); // 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. resolveState.getModule(moduleIdentifier).restart(selected); } }); } }); } } }