You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by cs...@apache.org on 2022/04/14 08:47:42 UTC

[maven-resolver] branch make-local-path-composer-reusable created (now 8af7e130)

This is an automated email from the ASF dual-hosted git repository.

cstamas pushed a change to branch make-local-path-composer-reusable
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git


      at 8af7e130 [EXPERIMENT] Make LRM path composition reusable

This branch includes the following new commits:

     new 8af7e130 [EXPERIMENT] Make LRM path composition reusable

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[maven-resolver] 01/01: [EXPERIMENT] Make LRM path composition reusable

Posted by cs...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cstamas pushed a commit to branch make-local-path-composer-reusable
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git

commit 8af7e1304161f375515daf23597c652fe3f8504a
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Thu Apr 14 10:45:40 2022 +0200

    [EXPERIMENT] Make LRM path composition reusable
    
    LocalRepositoryManager path composition was enclosed
    into SimpleLocalRepositoryManager in not-quite reusable
    manner. Make it reusable, by making it into a component.
    
    Currently FileProvidedChecksumsSource was reusing local
    paths, is adjusted now.
    
    Also, make LRM implementations more encapsulated and
    clear up many ctors leaving only one for simplicity.
---
 .../eclipse/aether/impl/DefaultServiceLocator.java |   3 +
 .../eclipse/aether/impl/guice/AetherModule.java    |   4 +
 .../aether/internal/impl/ArtifactPathComposer.java |  36 +++++++
 .../internal/impl/DefaultArtifactPathComposer.java | 110 +++++++++++++++++++++
 .../impl/EnhancedLocalRepositoryManager.java       |   3 +-
 .../EnhancedLocalRepositoryManagerFactory.java     |  25 +++--
 .../internal/impl/FileProvidedChecksumsSource.java |  10 +-
 .../impl/SimpleLocalRepositoryManager.java         | 108 ++++----------------
 .../impl/SimpleLocalRepositoryManagerFactory.java  |  29 +++++-
 .../impl/EnhancedLocalRepositoryManagerTest.java   |   2 +-
 .../impl/FileProvidedChecksumsSourceTest.java      |   2 +-
 .../impl/SimpleLocalRepositoryManagerTest.java     |   3 +-
 12 files changed, 225 insertions(+), 110 deletions(-)

diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java
index c17e2378..e3bf55a2 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java
@@ -31,6 +31,8 @@ import java.util.Map;
 import static java.util.Objects.requireNonNull;
 
 import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.internal.impl.ArtifactPathComposer;
+import org.eclipse.aether.internal.impl.DefaultArtifactPathComposer;
 import org.eclipse.aether.internal.impl.DefaultArtifactResolver;
 import org.eclipse.aether.internal.impl.DefaultChecksumPolicyProvider;
 import org.eclipse.aether.internal.impl.DefaultTrackingFileManager;
@@ -227,6 +229,7 @@ public final class DefaultServiceLocator
         addService( TrackingFileManager.class, DefaultTrackingFileManager.class );
         addService( NamedLockFactorySelector.class, SimpleNamedLockFactorySelector.class );
         addService( ChecksumAlgorithmFactorySelector.class, DefaultChecksumAlgorithmFactorySelector.class );
+        addService( ArtifactPathComposer.class, DefaultArtifactPathComposer.class );
     }
 
     private <T> Entry<T> getEntry( Class<T> type, boolean create )
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java
index 93ef99ec..49e29adc 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java
@@ -40,6 +40,8 @@ import org.eclipse.aether.impl.OfflineController;
 import org.eclipse.aether.impl.RemoteRepositoryManager;
 import org.eclipse.aether.impl.RepositoryConnectorProvider;
 import org.eclipse.aether.impl.RepositoryEventDispatcher;
+import org.eclipse.aether.internal.impl.ArtifactPathComposer;
+import org.eclipse.aether.internal.impl.DefaultArtifactPathComposer;
 import org.eclipse.aether.internal.impl.DefaultTrackingFileManager;
 import org.eclipse.aether.internal.impl.FileProvidedChecksumsSource;
 import org.eclipse.aether.internal.impl.TrackingFileManager;
@@ -171,6 +173,8 @@ public class AetherModule
                 .to( DefaultRepositoryEventDispatcher.class ).in( Singleton.class );
         bind( OfflineController.class ) //
                 .to( DefaultOfflineController.class ).in( Singleton.class );
+
+        bind( ArtifactPathComposer.class ).to( DefaultArtifactPathComposer.class ).in( Singleton.class );
         bind( LocalRepositoryProvider.class ) //
                 .to( DefaultLocalRepositoryProvider.class ).in( Singleton.class );
         bind( LocalRepositoryManagerFactory.class ).annotatedWith( Names.named( "simple" ) ) //
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/ArtifactPathComposer.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/ArtifactPathComposer.java
new file mode 100644
index 00000000..e2c0c63d
--- /dev/null
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/ArtifactPathComposer.java
@@ -0,0 +1,36 @@
+package org.eclipse.aether.internal.impl;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.metadata.Metadata;
+
+/**
+ * Composes {@link Artifact} and {@link Metadata} relative paths to be used in
+ * {@link org.eclipse.aether.repository.LocalRepositoryManager}.
+ *
+ * @since TBD
+ */
+public interface ArtifactPathComposer
+{
+    String getPathForArtifact( Artifact artifact, boolean local );
+
+    String getPathForMetadata( Metadata metadata, String repositoryKey );
+}
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactPathComposer.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactPathComposer.java
new file mode 100644
index 00000000..3c5b4faf
--- /dev/null
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactPathComposer.java
@@ -0,0 +1,110 @@
+package org.eclipse.aether.internal.impl;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.metadata.Metadata;
+
+/**
+ * Default implementation of {@link ArtifactPathComposer}.
+ *
+ * @since TBD
+ */
+@Singleton
+@Named
+public final class DefaultArtifactPathComposer implements ArtifactPathComposer
+{
+    @Override
+    public String getPathForArtifact( Artifact artifact, boolean local )
+    {
+        StringBuilder path = new StringBuilder( 128 );
+
+        path.append( artifact.getGroupId().replace( '.', '/' ) ).append( '/' );
+
+        path.append( artifact.getArtifactId() ).append( '/' );
+
+        path.append( artifact.getBaseVersion() ).append( '/' );
+
+        path.append( artifact.getArtifactId() ).append( '-' );
+        if ( local )
+        {
+            path.append( artifact.getBaseVersion() );
+        }
+        else
+        {
+            path.append( artifact.getVersion() );
+        }
+
+        if ( artifact.getClassifier().length() > 0 )
+        {
+            path.append( '-' ).append( artifact.getClassifier() );
+        }
+
+        if ( artifact.getExtension().length() > 0 )
+        {
+            path.append( '.' ).append( artifact.getExtension() );
+        }
+
+        return path.toString();
+    }
+
+    @Override
+    public String getPathForMetadata( Metadata metadata, String repositoryKey )
+    {
+        StringBuilder path = new StringBuilder( 128 );
+
+        if ( metadata.getGroupId().length() > 0 )
+        {
+            path.append( metadata.getGroupId().replace( '.', '/' ) ).append( '/' );
+
+            if ( metadata.getArtifactId().length() > 0 )
+            {
+                path.append( metadata.getArtifactId() ).append( '/' );
+
+                if ( metadata.getVersion().length() > 0 )
+                {
+                    path.append( metadata.getVersion() ).append( '/' );
+                }
+            }
+        }
+
+        path.append( insertRepositoryKey( metadata.getType(), repositoryKey ) );
+
+        return path.toString();
+    }
+
+    private String insertRepositoryKey( String filename, String repositoryKey )
+    {
+        String result;
+        int idx = filename.indexOf( '.' );
+        if ( idx < 0 )
+        {
+            result = filename + '-' + repositoryKey;
+        }
+        else
+        {
+            result = filename.substring( 0, idx ) + '-' + repositoryKey + filename.substring( idx );
+        }
+        return result;
+    }
+}
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManager.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManager.java
index 65da5321..13110db6 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManager.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManager.java
@@ -68,10 +68,11 @@ class EnhancedLocalRepositoryManager
     private final TrackingFileManager trackingFileManager;
 
     EnhancedLocalRepositoryManager( File basedir,
+                                    ArtifactPathComposer artifactPathComposer,
                                     RepositorySystemSession session,
                                     TrackingFileManager trackingFileManager )
     {
-        super( basedir, "enhanced" );
+        super( basedir, "enhanced", artifactPathComposer );
         String filename = ConfigUtils.getString( session, "", "aether.enhancedLocalRepository.trackingFilename" );
         if ( filename.isEmpty() || filename.contains( "/" ) || filename.contains( "\\" )
             || filename.contains( ".." ) )
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerFactory.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerFactory.java
index d5d64b1c..ab6ce00d 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerFactory.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerFactory.java
@@ -19,8 +19,6 @@ package org.eclipse.aether.internal.impl;
  * under the License.
  */
 
-import java.util.Objects;
-
 import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Singleton;
@@ -33,6 +31,8 @@ import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory;
 import org.eclipse.aether.spi.locator.Service;
 import org.eclipse.aether.spi.locator.ServiceLocator;
 
+import static java.util.Objects.requireNonNull;
+
 /**
  * Creates enhanced local repository managers for repository types {@code "default"} or {@code "" (automatic)}. Enhanced
  * local repository manager is built upon the classical Maven 2.0 local repository structure but additionally keeps
@@ -47,6 +47,8 @@ public class EnhancedLocalRepositoryManagerFactory
 {
     private float priority = 10.0f;
 
+    private ArtifactPathComposer artifactPathComposer;
+
     private TrackingFileManager trackingFileManager;
 
     public EnhancedLocalRepositoryManagerFactory()
@@ -55,26 +57,32 @@ public class EnhancedLocalRepositoryManagerFactory
     }
 
     @Inject
-    public EnhancedLocalRepositoryManagerFactory( final TrackingFileManager trackingFileManager )
+    public EnhancedLocalRepositoryManagerFactory( final ArtifactPathComposer artifactPathComposer,
+                                                  final TrackingFileManager trackingFileManager )
     {
-        this.trackingFileManager = Objects.requireNonNull( trackingFileManager );
+        this.artifactPathComposer = requireNonNull( artifactPathComposer );
+        this.trackingFileManager = requireNonNull( trackingFileManager );
     }
 
     @Override
     public void initService( final ServiceLocator locator )
     {
-        this.trackingFileManager = Objects.requireNonNull( locator.getService( TrackingFileManager.class ) );
+        this.artifactPathComposer = requireNonNull( locator.getService( ArtifactPathComposer.class ) );
+        this.trackingFileManager = requireNonNull( locator.getService( TrackingFileManager.class ) );
     }
 
+    @Override
     public LocalRepositoryManager newInstance( RepositorySystemSession session, LocalRepository repository )
         throws NoLocalRepositoryManagerException
     {
-        Objects.requireNonNull( session, "session cannot be null" );
-        Objects.requireNonNull( repository, "repository cannot be null" );
+        requireNonNull( session, "session cannot be null" );
+        requireNonNull( repository, "repository cannot be null" );
 
         if ( "".equals( repository.getContentType() ) || "default".equals( repository.getContentType() ) )
         {
-            return new EnhancedLocalRepositoryManager( repository.getBasedir(), session, trackingFileManager );
+            return new EnhancedLocalRepositoryManager(
+                    repository.getBasedir(), artifactPathComposer, session, trackingFileManager
+            );
         }
         else
         {
@@ -82,6 +90,7 @@ public class EnhancedLocalRepositoryManagerFactory
         }
     }
 
+    @Override
     public float getPriority()
     {
         return priority;
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/FileProvidedChecksumsSource.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/FileProvidedChecksumsSource.java
index 2289fa56..f3bb7f8e 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/FileProvidedChecksumsSource.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/FileProvidedChecksumsSource.java
@@ -32,7 +32,6 @@ import org.slf4j.LoggerFactory;
 import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Singleton;
-import java.io.File;
 import java.io.IOException;
 import java.net.URI;
 import java.nio.file.Files;
@@ -68,14 +67,13 @@ public final class FileProvidedChecksumsSource
 
     private final FileProcessor fileProcessor;
 
-    private final SimpleLocalRepositoryManager simpleLocalRepositoryManager;
+    private final ArtifactPathComposer artifactPathComposer;
 
     @Inject
-    public FileProvidedChecksumsSource( FileProcessor fileProcessor )
+    public FileProvidedChecksumsSource( FileProcessor fileProcessor, ArtifactPathComposer artifactPathComposer )
     {
         this.fileProcessor = requireNonNull( fileProcessor );
-        // we really needs just "local layout" from it (relative paths), so baseDir here is irrelevant
-        this.simpleLocalRepositoryManager = new SimpleLocalRepositoryManager( new File( "" ) );
+        this.artifactPathComposer = requireNonNull( artifactPathComposer );
     }
 
     @Override
@@ -92,7 +90,7 @@ public final class FileProvidedChecksumsSource
         for ( ChecksumAlgorithmFactory checksumAlgorithmFactory : checksumAlgorithmFactories )
         {
             checksumFilePaths.add( new ChecksumFilePath(
-                    simpleLocalRepositoryManager.getPathForArtifact( transfer.getArtifact(), false ) + '.'
+                    artifactPathComposer.getPathForArtifact( transfer.getArtifact(), false ) + '.'
                     + checksumAlgorithmFactory.getFileExtension(), checksumAlgorithmFactory ) );
         }
         return getProvidedChecksums( baseDir, checksumFilePaths, ArtifactIdUtils.toId( transfer.getArtifact() ) );
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/SimpleLocalRepositoryManager.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/SimpleLocalRepositoryManager.java
index 9023d17a..c208e53c 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/SimpleLocalRepositoryManager.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/SimpleLocalRepositoryManager.java
@@ -46,66 +46,34 @@ class SimpleLocalRepositoryManager
 
     private final LocalRepository repository;
 
-    SimpleLocalRepositoryManager( File basedir )
-    {
-        this( basedir, "simple" );
-    }
-
-    SimpleLocalRepositoryManager( String basedir )
-    {
-        this( ( basedir != null ) ? new File( basedir ) : null, "simple" );
-    }
+    private final ArtifactPathComposer artifactPathComposer;
 
-    SimpleLocalRepositoryManager( File basedir, String type )
+    SimpleLocalRepositoryManager( File basedir, String type, ArtifactPathComposer artifactPathComposer )
     {
         requireNonNull( basedir, "base directory cannot be null" );
         repository = new LocalRepository( basedir.getAbsoluteFile(), type );
+        this.artifactPathComposer = requireNonNull( artifactPathComposer );
     }
 
+    @Override
     public LocalRepository getRepository()
     {
         return repository;
     }
 
-    String getPathForArtifact( Artifact artifact, boolean local )
+    protected String getPathForArtifact( Artifact artifact, boolean local )
     {
-        StringBuilder path = new StringBuilder( 128 );
-
-        path.append( artifact.getGroupId().replace( '.', '/' ) ).append( '/' );
-
-        path.append( artifact.getArtifactId() ).append( '/' );
-
-        path.append( artifact.getBaseVersion() ).append( '/' );
-
-        path.append( artifact.getArtifactId() ).append( '-' );
-        if ( local )
-        {
-            path.append( artifact.getBaseVersion() );
-        }
-        else
-        {
-            path.append( artifact.getVersion() );
-        }
-
-        if ( artifact.getClassifier().length() > 0 )
-        {
-            path.append( '-' ).append( artifact.getClassifier() );
-        }
-
-        if ( artifact.getExtension().length() > 0 )
-        {
-            path.append( '.' ).append( artifact.getExtension() );
-        }
-
-        return path.toString();
+        return artifactPathComposer.getPathForArtifact( artifact, local );
     }
 
+    @Override
     public String getPathForLocalArtifact( Artifact artifact )
     {
         requireNonNull( artifact, "artifact cannot be null" );
         return getPathForArtifact( artifact, true );
     }
 
+    @Override
     public String getPathForRemoteArtifact( Artifact artifact, RemoteRepository repository, String context )
     {
         requireNonNull( artifact, "artifact cannot be null" );
@@ -113,20 +81,22 @@ class SimpleLocalRepositoryManager
         return getPathForArtifact( artifact, false );
     }
 
+    @Override
     public String getPathForLocalMetadata( Metadata metadata )
     {
         requireNonNull( metadata, "metadata cannot be null" );
-        return getPath( metadata, "local" );
+        return artifactPathComposer.getPathForMetadata( metadata, "local" );
     }
 
+    @Override
     public String getPathForRemoteMetadata( Metadata metadata, RemoteRepository repository, String context )
     {
         requireNonNull( metadata, "metadata cannot be null" );
         requireNonNull( repository, "repository cannot be null" );
-        return getPath( metadata, getRepositoryKey( repository, context ) );
+        return artifactPathComposer.getPathForMetadata( metadata, getRepositoryKey( repository, context ) );
     }
 
-    String getRepositoryKey( RemoteRepository repository, String context )
+    protected String getRepositoryKey( RemoteRepository repository, String context )
     {
         String key;
 
@@ -166,45 +136,7 @@ class SimpleLocalRepositoryManager
         return key;
     }
 
-    private String getPath( Metadata metadata, String repositoryKey )
-    {
-        StringBuilder path = new StringBuilder( 128 );
-
-        if ( metadata.getGroupId().length() > 0 )
-        {
-            path.append( metadata.getGroupId().replace( '.', '/' ) ).append( '/' );
-
-            if ( metadata.getArtifactId().length() > 0 )
-            {
-                path.append( metadata.getArtifactId() ).append( '/' );
-
-                if ( metadata.getVersion().length() > 0 )
-                {
-                    path.append( metadata.getVersion() ).append( '/' );
-                }
-            }
-        }
-
-        path.append( insertRepositoryKey( metadata.getType(), repositoryKey ) );
-
-        return path.toString();
-    }
-
-    private String insertRepositoryKey( String filename, String repositoryKey )
-    {
-        String result;
-        int idx = filename.indexOf( '.' );
-        if ( idx < 0 )
-        {
-            result = filename + '-' + repositoryKey;
-        }
-        else
-        {
-            result = filename.substring( 0, idx ) + '-' + repositoryKey + filename.substring( idx );
-        }
-        return result;
-    }
-
+    @Override
     public LocalArtifactResult find( RepositorySystemSession session, LocalArtifactRequest request )
     {
         requireNonNull( session, "session cannot be null" );
@@ -222,6 +154,7 @@ class SimpleLocalRepositoryManager
         return result;
     }
 
+    @Override
     public void add( RepositorySystemSession session, LocalArtifactRegistration request )
     {
         requireNonNull( session, "session cannot be null" );
@@ -230,11 +163,6 @@ class SimpleLocalRepositoryManager
     }
 
     @Override
-    public String toString()
-    {
-        return String.valueOf( getRepository() );
-    }
-
     public LocalMetadataResult find( RepositorySystemSession session, LocalMetadataRequest request )
     {
         requireNonNull( session, "session cannot be null" );
@@ -265,6 +193,7 @@ class SimpleLocalRepositoryManager
         return result;
     }
 
+    @Override
     public void add( RepositorySystemSession session, LocalMetadataRegistration request )
     {
         requireNonNull( session, "session cannot be null" );
@@ -272,4 +201,9 @@ class SimpleLocalRepositoryManager
         // noop
     }
 
+    @Override
+    public String toString()
+    {
+        return String.valueOf( getRepository() );
+    }
 }
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/SimpleLocalRepositoryManagerFactory.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/SimpleLocalRepositoryManagerFactory.java
index 6903e4ce..d62301f5 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/SimpleLocalRepositoryManagerFactory.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/SimpleLocalRepositoryManagerFactory.java
@@ -19,6 +19,7 @@ package org.eclipse.aether.internal.impl;
  * under the License.
  */
 
+import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Singleton;
 
@@ -29,6 +30,10 @@ import org.eclipse.aether.repository.LocalRepository;
 import org.eclipse.aether.repository.LocalRepositoryManager;
 import org.eclipse.aether.repository.NoLocalRepositoryManagerException;
 import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory;
+import org.eclipse.aether.spi.locator.Service;
+import org.eclipse.aether.spi.locator.ServiceLocator;
+
+import static java.util.Objects.requireNonNull;
 
 /**
  * Creates local repository managers for repository type {@code "simple"}.
@@ -36,24 +41,39 @@ import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory;
 @Singleton
 @Named( "simple" )
 public class SimpleLocalRepositoryManagerFactory
-    implements LocalRepositoryManagerFactory
+    implements LocalRepositoryManagerFactory, Service
 {
     private float priority;
 
+    private ArtifactPathComposer artifactPathComposer;
+
     public SimpleLocalRepositoryManagerFactory()
     {
         // enable no-arg constructor
     }
 
+    @Inject
+    public SimpleLocalRepositoryManagerFactory( final ArtifactPathComposer artifactPathComposer )
+    {
+        this.artifactPathComposer = requireNonNull( artifactPathComposer );
+    }
+
+    @Override
+    public void initService( final ServiceLocator locator )
+    {
+        this.artifactPathComposer = Objects.requireNonNull( locator.getService( ArtifactPathComposer.class ) );
+    }
+
+    @Override
     public LocalRepositoryManager newInstance( RepositorySystemSession session, LocalRepository repository )
         throws NoLocalRepositoryManagerException
     {
-        Objects.requireNonNull( session, "session cannot be null" );
-        Objects.requireNonNull( repository, "repository cannot be null" );
+        requireNonNull( session, "session cannot be null" );
+        requireNonNull( repository, "repository cannot be null" );
 
         if ( "".equals( repository.getContentType() ) || "simple".equals( repository.getContentType() ) )
         {
-            return new SimpleLocalRepositoryManager( repository.getBasedir() );
+            return new SimpleLocalRepositoryManager( repository.getBasedir(), "simple", artifactPathComposer );
         }
         else
         {
@@ -61,6 +81,7 @@ public class SimpleLocalRepositoryManagerFactory
         }
     }
 
+    @Override
     public float getPriority()
     {
         return priority;
diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerTest.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerTest.java
index 729b0123..f4da7edc 100644
--- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerTest.java
+++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerTest.java
@@ -99,7 +99,7 @@ public class EnhancedLocalRepositoryManagerTest
         basedir = TestFileUtils.createTempDir( "enhanced-repo" );
         session = TestUtils.newSession();
         trackingFileManager = new DefaultTrackingFileManager();
-        manager = new EnhancedLocalRepositoryManager( basedir, session, trackingFileManager );
+        manager = new EnhancedLocalRepositoryManager( basedir, new DefaultArtifactPathComposer(), session, trackingFileManager );
 
         artifactFile = new File( basedir, manager.getPathForLocalArtifact( artifact ) );
     }
diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/FileProvidedChecksumsSourceTest.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/FileProvidedChecksumsSourceTest.java
index e062a32b..14ec97cd 100644
--- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/FileProvidedChecksumsSourceTest.java
+++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/FileProvidedChecksumsSourceTest.java
@@ -57,7 +57,7 @@ public class FileProvidedChecksumsSourceTest
     RemoteRepository repository = new RemoteRepository.Builder("test", "default", "https://irrelevant.com").build();
     session = TestUtils.newSession();
     repositoryLayout = new Maven2RepositoryLayoutFactory().newInstance(session, repository);
-    subject = new FileProvidedChecksumsSource(new TestFileProcessor() );
+    subject = new FileProvidedChecksumsSource(new TestFileProcessor(), new DefaultArtifactPathComposer() );
 
     // populate local repository
     Path baseDir = session.getLocalRepository().getBasedir().toPath().resolve( FileProvidedChecksumsSource.LOCAL_REPO_PREFIX);
diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/SimpleLocalRepositoryManagerTest.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/SimpleLocalRepositoryManagerTest.java
index 9a985261..17268b42 100644
--- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/SimpleLocalRepositoryManagerTest.java
+++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/SimpleLocalRepositoryManagerTest.java
@@ -27,7 +27,6 @@ import java.io.IOException;
 import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
-import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManager;
 import org.eclipse.aether.internal.test.util.TestFileUtils;
 import org.eclipse.aether.internal.test.util.TestUtils;
 import org.eclipse.aether.repository.LocalArtifactRequest;
@@ -53,7 +52,7 @@ public class SimpleLocalRepositoryManagerTest
         throws IOException
     {
         basedir = TestFileUtils.createTempDir( "simple-repo" );
-        manager = new SimpleLocalRepositoryManager( basedir );
+        manager = new SimpleLocalRepositoryManager( basedir, "simple", new DefaultArtifactPathComposer() );
         session = TestUtils.newSession();
     }