Class DependencyGraph
-
- All Implemented Interfaces:
public final class DependencyGraphA data class that represents the graph of dependencies of a project.
This class holds information about a project's scopes and their dependencies in a format that minimizes the consumption of memory. In projects with many scopes there is often a high degree of duplication in the dependencies of the scopes. To avoid this, this class aims to share as many parts of the dependency graph as possible between the different scopes. Ideally, there is only a single dependency graph containing the dependencies used by all scopes. This is not always possibles due to inconsistencies in dependency relations, like a package using different dependencies in different scopes. Then the dependency graph is split into multiple fragments, and each fragment has a consistent view on the dependencies it contains.
When constructing a dependency graph the dependencies are organized as a connected structure of DependencyReference objects in memory. Originally, the serialization format of a graph was based on this structure, but that turned out to be not ideal: During serialization, sub graphs referenced from multiple nodes (e.g. libraries with transitive dependencies referenced from multiple projects) get duplicated, which can cause a significant amount of redundancy. Therefore, the data representation has been changed again to a form, which can be serialized without introducing redundancy. It consists of the following elements:
packages: A list with the coordinates of all the packages (free of duplication) that are referenced by the graph. This allows extracting the packages directly, but also has the advantage that the package coordinates do not have to be repeated over and over: All the references to packages are expressed by indices into this list.
nodes: An ordered list with the nodes of the dependency graph. A single node represents a package, and therefore has a reference into the list with package coordinates. It can, however, happen that packages occur multiple times in the graph if they are in different subtrees with different sets of transitive dependencies. Then there are multiple nodes for the packages affected, and a fragmentIndex is used to identify them uniquely. Nodes also store information about issues of a package and their linkage.
edges: Here the structure of the graph comes in. Each edge connects two nodes and represents a directed depends-on relationship. The nodes are referenced by numeric indices into the list of nodes.
scopes: This is a map that associates the scopes used by projects with their direct dependencies. A single dependency graph contains the dependencies of all the projects processed by a specific package manager. Therefore, the keys of this map are scope names qualified by the coordinates of a project; which makes them unique. The values are references to the nodes in the graph that correspond to the packages the scopes depend on directly.
So to navigate this structure, start with a scope and gather the references to its direct dependency nodes. Then, by following the edges starting from these nodes, the set of transitive dependencies can be determined. The numeric indices can be resolved via the packages list.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description public classDependencyGraph.Companion
-
Field Summary
Fields Modifier and Type Field Description private final Map<DependencyGraphNode, List<DependencyGraphNode>>dependenciesprivate final List<Identifier>packagesprivate final SortedSet<DependencyReference>scopeRootsprivate final Map<String, List<RootDependencyIndex>>scopesprivate final List<DependencyGraphNode>nodesprivate final List<DependencyGraphEdge>edgespublic final static DependencyGraph.CompanionCompanion
-
Constructor Summary
Constructors Constructor Description DependencyGraph(List<Identifier> packages, SortedSet<DependencyReference> scopeRoots, Map<String, List<RootDependencyIndex>> scopes, List<DependencyGraphNode> nodes, List<DependencyGraphEdge> edges)
-
Method Summary
Modifier and Type Method Description final Map<DependencyGraphNode, List<DependencyGraphNode>>getDependencies()A mapping that allows fast access to the dependencies of a node in this graph. final List<Identifier>getPackages()A list with the identifiers of the packages that appear in the dependency graph. final SortedSet<DependencyReference>getScopeRoots()Stores the dependency graph as a list of root nodes for the direct dependencies referenced by scopes. final Map<String, List<RootDependencyIndex>>getScopes()A mapping from scope names to the direct dependencies of the scopes. final List<DependencyGraphNode>getNodes()A list with the nodes of this dependency graph. final List<DependencyGraphEdge>getEdges()A list with the edges of this dependency graph. final Set<Scope>createScopes()Transform the data stored in this object to the classical layout of dependency information, which is a set of Scopes referencing the packages they depend on. final Set<Scope>createScopes(Set<String> scopeNames, Boolean unqualify)Transform a subset of the data stored in this object to the classical layout of dependency information. final Map<Identifier, Set<Issue>>collectIssues()Return a map of all de-duplicated Issues associated by Identifier. -
-
Constructor Detail
-
DependencyGraph
DependencyGraph(List<Identifier> packages, SortedSet<DependencyReference> scopeRoots, Map<String, List<RootDependencyIndex>> scopes, List<DependencyGraphNode> nodes, List<DependencyGraphEdge> edges)
-
-
Method Detail
-
getDependencies
final Map<DependencyGraphNode, List<DependencyGraphNode>> getDependencies()
A mapping that allows fast access to the dependencies of a node in this graph.
-
getPackages
final List<Identifier> getPackages()
A list with the identifiers of the packages that appear in the dependency graph. This list is used to resolve the numeric indices contained in the DependencyGraphNode objects.
-
getScopeRoots
final SortedSet<DependencyReference> getScopeRoots()
Stores the dependency graph as a list of root nodes for the direct dependencies referenced by scopes. Starting with these nodes, the whole graph can be traversed. The nodes are constructed from the direct dependencies declared by scopes that cannot be reached via other paths in the dependency graph. Note that this property exists for backwards compatibility only; it is replaced by the lists of nodes and edges.
-
getScopes
final Map<String, List<RootDependencyIndex>> getScopes()
A mapping from scope names to the direct dependencies of the scopes. Based on this information, the set of Scopes of a project can be constructed from the serialized form.
-
getNodes
final List<DependencyGraphNode> getNodes()
A list with the nodes of this dependency graph. Nodes correspond to packages, but in contrast to the packages list, there can be multiple nodes for a single package. The order of nodes in this list is relevant; the edges of the graph reference their nodes by numeric indices.
-
getEdges
final List<DependencyGraphEdge> getEdges()
A list with the edges of this dependency graph. By traversing the edges, the dependencies of packages can be determined.
-
createScopes
final Set<Scope> createScopes()
Transform the data stored in this object to the classical layout of dependency information, which is a set of Scopes referencing the packages they depend on.
-
createScopes
final Set<Scope> createScopes(Set<String> scopeNames, Boolean unqualify)
Transform a subset of the data stored in this object to the classical layout of dependency information. This is analogous to createScopes, but only the provided scopeNames are taken into account. If unqualify is true, remove qualifiers from scope names before constructing the Scopes.
-
collectIssues
final Map<Identifier, Set<Issue>> collectIssues()
Return a map of all de-duplicated Issues associated by Identifier.
-
-
-
-