]> source.dussan.org Git - archiva.git/commitdiff
Adding new API methods for repository content. Still in progress.
authorMartin Stockhammer <martin_s@apache.org>
Mon, 17 Feb 2020 21:20:43 +0000 (22:20 +0100)
committerMartin Stockhammer <martin_s@apache.org>
Mon, 17 Feb 2020 21:20:43 +0000 (22:20 +0100)
archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/ManagedRepositoryContent.java
archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryContent.java
archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java
archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/mock/ManagedRepositoryContentMock.java
archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java
archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/content/maven2/AbstractDefaultRepositoryContent.java
archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/content/maven2/ManagedDefaultRepositoryContent.java

index 5dd39cc45f8f4e2f860916e2c33efe9d3889a264..3c0dc1d55e0684278a5c51e7e5403c57aecdaede 100644 (file)
@@ -23,10 +23,19 @@ import org.apache.archiva.model.ArchivaArtifact;
 import org.apache.archiva.model.ArtifactReference;
 import org.apache.archiva.model.ProjectReference;
 import org.apache.archiva.model.VersionedReference;
+import org.apache.archiva.repository.content.Artifact;
+import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.ItemNotFoundException;
+import org.apache.archiva.repository.content.ItemSelector;
+import org.apache.archiva.repository.content.Namespace;
+import org.apache.archiva.repository.content.Project;
+import org.apache.archiva.repository.content.Version;
 import org.apache.archiva.repository.storage.StorageAsset;
 
+import java.nio.file.Path;
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Stream;
 
 /**
  * ManagedRepositoryContent interface for interacting with a managed repository in an abstract way,
@@ -47,6 +56,7 @@ public interface ManagedRepositoryContent extends RepositoryContent
      */
     VersionedReference toVersion( String groupId, String artifactId, String version );
 
+
     /**
      * Returns the version reference that represents the generic version, which means that
      * snapshot versions are converted to <VERSION>-SNAPSHOT
@@ -74,6 +84,205 @@ public interface ManagedRepositoryContent extends RepositoryContent
      */
     ArtifactReference toArtifact( String groupId, String artifactId, String version, String type, String classifier);
 
+    /**
+     * Removes the specified content item and all content stored under the given item.
+     *
+     * @param item the item.
+     * @throws ItemNotFoundException if the item cannot be found
+     * @throws ContentAccessException if the deletion was not possible or only partly successful, because the access
+     *  to the artifacts failed
+     */
+    void deleteItem( ContentItem item) throws ItemNotFoundException, ContentAccessException;
+
+    /**
+     * Returns the namespace for the given selected coordinates. The selector must specify a namespace. All other
+     * coordinates are ignored.
+     * The following coordinates must be set at the given selector:
+     * <ul>
+     *     <li>namespace</li>
+     * </ul>
+     * If not, a {@link IllegalArgumentException} will be thrown.
+     *
+     * @param namespaceSelector the selectory with the namespace coordinates
+     * @return the namespace
+     * @throws ItemNotFoundException if the item does not exist
+     * @throws ContentAccessException if the item cannot be accessed
+     * @throws IllegalArgumentException if the selector has no namespace specified
+     */
+    Namespace getNamespace( ItemSelector namespaceSelector ) throws ContentAccessException, IllegalArgumentException;
+
+    /**
+     * Returns the project for the given coordinates.
+     * The following coordinates must be set at the given selector:
+     * <ul>
+     *     <li>namespace</li>
+     *     <li>projectId</li>
+     * </ul>
+     * If not, a {@link IllegalArgumentException} will be thrown.
+     * Additional coordinates will be ignored.
+     *
+     * @param projectSelector
+     * @return the project instance
+     * @throws ItemNotFoundException if the project does not exist
+     * @throws ContentAccessException if the item cannot be accessed
+     * @throws IllegalArgumentException if the selector does not specify the required coordinates
+     */
+    Project getProject( ItemSelector projectSelector ) throws ContentAccessException, IllegalArgumentException;
+
+    /**
+     * Returns the version for the given coordinates.
+     * The following coordinates must be set at the given selector:
+     * <ul>
+     *     <li>namespace</li>
+     *     <li>projectId</li>
+     *     <li>version</li>
+     * </ul>
+     * If not, a {@link IllegalArgumentException} will be thrown.
+     *
+     * Additional coordinates will be ignored.
+     *
+     * @param versionCoordinates
+     * @return the version object
+     * @throws ItemNotFoundException
+     * @throws ContentAccessException
+     * @throws IllegalArgumentException
+     */
+    Version getVersion(ItemSelector versionCoordinates) throws ContentAccessException, IllegalArgumentException;
+
+    /**
+     * Returns the artifact for the given coordinates.
+     *
+     * Normally the following coordinates should be set at the given selector:
+     * <ul>
+     *     <li>namespace</li>
+     *     <li>artifactVersion and or version</li>
+     *     <li>artifactId or projectId</li>
+     * </ul>
+     * If the coordinates do not provide enough information for selecting a artifact, a {@link IllegalArgumentException} will be thrown
+     * It depends on the repository type, what exactly is deleted for a given set of coordinates. Some repository type
+     * may have different required and optional coordinates. For further information please check the documentation for the
+     * type specific implementations.
+     *
+     * The following coordinates are optional and may further specify the artifact to delete.
+     * <ul>
+     *     <li>classifier</li>
+     *     <li>type</li>
+     *     <li>extension</li>
+     * </ul>
+     *
+     * @param selector the selector with the artifact coordinates
+     * @return a artifact
+     * @throws ItemNotFoundException if the selector coordinates do not specify a artifact
+     * @throws ContentAccessException if the access to the underlying storage failed
+     */
+    Artifact getArtifact(ItemSelector selector) throws ContentAccessException;
+
+
+    /**
+     * Returns the artifacts that match the given selector. It is up to the repository implementation
+     * what artifacts are returned for a given set of coordinates.
+     *
+     * @param selector the selector for the artifacts
+     * @return a list of artifacts.
+     * @throws ItemNotFoundException if the specified coordinates cannot be found in the repository
+     * @throws ContentAccessException if the access to the underlying storage failed
+     */
+    List<Artifact> getAllArtifacts( ItemSelector selector) throws ContentAccessException;
+
+    /**
+     * Returns the artifacts that match the given selector. It is up to the repository implementation
+     * what artifacts are returned for a given set of coordinates.
+     *
+     * The returned stream is autoclosable and should always closed after using it.
+     *
+     * There is no guarantee about the order of the returned artifacts
+     *
+     * @param selector the selector for the artifacts
+     * @return a stream with artifact elements.
+     * @throws ItemNotFoundException if the specified coordinates cannot be found in the repository
+     * @throws ContentAccessException if the access to the underlying storage failed
+     */
+    Stream<Artifact> getAllArtifactStream( ItemSelector selector) throws ContentAccessException;
+
+
+    /**
+     * Return the projects that are part of the given namespace.
+     *
+     * @param namespace the namespace
+     * @return the list of projects or a empty list, if there are no projects for the given namespace.
+     */
+    List<Project> getProjects(Namespace namespace) throws ContentAccessException;
+
+    /**
+     * Return the existing versions of the given project.
+     *
+     * @param project the project
+     * @return a list of versions or a empty list, if not versions are available for the specified project
+     */
+    List<Version> getVersions(Project project) throws ContentAccessException;
+
+    /**
+     * Return all the artifacts of a given content item (namespace, project, version)
+     *
+     * @param item the item
+     * @return a list of artifacts or a empty list, if no artifacts are available for the specified item
+     */
+    List<Artifact> getArtifacts( ContentItem item) throws ContentAccessException;
+
+    /**
+     * Return all the artifacts of a given namespace and all sub namespaces that are defined under the
+     * given namespace.
+     *
+     * @param namespace the namespace, which is the parent namespace
+     * @return a list of artifacts or a empty list, if no artifacts are available for the specified namespace
+     */
+    List<Artifact> getArtifactsStartingWith( Namespace namespace ) throws ContentAccessException;
+
+
+    /**
+     * Return a stream of artifacts that are part of the given content item. The returned stream is
+     * auto closable. There is no guarantee about the order of returned artifacts.
+     *
+     * As the stream may access IO resources, you should always use call this method inside try-with-resources or
+     * make sure, that the stream is closed after using it.
+     *
+     * @param item the item from where the artifacts should be returned
+     * @return a stream of artifacts. The stream is auto closable. You should always make sure, that the stream
+     * is closed after use.
+     */
+    Stream<Artifact> getArtifactStream( ContentItem item ) throws ContentAccessException;
+
+
+    /**
+     * Return a stream of all artifacts that are available for the given namespace and its sub namespaces. The artifacts
+     * are retrieved recursively. There is no guarantee about the order of returned artifacts.
+     *
+     * As the stream may access IO resources, you should always use call this method inside try-with-resources or
+     * make sure, that the stream is closed after using it.
+     *
+     * @param namespace the namespace from where the artifacts should be returned
+     * @return a stream of artifacts. The stream is auto closable. You should always make sure, that the stream
+     * is closed after use.
+     */
+    Stream<Artifact> getArtifactStreamStartingWith( Namespace namespace ) throws ContentAccessException;
+
+
+    /**
+     * Returns true, if the selector coordinates point to a existing item in the repository.
+     *
+     * @param selector the item selector
+     * @return <code>true</code>, if there exists such a item, otherwise <code>false</code>
+     */
+    boolean hasContent( ItemSelector selector );
+
+    /**
+     * Copies the artifact to the given destination coordinates
+     *
+     * @param sourceFile the path to the source file
+     * @param destination the coordinates of the destination
+     * @throws IllegalArgumentException if the destination is not valid
+     */
+    void copyArtifact( Path sourceFile, ItemSelector destination ) throws IllegalArgumentException;
 
     /**
      * Delete from the managed repository all files / directories associated with the
@@ -85,6 +294,8 @@ public interface ManagedRepositoryContent extends RepositoryContent
     void deleteVersion( VersionedReference reference )
         throws ContentNotFoundException, ContentAccessException;
 
+
+
     /**
      * delete a specified artifact from the repository
      *
@@ -94,6 +305,8 @@ public interface ManagedRepositoryContent extends RepositoryContent
     void deleteArtifact( ArtifactReference artifactReference )
         throws ContentNotFoundException, ContentAccessException;
 
+
+
     /**
      * @param groupId
      * @throws ContentNotFoundException
@@ -102,6 +315,9 @@ public interface ManagedRepositoryContent extends RepositoryContent
     void deleteGroupId( String groupId )
         throws ContentNotFoundException, ContentAccessException;
 
+
+
+
     /**
      *
      * @param namespace groupId for maven
@@ -119,6 +335,8 @@ public interface ManagedRepositoryContent extends RepositoryContent
     void deleteProject(ProjectReference reference) throws ContentNotFoundException, ContentAccessException;
 
 
+
+
     /**
      * <p>
      * Convenience method to get the repository id.
@@ -168,6 +386,13 @@ public interface ManagedRepositoryContent extends RepositoryContent
      */
     List<ArtifactReference> getRelatedArtifacts( VersionedReference reference )
         throws ContentNotFoundException, LayoutException, ContentAccessException;
+
+
+
+
+
+
+
     /**
      * Returns all the assets that belong to a given artifact type. The list returned contain
      * all the files that correspond to the given artifact reference.
index f72645dba1d6b98c8b7ae87792e7d62b6800f783..9d6869f4229d6eaac89c7a7152b65854b187df55 100644 (file)
@@ -72,4 +72,6 @@ public interface RepositoryContent
      * @return a item selector that would select the given path
      */
     ItemSelector toItemSelector(String path) throws LayoutException;
+
+
 }
index c252a8ab4c88dab6fc950ee4cdcaee1008807808..9e56da0463f498d0879cb56e5c2a3b7c66dde497 100644 (file)
@@ -28,12 +28,20 @@ import org.apache.archiva.repository.ContentNotFoundException;
 import org.apache.archiva.repository.LayoutException;
 import org.apache.archiva.repository.ManagedRepository;
 import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.content.Artifact;
+import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.ItemNotFoundException;
 import org.apache.archiva.repository.content.ItemSelector;
+import org.apache.archiva.repository.content.Namespace;
+import org.apache.archiva.repository.content.Project;
+import org.apache.archiva.repository.content.Version;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.springframework.stereotype.Service;
 
+import java.nio.file.Path;
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Stream;
 
 /**
  * @author Martin Stockhammer <martin_s@apache.org>
@@ -67,24 +75,119 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent
         return null;
     }
 
+    @Override
+    public void deleteItem( ContentItem item ) throws ItemNotFoundException, ContentAccessException
+    {
+
+    }
+
+    @Override
+    public Namespace getNamespace( ItemSelector namespaceSelector ) throws ContentAccessException, IllegalArgumentException
+    {
+        return null;
+    }
+
+    @Override
+    public Project getProject( ItemSelector projectSelector ) throws ContentAccessException, IllegalArgumentException
+    {
+        return null;
+    }
+
+
     @Override
     public void deleteVersion( VersionedReference reference ) throws ContentNotFoundException, ContentAccessException
     {
 
     }
 
+
+    @Override
+    public Version getVersion( ItemSelector versionCoordinates ) throws ContentAccessException, IllegalArgumentException
+    {
+        return null;
+    }
+
     @Override
     public void deleteArtifact( ArtifactReference artifactReference ) throws ContentNotFoundException, ContentAccessException
     {
 
     }
 
+
+    @Override
+    public Artifact getArtifact( ItemSelector selector ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Artifact> getAllArtifacts( ItemSelector selector ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public Stream<Artifact> getAllArtifactStream( ItemSelector selector ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Project> getProjects( Namespace namespace ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Version> getVersions( Project project ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Artifact> getArtifacts( ContentItem item ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Artifact> getArtifactsStartingWith( Namespace namespace ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public Stream<Artifact> getArtifactStream( ContentItem item ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public Stream<Artifact> getArtifactStreamStartingWith( Namespace namespace ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public boolean hasContent( ItemSelector selector )
+    {
+        return false;
+    }
+
+    @Override
+    public void copyArtifact( Path sourceFile, ItemSelector destination ) throws IllegalArgumentException
+    {
+
+    }
+
+
     @Override
     public void deleteGroupId( String groupId ) throws ContentNotFoundException, ContentAccessException
     {
 
     }
 
+
     @Override
     public void deleteProject( String namespace, String projectId ) throws ContentNotFoundException, ContentAccessException
     {
index 69fa8d9e718c07d2370a8b07d2a6ddd7e1eabb32..8c7ebabd117fc543664ff3e3e7907a5a1c8579a8 100644 (file)
@@ -28,12 +28,19 @@ import org.apache.archiva.model.ArtifactReference;
 import org.apache.archiva.model.ProjectReference;
 import org.apache.archiva.model.VersionedReference;
 import org.apache.archiva.repository.*;
+import org.apache.archiva.repository.content.Artifact;
+import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.ItemNotFoundException;
 import org.apache.archiva.repository.content.ItemSelector;
+import org.apache.archiva.repository.content.Namespace;
+import org.apache.archiva.repository.content.Project;
+import org.apache.archiva.repository.content.Version;
 import org.apache.archiva.repository.storage.FilesystemStorage;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.commons.lang3.StringUtils;
 
 import java.io.IOException;
+import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.List;
@@ -41,6 +48,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Stream;
 
 /**
  * @author Martin Stockhammer <martin_s@apache.org>
@@ -83,6 +91,96 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent
         return null;
     }
 
+    @Override
+    public void deleteItem( ContentItem item ) throws ItemNotFoundException, ContentAccessException
+    {
+
+    }
+
+    @Override
+    public Namespace getNamespace( ItemSelector namespaceSelector ) throws ContentAccessException, IllegalArgumentException
+    {
+        return null;
+    }
+
+    @Override
+    public Project getProject( ItemSelector projectSelector ) throws ContentAccessException, IllegalArgumentException
+    {
+        return null;
+    }
+
+    @Override
+    public Version getVersion( ItemSelector versionCoordinates ) throws ContentAccessException, IllegalArgumentException
+    {
+        return null;
+    }
+
+    @Override
+    public Artifact getArtifact( ItemSelector selector ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Artifact> getAllArtifacts( ItemSelector selector ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public Stream<Artifact> getAllArtifactStream( ItemSelector selector ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Project> getProjects( Namespace namespace ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Version> getVersions( Project project ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Artifact> getArtifacts( ContentItem item ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Artifact> getArtifactsStartingWith( Namespace namespace ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public Stream<Artifact> getArtifactStream( ContentItem item ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public Stream<Artifact> getArtifactStreamStartingWith( Namespace namespace ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public boolean hasContent( ItemSelector selector )
+    {
+        return false;
+    }
+
+    @Override
+    public void copyArtifact( Path sourceFile, ItemSelector destination ) throws IllegalArgumentException
+    {
+
+    }
+
     @Override
     public void deleteVersion( VersionedReference reference ) throws ContentNotFoundException, ContentAccessException
     {
index 53950cca1acf93a6725bc476e2ad3a7624287ab8..9b8b82a47c6f4aaa15aa346777583bf3f8a367db 100644 (file)
@@ -28,7 +28,13 @@ import org.apache.archiva.model.ArtifactReference;
 import org.apache.archiva.model.ProjectReference;
 import org.apache.archiva.model.VersionedReference;
 import org.apache.archiva.repository.*;
+import org.apache.archiva.repository.content.Artifact;
+import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.ItemNotFoundException;
 import org.apache.archiva.repository.content.ItemSelector;
+import org.apache.archiva.repository.content.Namespace;
+import org.apache.archiva.repository.content.Project;
+import org.apache.archiva.repository.content.Version;
 import org.apache.archiva.repository.storage.FilesystemStorage;
 import org.apache.archiva.repository.storage.RepositoryStorage;
 import org.apache.archiva.repository.storage.StorageAsset;
@@ -36,6 +42,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 
 import java.io.IOException;
+import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.List;
@@ -43,6 +50,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Stream;
 
 /**
  * @author Martin Stockhammer <martin_s@apache.org>
@@ -87,6 +95,96 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent
         return null;
     }
 
+    @Override
+    public void deleteItem( ContentItem item ) throws ItemNotFoundException, ContentAccessException
+    {
+
+    }
+
+    @Override
+    public Namespace getNamespace( ItemSelector namespaceSelector ) throws ContentAccessException, IllegalArgumentException
+    {
+        return null;
+    }
+
+    @Override
+    public Project getProject( ItemSelector projectSelector ) throws ContentAccessException, IllegalArgumentException
+    {
+        return null;
+    }
+
+    @Override
+    public Version getVersion( ItemSelector versionCoordinates ) throws ContentAccessException, IllegalArgumentException
+    {
+        return null;
+    }
+
+    @Override
+    public Artifact getArtifact( ItemSelector selector ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Artifact> getAllArtifacts( ItemSelector selector ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public Stream<Artifact> getAllArtifactStream( ItemSelector selector ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Project> getProjects( Namespace namespace ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Version> getVersions( Project project ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Artifact> getArtifacts( ContentItem item ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public List<Artifact> getArtifactsStartingWith( Namespace namespace ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public Stream<Artifact> getArtifactStream( ContentItem item ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public Stream<Artifact> getArtifactStreamStartingWith( Namespace namespace ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    @Override
+    public boolean hasContent( ItemSelector selector )
+    {
+        return false;
+    }
+
+    @Override
+    public void copyArtifact( Path sourceFile, ItemSelector destination ) throws IllegalArgumentException
+    {
+
+    }
+
     @Override
     public void deleteVersion( VersionedReference reference ) throws ContentNotFoundException, ContentAccessException
     {
index 5c7da20043eed1e03e9d416f11bcee034066b445..1e1381c0ff6b8621a5d2c549363193f77e047494 100644 (file)
@@ -205,7 +205,7 @@ public abstract class AbstractDefaultRepositoryContent implements RepositoryCont
                        reference.getClassifier(), reference.getType() );
     }
 
-    private String formatAsDirectory( String directory )
+    protected String formatAsDirectory( String directory )
     {
         return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR );
     }
index cfb37a064a9e5dc707ead106135f9ac175a1336b..731a1063c41df8514ab9d078d025e8ee78824747 100644 (file)
@@ -20,6 +20,8 @@ package org.apache.archiva.repository.content.maven2;
  */
 
 import org.apache.archiva.common.filelock.FileLockManager;
+import org.apache.archiva.common.utils.FileUtils;
+import org.apache.archiva.common.utils.PathUtil;
 import org.apache.archiva.common.utils.VersionUtil;
 import org.apache.archiva.configuration.FileTypes;
 import org.apache.archiva.metadata.repository.storage.maven2.ArtifactMappingProvider;
@@ -34,8 +36,17 @@ import org.apache.archiva.repository.EditableManagedRepository;
 import org.apache.archiva.repository.LayoutException;
 import org.apache.archiva.repository.ManagedRepository;
 import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.content.Artifact;
+import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.ItemNotFoundException;
 import org.apache.archiva.repository.content.ItemSelector;
+import org.apache.archiva.repository.content.Namespace;
+import org.apache.archiva.repository.content.Project;
+import org.apache.archiva.repository.content.Version;
+import org.apache.archiva.repository.content.base.ArchivaNamespace;
+import org.apache.archiva.repository.content.base.ArchivaProject;
 import org.apache.archiva.repository.storage.StorageAsset;
+import org.apache.commons.collections4.map.ReferenceMap;
 import org.apache.commons.lang3.StringUtils;
 
 import java.io.IOException;
@@ -69,6 +80,11 @@ public class ManagedDefaultRepositoryContent
 
     FileLockManager lockManager;
 
+    private ReferenceMap<String, Namespace> namespaceMap = new ReferenceMap<>( );
+    private ReferenceMap<StorageAsset, Project> projectMap = new ReferenceMap<>( );
+    private ReferenceMap<StorageAsset, Version> versionMap = new ReferenceMap<>( );
+    private ReferenceMap<StorageAsset, Artifact> artifactMap = new ReferenceMap<>( );
+
     public ManagedDefaultRepositoryContent(ManagedRepository repository, FileTypes fileTypes, FileLockManager lockManager) {
         super(Collections.singletonList( new DefaultArtifactMappingProvider() ));
         setFileTypes( fileTypes );
@@ -117,6 +133,196 @@ public class ManagedDefaultRepositoryContent
         return new ArtifactReference( ).groupId( groupId ).artifactId( artifactId ).version( version ).type( type ).classifier( classifier );
     }
 
+    @Override
+    public void deleteItem( ContentItem item ) throws ItemNotFoundException, ContentAccessException
+    {
+        final Path baseDirectory = getRepoDir( );
+        final Path itemPath = item.getAsset( ).getFilePath( );
+        if ( !Files.exists( itemPath ) )
+        {
+            throw new ItemNotFoundException( "The item " + item.toString() + "does not exist in the repository " + getId( ) );
+        }
+        if ( !itemPath.toAbsolutePath().startsWith( baseDirectory.toAbsolutePath() ) )
+        {
+            log.error( "The namespace {} to delete from repository {} is not a subdirectory of the repository base.", item, getId( ) );
+            log.error( "Namespace directory: {}", itemPath );
+            log.error( "Repository directory: {}", baseDirectory );
+            throw new ContentAccessException( "Inconsistent directories found. Could not delete namespace." );
+        }
+        try
+        {
+            if (Files.isDirectory( itemPath ))
+            {
+                FileUtils.deleteDirectory( itemPath );
+            } else {
+                Files.deleteIfExists( itemPath );
+            }
+        }
+        catch ( IOException e )
+        {
+            log.error( "Could not delete namespace directory {}: {}", itemPath, e.getMessage( ), e );
+            throw new ContentAccessException( "Error occured while deleting namespace " + item + ": " + e.getMessage( ), e );
+        }
+    }
+
+    private StorageAsset getAsset(String namespace) {
+        String namespacePath = formatAsDirectory( namespace.trim() );
+        if (StringUtils.isEmpty( namespacePath )) {
+            namespacePath = "";
+        }
+        return getAsset(namespacePath);
+    }
+
+    private StorageAsset getAsset(String namespace, String project) {
+        return getAsset( namespace ).resolve( project );
+    }
+
+    private StorageAsset getAsset(String namespace, String project, String version) {
+        return getAsset( namespace, project ).resolve( version );
+    }
+
+    private StorageAsset getAsset(String namespace, String project, String version, String fileName) {
+        return getAsset( namespace, project, version ).resolve( fileName );
+    }
+
+    @Override
+    public Namespace getNamespace( final ItemSelector namespaceSelector ) throws ContentAccessException, IllegalArgumentException
+    {
+        return namespaceMap.computeIfAbsent( namespaceSelector.getNamespace(),
+            namespace -> {
+                StorageAsset nsPath = getAsset( namespace );
+                return ArchivaNamespace.withRepository( this ).withAsset( nsPath ).
+                    withNamespace( namespace ).build( );
+            });
+    }
+
+
+    @Override
+    public Project getProject( final ItemSelector projectSelector ) throws ContentAccessException, IllegalArgumentException
+    {
+        if (StringUtils.isEmpty( projectSelector.getProjectId() )) {
+            throw new IllegalArgumentException( "Project id must be set" );
+        }
+        final StorageAsset path = getAsset( projectSelector.getNamespace( ), projectSelector.getProjectId( ) );
+        return projectMap.computeIfAbsent( path, projectPath -> {
+            final Namespace ns = getNamespace( projectSelector );
+            return ArchivaProject.withAsset( projectPath ).withNamespace( ns ).withId( projectSelector.getProjectId( ) ).build( );
+        }
+        );
+    }
+
+
+    /*
+        TBD
+     */
+    @Override
+    public Version getVersion( ItemSelector versionCoordinates ) throws ContentAccessException, IllegalArgumentException
+    {
+        if (StringUtils.isEmpty( versionCoordinates.getVersion() )) {
+            throw new IllegalArgumentException( "Version must be set" );
+        }
+        return null;
+    }
+
+
+    /*
+        TBD
+     */
+    @Override
+    public Artifact getArtifact( ItemSelector selector ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    /*
+        TBD
+     */
+    @Override
+    public List<Artifact> getAllArtifacts( ItemSelector selector ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    /*
+        TBD
+     */
+    @Override
+    public Stream<Artifact> getAllArtifactStream( ItemSelector selector ) throws ContentAccessException
+    {
+        return null;
+    }
+
+    /*
+        TBD
+     */
+    @Override
+    public List<Project> getProjects( Namespace namespace )
+    {
+        return null;
+    }
+
+    /*
+        TBD
+     */
+    @Override
+    public List<Version> getVersions( Project project )
+    {
+        return null;
+    }
+
+    /*
+        TBD
+     */
+    @Override
+    public List<Artifact> getArtifacts( ContentItem item )
+    {
+        return null;
+    }
+
+    /*
+        TBD
+     */
+    @Override
+    public List<Artifact> getArtifactsStartingWith( Namespace namespace )
+    {
+        return null;
+    }
+
+    /*
+        TBD
+     */
+    @Override
+    public Stream<Artifact> getArtifactStream( ContentItem item )
+    {
+        return null;
+    }
+
+    /*
+        TBD
+     */
+    @Override
+    public Stream<Artifact> getArtifactStreamStartingWith( Namespace namespace )
+    {
+        return null;
+    }
+
+    /*
+        TBD
+     */
+    @Override
+    public boolean hasContent( ItemSelector selector )
+    {
+        return false;
+    }
+
+    /*
+        TBD
+     */
+    @Override
+    public void copyArtifact( Path sourceFile, ItemSelector destination ) throws IllegalArgumentException
+    {
+
+    }
 
     @Override
     public void deleteVersion( VersionedReference ref ) throws ContentNotFoundException, ContentAccessException