Class MavenLocalRepositoryNegotiator

java.lang.Object
org.stianloader.picoresolve.repo.MavenLocalRepositoryNegotiator
All Implemented Interfaces:
RepositoryNegotiatior

public class MavenLocalRepositoryNegotiator extends Object implements RepositoryNegotiatior
An implementation of the RepositoryNegotiatior interface capable to reading and writing maven locals while having full compatibility with the latest versions of the standard maven resolver (as of time of writing, so late 2022). This includes support for file locking and internal metadata files, which were reverse-engineered by looking at file access patterns that became apparent when inspecting file IO with tools such as inotifywait.
  • Constructor Details

    • MavenLocalRepositoryNegotiator

      public MavenLocalRepositoryNegotiator(@NotNull @NotNull Path mavenLocal)
  • Method Details

    • addRepository

      @NotNull @Contract(mutates="this", pure=false, value="null -> fail; !null -> this") public @NotNull MavenLocalRepositoryNegotiator addRepository(@NotNull @NotNull MavenRepository remote)
      Specified by:
      addRepository in interface RepositoryNegotiatior
    • getLocalCache

      @NotNull public @NotNull Path getLocalCache()
    • resolveMavenMeta

      @NotNull public @NotNull CompletableFuture<List<RepositoryAttachedValue<Path>>> resolveMavenMeta(@NotNull @NotNull String path, @NotNull @NotNull Executor executor)
      Description copied from interface: RepositoryNegotiatior
      Resolve all relevant maven-metadata.xml files from the repositories and cache them into files.

      • This method MUST throw directly if something else but a maven-metadata.xml is requested.
      • The returned CompletableFuture WILL complete exceptionally if the requested file does not exist in any repository known to this instance of the RepositoryNegotiatior and if the file was not cached locally beforehand.
      • The CompletableFuture CAN complete exceptionally if the requested file does not exist in the repositories but was cached locally previously.
      • However it SHOULD complete normally if the file was cached recently - that is before the repository refresh interval.
      • Normal completion MUST occur if any repository contains the file. (It may complete exceptionally if needed file IO is not possible for the caching, but that is an ignored edge-case scenario here)
      • Normal completion SHOULD occur if the file exists locally at the right path, even though it was never stored beforehand through caching mechanism known to the negotiator. More specifically, certain internal metadata files used by the negotiator can be absent.

      Reason as to why maven-metadata.xml and other files have their own resolve methods is that MavenLocal stores metadata files a bit different to non-metadata files and therefore it makes sense to separate the two methods.

      Furthermore it makes sense to basically merge all the maven-metadata.xml files instead of only fetching a single one.

      Specified by:
      resolveMavenMeta in interface RepositoryNegotiatior
      Parameters:
      path - The path relative to the repository root where the file is located.
      executor - The executor with whom asynchronous operations should be performed.
      Returns:
      A CompletableFuture which upon non-exceptional completion stores the path where the resolved file is stored locally.
    • resolveStandard

      @NotNull public @NotNull CompletableFuture<RepositoryAttachedValue<Path>> resolveStandard(@NotNull @NotNull String path, @NotNull @NotNull Executor executor)
      Description copied from interface: RepositoryNegotiatior
      Resolve a "standard" non-metadata file from the repositories and store it into a file.

      • Exceptional completion CAN occur if a maven-metadata.xml is requested.
      • The returned CompletableFuture WILL complete exceptionally if the requested file does not exist in any repository known to this instance of the RepositoryNegotiatior and if the file was not cached locally beforehand.
      • The CompletableFuture CAN complete exceptionally if the requested file does not exist in the repositories but was cached locally previously.
      • However it SHOULD complete normally if the file was cached recently - that is before the repository refresh interval.
      • Normal completion MUST occur if any repository contains the file. (It may complete exceptionally if needed file IO is not possible for the caching, but that is an ignored edge-case scenario here)
      • Normal completion SHOULD occur if the file exists locally at the right path, even though it was never stored beforehand through caching mechanism known to the negotiator. More specifically, certain internal metadata files used by the negotiator can be absent.

      Reason as to why maven-metadata.xml and other files have their own resolve methods is that MavenLocal stores metadata files a bit different to non-metadata files and therefore it makes sense to separate the two methods.

      Specified by:
      resolveStandard in interface RepositoryNegotiatior
      Parameters:
      path - The path relative to the repository root where the file is located.
      executor - The executor with whom asynchronous operations should be performed.
      Returns:
      A CompletableFuture which upon non-exceptional completion stores the path where the resolved file is stored locally.
    • setWriteCacheMetadata

      @NotNull @Contract(mutates="this", pure=false, value="-> this") public @NotNull MavenLocalRepositoryNegotiator setWriteCacheMetadata(boolean writeMetadata)
      Description copied from interface: RepositoryNegotiatior
      Set whether the RepositoryNegotiatior is permitted to write metadata files for caching or repository tracking purposes. If the instance is not permitted to write such files, then it is likely to be necessitated to give up the ability to attach a repository to an artifact through RepositoryAttachedValue, that is it's repository value will more often than not be null.

      The state of this flag has no effect on whether the negotiator is permitted to fetch artifacts from remote repositories. Nor should it have a direct effect on other policies, such as the repository refresh interval. However, as the refresh interval can only be handled with great difficult in the absence of metadata files, the refresh behaviour is likely either going to be completely absent or be always present. MavenLocalRepositoryNegotiator will still proceed reading metadata files and handling them accordingly if they are present if writing is disabled; however it will not write any new ones nor update any existing ones.

      Disabling metadata is strongly discouraged. It should only be turned off if reducing clutter is absolutely crucial (e.g. in public-facing maven repositories) and read latencies are low. Furthermore it is recommended to have no remote repositories, in which case cache metadata files are of little use.

      Specified by:
      setWriteCacheMetadata in interface RepositoryNegotiatior
      Parameters:
      writeMetadata - True to allow writing metadata, false otherwise
      Returns:
      The current RepositoryNegotiatior instance, for chaining
    • write

      protected void write(byte[] data, Path to)