From b06b167a847a04b5136e9d7b6a9fa4c04d776894 Mon Sep 17 00:00:00 2001 From: Martin Stockhammer Date: Mon, 17 Feb 2020 22:20:43 +0100 Subject: [PATCH] Adding new API methods for repository content. Still in progress. --- .../repository/ManagedRepositoryContent.java | 225 ++++++++++++++++++ .../archiva/repository/RepositoryContent.java | 2 + .../mock/ManagedRepositoryContentMock.java | 103 ++++++++ .../mock/ManagedRepositoryContentMock.java | 98 ++++++++ .../mock/ManagedRepositoryContentMock.java | 98 ++++++++ .../AbstractDefaultRepositoryContent.java | 2 +- .../ManagedDefaultRepositoryContent.java | 206 ++++++++++++++++ 7 files changed, 733 insertions(+), 1 deletion(-) diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/ManagedRepositoryContent.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/ManagedRepositoryContent.java index 5dd39cc45..3c0dc1d55 100644 --- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/ManagedRepositoryContent.java +++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/ManagedRepositoryContent.java @@ -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 -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: + * + * 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: + * + * 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: + * + * 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: + * + * 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. + * + * + * @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 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 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 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 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 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 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 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 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 true, if there exists such a item, otherwise false + */ + 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; + + /** *

* Convenience method to get the repository id. @@ -168,6 +386,13 @@ public interface ManagedRepositoryContent extends RepositoryContent */ List 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. diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryContent.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryContent.java index f72645dba..9d6869f42 100644 --- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryContent.java +++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryContent.java @@ -72,4 +72,6 @@ public interface RepositoryContent * @return a item selector that would select the given path */ ItemSelector toItemSelector(String path) throws LayoutException; + + } diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java b/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java index c252a8ab4..9e56da046 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java @@ -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 @@ -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 getAllArtifacts( ItemSelector selector ) throws ContentAccessException + { + return null; + } + + @Override + public Stream getAllArtifactStream( ItemSelector selector ) throws ContentAccessException + { + return null; + } + + @Override + public List getProjects( Namespace namespace ) throws ContentAccessException + { + return null; + } + + @Override + public List getVersions( Project project ) throws ContentAccessException + { + return null; + } + + @Override + public List getArtifacts( ContentItem item ) throws ContentAccessException + { + return null; + } + + @Override + public List getArtifactsStartingWith( Namespace namespace ) throws ContentAccessException + { + return null; + } + + @Override + public Stream getArtifactStream( ContentItem item ) throws ContentAccessException + { + return null; + } + + @Override + public Stream 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 { diff --git a/archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/mock/ManagedRepositoryContentMock.java b/archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/mock/ManagedRepositoryContentMock.java index 69fa8d9e7..8c7ebabd1 100644 --- a/archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/mock/ManagedRepositoryContentMock.java +++ b/archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/mock/ManagedRepositoryContentMock.java @@ -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 @@ -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 getAllArtifacts( ItemSelector selector ) throws ContentAccessException + { + return null; + } + + @Override + public Stream getAllArtifactStream( ItemSelector selector ) throws ContentAccessException + { + return null; + } + + @Override + public List getProjects( Namespace namespace ) throws ContentAccessException + { + return null; + } + + @Override + public List getVersions( Project project ) throws ContentAccessException + { + return null; + } + + @Override + public List getArtifacts( ContentItem item ) throws ContentAccessException + { + return null; + } + + @Override + public List getArtifactsStartingWith( Namespace namespace ) throws ContentAccessException + { + return null; + } + + @Override + public Stream getArtifactStream( ContentItem item ) throws ContentAccessException + { + return null; + } + + @Override + public Stream 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 { diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java index 53950cca1..9b8b82a47 100644 --- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java +++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java @@ -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 @@ -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 getAllArtifacts( ItemSelector selector ) throws ContentAccessException + { + return null; + } + + @Override + public Stream getAllArtifactStream( ItemSelector selector ) throws ContentAccessException + { + return null; + } + + @Override + public List getProjects( Namespace namespace ) throws ContentAccessException + { + return null; + } + + @Override + public List getVersions( Project project ) throws ContentAccessException + { + return null; + } + + @Override + public List getArtifacts( ContentItem item ) throws ContentAccessException + { + return null; + } + + @Override + public List getArtifactsStartingWith( Namespace namespace ) throws ContentAccessException + { + return null; + } + + @Override + public Stream getArtifactStream( ContentItem item ) throws ContentAccessException + { + return null; + } + + @Override + public Stream 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 { diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/content/maven2/AbstractDefaultRepositoryContent.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/content/maven2/AbstractDefaultRepositoryContent.java index 5c7da2004..1e1381c0f 100644 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/content/maven2/AbstractDefaultRepositoryContent.java +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/content/maven2/AbstractDefaultRepositoryContent.java @@ -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 ); } diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/content/maven2/ManagedDefaultRepositoryContent.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/content/maven2/ManagedDefaultRepositoryContent.java index cfb37a064..731a1063c 100644 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/content/maven2/ManagedDefaultRepositoryContent.java +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/content/maven2/ManagedDefaultRepositoryContent.java @@ -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 namespaceMap = new ReferenceMap<>( ); + private ReferenceMap projectMap = new ReferenceMap<>( ); + private ReferenceMap versionMap = new ReferenceMap<>( ); + private ReferenceMap 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 getAllArtifacts( ItemSelector selector ) throws ContentAccessException + { + return null; + } + + /* + TBD + */ + @Override + public Stream getAllArtifactStream( ItemSelector selector ) throws ContentAccessException + { + return null; + } + + /* + TBD + */ + @Override + public List getProjects( Namespace namespace ) + { + return null; + } + + /* + TBD + */ + @Override + public List getVersions( Project project ) + { + return null; + } + + /* + TBD + */ + @Override + public List getArtifacts( ContentItem item ) + { + return null; + } + + /* + TBD + */ + @Override + public List getArtifactsStartingWith( Namespace namespace ) + { + return null; + } + + /* + TBD + */ + @Override + public Stream getArtifactStream( ContentItem item ) + { + return null; + } + + /* + TBD + */ + @Override + public Stream 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 -- 2.39.5