Hello Guillaume
Le 2024-08-07 à 22 h 23, Guillaume Nodet a écrit :
* ArtifactCoordinate are used to locate artifacts in a repository,
it's basically a pointer to a file in maven repository
* Artifact is the pointed artifact in the repository. They are
created when *resolving* an ArtifactCoordinate which basically
download the artifact in the local repository
* DependencyCoordinate is used to express a dependency
* Node is the main output of the *dependency collection* process,
it's the graph of dependencies
* Dependency is the output of the *collection* process, part of the
graph computed from one or more DependencyCoordinate, it's an
artifact + type + scope
It would be great to have this summary in the package-info Javadoc, and
also the relevant parts in each interface Javadoc. I will try to do a PR
next weekend for that.
when building the collected graph, the artifacts are not downloaded,
only the POMs are needed to build the graph. When will those
getModuleDescriptor() and getModuleName() methods be made available ?
I'd like to keep the objects immutable though.
I agree about immutability, but "immutable" does not necessarily mean
"no deferred computation". The JDK has some examples of immutable
objects that compute and cache their values when first requested (e.g.,
`Path` itself, or `BigDecimal`, `Class`, etc.). Users still have the
benefit of immutable objects, in the sense that they can share the same
instance without the need for defensive copies and without the need to
do synchronization themselves. So maybe a
`Dependency.getModuleDescription()` method could load the module
description when first needed, and `Dependency` still be considered
immutable as long as no visible state changed. That method would
potentially throw IOException, but again there is examples in the JDK of
immutable objects throwing exceptions (e.g. File.getCanonicalPath()).
We could have a `ResolvedDependency` which would inherit from
`Dependency` and provide a `getPath()` method. Same for `Artifact`,
where we could define a `ResolvedArtifact`. Or maybe add a `Resolved`
interface with the`getPath` method, which could be implemented by both
ResolvedArtifact and ResolvedDependency.
That would work. But isn't `ResolvedDependency` the same as `Dependency`
if we accept deferred computation, including for downloading the JAR file?
About `Dependency` as a specialization of `DependencyCoordinate`:
I find the outcome much less clear. The same kind of objects are used
for multiple things, and it's very confusing.
Alternatively we can keep the interfaces independent but nevertheless
resolve the method collisions as below:
* In DependencyCoordinate, rename getVersion() as getVersionConstraint().
* Choose a common name and return type for `isOptional()`.
It would allow an implementation class, if desired, to implement the two
interfaces even if from user's eyes they are still two separated types.
This strategy allows to implement the `toCoordinate()` method simply as
`return this`, thus avoiding a copy operation and the possible
information lost that come with it. Implementations are not forced to do
that, it just become possible when convenient.
Martin