You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by ma...@apache.org on 2020/03/01 19:26:27 UTC
[archiva] 05/05: Additional methods for repository content
This is an automated email from the ASF dual-hosted git repository.
martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git
commit 939d127869e6eb3854adbd1cd9a0e54ec03e4f56
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Sun Mar 1 20:25:59 2020 +0100
Additional methods for repository content
---
.../repository/ManagedRepositoryContent.java | 26 +-
.../content/base/builder/ProjectOptBuilder.java | 2 -
.../mock/ManagedRepositoryContentMock.java | 16 +-
.../scanner/mock/ManagedRepositoryContentMock.java | 16 +-
.../repository/storage/fs/FilesystemAsset.java | 20 ++
.../mock/ManagedRepositoryContentMock.java | 16 +-
.../maven2/ManagedDefaultRepositoryContent.java | 313 ++++++++++++++++++++-
7 files changed, 358 insertions(+), 51 deletions(-)
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 3c0dc1d..7eb8da4 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
@@ -150,7 +150,7 @@ public interface ManagedRepositoryContent extends RepositoryContent
Version getVersion(ItemSelector versionCoordinates) throws ContentAccessException, IllegalArgumentException;
/**
- * Returns the artifact for the given coordinates.
+ * Returns the artifact object for the given coordinates.
*
* Normally the following coordinates should be set at the given selector:
* <ul>
@@ -170,8 +170,14 @@ public interface ManagedRepositoryContent extends RepositoryContent
* <li>extension</li>
* </ul>
*
+ * The method always returns a artifact object, if the coordinates are valid. It does not guarantee that the artifact
+ * exists. To check if there is really a physical representation of the artifact, use the <code>{@link Artifact#exists()}</code>
+ * method of the artifact.
+ * For upload and data retrieval use the methods of the {@link StorageAsset} reference returned in the artifact.
+ *
+ *
* @param selector the selector with the artifact coordinates
- * @return a artifact
+ * @return a artifact object
* @throws ItemNotFoundException if the selector coordinates do not specify a artifact
* @throws ContentAccessException if the access to the underlying storage failed
*/
@@ -187,7 +193,7 @@ public interface ManagedRepositoryContent extends RepositoryContent
* @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;
+ List<? extends Artifact> getAllArtifacts( ItemSelector selector) throws ContentAccessException;
/**
* Returns the artifacts that match the given selector. It is up to the repository implementation
@@ -202,7 +208,7 @@ public interface ManagedRepositoryContent extends RepositoryContent
* @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;
+ Stream<? extends Artifact> getAllArtifactStream( ItemSelector selector) throws ContentAccessException;
/**
@@ -211,7 +217,7 @@ public interface ManagedRepositoryContent extends RepositoryContent
* @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;
+ List<? extends Project> getProjects( Namespace namespace) throws ContentAccessException;
/**
* Return the existing versions of the given project.
@@ -219,7 +225,7 @@ public interface ManagedRepositoryContent extends RepositoryContent
* @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;
+ List<? extends Version> getVersions( Project project) throws ContentAccessException;
/**
* Return all the artifacts of a given content item (namespace, project, version)
@@ -227,7 +233,7 @@ public interface ManagedRepositoryContent extends RepositoryContent
* @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;
+ List<? extends Artifact> getArtifacts( ContentItem item) throws ContentAccessException;
/**
* Return all the artifacts of a given namespace and all sub namespaces that are defined under the
@@ -236,7 +242,7 @@ public interface ManagedRepositoryContent extends RepositoryContent
* @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;
+ List<? extends Artifact> getArtifactsStartingWith( Namespace namespace ) throws ContentAccessException;
/**
@@ -250,7 +256,7 @@ public interface ManagedRepositoryContent extends RepositoryContent
* @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;
+ Stream<? extends Artifact> getArtifactStream( ContentItem item ) throws ContentAccessException;
/**
@@ -264,7 +270,7 @@ public interface ManagedRepositoryContent extends RepositoryContent
* @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;
+ Stream<? extends Artifact> getArtifactStreamStartingWith( Namespace namespace ) throws ContentAccessException;
/**
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/builder/ProjectOptBuilder.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/builder/ProjectOptBuilder.java
index 4964e13..f2ebebe 100644
--- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/builder/ProjectOptBuilder.java
+++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/builder/ProjectOptBuilder.java
@@ -30,8 +30,6 @@ public interface ProjectOptBuilder
extends OptBuilder<ArchivaProject, ProjectOptBuilder>
{
- ProjectOptBuilder withId( String id );
-
ArchivaProject build( );
}
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 9e56da0..b5adf5c 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
@@ -121,49 +121,49 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent
}
@Override
- public List<Artifact> getAllArtifacts( ItemSelector selector ) throws ContentAccessException
+ public List<? extends Artifact> getAllArtifacts( ItemSelector selector ) throws ContentAccessException
{
return null;
}
@Override
- public Stream<Artifact> getAllArtifactStream( ItemSelector selector ) throws ContentAccessException
+ public Stream<? extends Artifact> getAllArtifactStream( ItemSelector selector ) throws ContentAccessException
{
return null;
}
@Override
- public List<Project> getProjects( Namespace namespace ) throws ContentAccessException
+ public List<? extends Project> getProjects( Namespace namespace ) throws ContentAccessException
{
return null;
}
@Override
- public List<Version> getVersions( Project project ) throws ContentAccessException
+ public List<? extends Version> getVersions( Project project ) throws ContentAccessException
{
return null;
}
@Override
- public List<Artifact> getArtifacts( ContentItem item ) throws ContentAccessException
+ public List<? extends Artifact> getArtifacts( ContentItem item ) throws ContentAccessException
{
return null;
}
@Override
- public List<Artifact> getArtifactsStartingWith( Namespace namespace ) throws ContentAccessException
+ public List<? extends Artifact> getArtifactsStartingWith( Namespace namespace ) throws ContentAccessException
{
return null;
}
@Override
- public Stream<Artifact> getArtifactStream( ContentItem item ) throws ContentAccessException
+ public Stream<? extends Artifact> getArtifactStream( ContentItem item ) throws ContentAccessException
{
return null;
}
@Override
- public Stream<Artifact> getArtifactStreamStartingWith( Namespace namespace ) throws ContentAccessException
+ public Stream<? extends Artifact> getArtifactStreamStartingWith( Namespace namespace ) throws ContentAccessException
{
return null;
}
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 b19dd5b..5d2520f 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
@@ -122,49 +122,49 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent
}
@Override
- public List<Artifact> getAllArtifacts( ItemSelector selector ) throws ContentAccessException
+ public List<? extends Artifact> getAllArtifacts( ItemSelector selector ) throws ContentAccessException
{
return null;
}
@Override
- public Stream<Artifact> getAllArtifactStream( ItemSelector selector ) throws ContentAccessException
+ public Stream<? extends Artifact> getAllArtifactStream( ItemSelector selector ) throws ContentAccessException
{
return null;
}
@Override
- public List<Project> getProjects( Namespace namespace ) throws ContentAccessException
+ public List<? extends Project> getProjects( Namespace namespace ) throws ContentAccessException
{
return null;
}
@Override
- public List<Version> getVersions( Project project ) throws ContentAccessException
+ public List<? extends Version> getVersions( Project project ) throws ContentAccessException
{
return null;
}
@Override
- public List<Artifact> getArtifacts( ContentItem item ) throws ContentAccessException
+ public List<? extends Artifact> getArtifacts( ContentItem item ) throws ContentAccessException
{
return null;
}
@Override
- public List<Artifact> getArtifactsStartingWith( Namespace namespace ) throws ContentAccessException
+ public List<? extends Artifact> getArtifactsStartingWith( Namespace namespace ) throws ContentAccessException
{
return null;
}
@Override
- public Stream<Artifact> getArtifactStream( ContentItem item ) throws ContentAccessException
+ public Stream<? extends Artifact> getArtifactStream( ContentItem item ) throws ContentAccessException
{
return null;
}
@Override
- public Stream<Artifact> getArtifactStreamStartingWith( Namespace namespace ) throws ContentAccessException
+ public Stream<? extends Artifact> getArtifactStreamStartingWith( Namespace namespace ) throws ContentAccessException
{
return null;
}
diff --git a/archiva-modules/archiva-base/archiva-storage-fs/src/main/java/org/apache/archiva/repository/storage/fs/FilesystemAsset.java b/archiva-modules/archiva-base/archiva-storage-fs/src/main/java/org/apache/archiva/repository/storage/fs/FilesystemAsset.java
index 551729a..bbcf38a 100644
--- a/archiva-modules/archiva-base/archiva-storage-fs/src/main/java/org/apache/archiva/repository/storage/fs/FilesystemAsset.java
+++ b/archiva-modules/archiva-base/archiva-storage-fs/src/main/java/org/apache/archiva/repository/storage/fs/FilesystemAsset.java
@@ -521,4 +521,24 @@ public class FilesystemAsset implements StorageAsset, Comparable {
}
return 0;
}
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+ FilesystemAsset that = (FilesystemAsset) o;
+
+ if ( !assetPath.equals( that.assetPath ) ) return false;
+ return storage.equals( that.storage );
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ int result = assetPath.hashCode( );
+ result = 31 * result + storage.hashCode( );
+ return result;
+ }
}
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 b532d83..5314c18 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
@@ -126,49 +126,49 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent
}
@Override
- public List<Artifact> getAllArtifacts( ItemSelector selector ) throws ContentAccessException
+ public List<? extends Artifact> getAllArtifacts( ItemSelector selector ) throws ContentAccessException
{
return null;
}
@Override
- public Stream<Artifact> getAllArtifactStream( ItemSelector selector ) throws ContentAccessException
+ public Stream<? extends Artifact> getAllArtifactStream( ItemSelector selector ) throws ContentAccessException
{
return null;
}
@Override
- public List<Project> getProjects( Namespace namespace ) throws ContentAccessException
+ public List<? extends Project> getProjects( Namespace namespace ) throws ContentAccessException
{
return null;
}
@Override
- public List<Version> getVersions( Project project ) throws ContentAccessException
+ public List<? extends Version> getVersions( Project project ) throws ContentAccessException
{
return null;
}
@Override
- public List<Artifact> getArtifacts( ContentItem item ) throws ContentAccessException
+ public List<? extends Artifact> getArtifacts( ContentItem item ) throws ContentAccessException
{
return null;
}
@Override
- public List<Artifact> getArtifactsStartingWith( Namespace namespace ) throws ContentAccessException
+ public List<? extends Artifact> getArtifactsStartingWith( Namespace namespace ) throws ContentAccessException
{
return null;
}
@Override
- public Stream<Artifact> getArtifactStream( ContentItem item ) throws ContentAccessException
+ public Stream<? extends Artifact> getArtifactStream( ContentItem item ) throws ContentAccessException
{
return null;
}
@Override
- public Stream<Artifact> getArtifactStreamStartingWith( Namespace namespace ) throws ContentAccessException
+ public Stream<? extends Artifact> getArtifactStreamStartingWith( Namespace namespace ) throws ContentAccessException
{
return null;
}
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 780cf35..c1b2bd7 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
@@ -51,22 +51,29 @@ import org.apache.archiva.repository.content.base.ArchivaProject;
import org.apache.archiva.repository.content.base.ArchivaVersion;
import org.apache.archiva.repository.content.base.builder.ArtifactOptBuilder;
import org.apache.archiva.repository.metadata.RepositoryMetadataException;
+import org.apache.archiva.repository.storage.RepositoryStorage;
import org.apache.archiva.repository.storage.StorageAsset;
+import org.apache.archiva.repository.storage.util.StorageUtil;
import org.apache.commons.collections4.map.ReferenceMap;
import org.apache.commons.lang3.StringUtils;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.IOException;
+import java.net.Socket;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -87,7 +94,7 @@ public class ManagedDefaultRepositoryContent
private ManagedRepository repository;
- FileLockManager lockManager;
+ private FileLockManager lockManager;
@Inject
@Named("repositoryPathTranslator#maven2")
@@ -97,6 +104,15 @@ public class ManagedDefaultRepositoryContent
@Named( "metadataReader#maven" )
MavenMetadataReader metadataReader;
+ public static final String SNAPSHOT = "SNAPSHOT";
+
+ public static final Pattern UNIQUE_SNAPSHOT_PATTERN = Pattern.compile( "^(SNAPSHOT|[0-9]{8}\\.[0-9]{6}-[0-9]+)(.*)" );
+ public static final Pattern CLASSIFIER_PATTERN = Pattern.compile( "^-([^.]+)(\\..*)" );
+
+ public static final Pattern TIMESTAMP_PATTERN = Pattern.compile( "^([0-9]{8})\\.([0-9]{6})$" );
+
+ public static final Pattern GENERIC_SNAPSHOT_PATTERN = Pattern.compile( "^(.*)-" + SNAPSHOT );
+
/**
* We are caching content items in a weak reference map. To avoid always recreating the
* the hierarchical structure.
@@ -255,7 +271,6 @@ public class ManagedDefaultRepositoryContent
/*
- TBD
*/
private String getArtifactFileName(ItemSelector selector, String artifactVersion,
String classifier, String extension) {
@@ -300,6 +315,26 @@ public class ManagedDefaultRepositoryContent
}
}
+ private String getTypeFromClassifierAndExtension(String classifierArg, String extensionArg) {
+ String extension = extensionArg.toLowerCase( ).trim( );
+ String classifier = classifierArg.toLowerCase( ).trim( );
+ if (StringUtils.isEmpty( extension )) {
+ return "";
+ } else if (StringUtils.isEmpty( classifier ) ) {
+ return extension;
+ } else if (classifier.equals("tests") && extension.equals("jar")) {
+ return "test-jar";
+ } else if (classifier.equals("client") && extension.equals( "jar" )) {
+ return "ejb-client";
+ } else if (classifier.equals("source") && extension.equals("jar")) {
+ return "java-source";
+ } else if (classifier.equals("javadoc") && extension.equals( "jar" )) {
+ return "javadoc";
+ } else {
+ return extension;
+ }
+ }
+
private String getArtifactExtension(ItemSelector selector) {
if (selector.hasExtension()) {
return selector.getExtension( );
@@ -339,7 +374,7 @@ public class ManagedDefaultRepositoryContent
}
- public String getArtifactSnapshotVersion(StorageAsset artifactDir, String snapshotVersion) {
+ private String getArtifactSnapshotVersion(StorageAsset artifactDir, String snapshotVersion) {
final StorageAsset metadataFile = artifactDir.resolve( METADATA_FILENAME );
StringBuilder version = new StringBuilder( );
try
@@ -369,16 +404,216 @@ public class ManagedDefaultRepositoryContent
ArtifactOptBuilder builder = org.apache.archiva.repository.content.base.ArchivaArtifact.withAsset( artifactPath )
.withVersion( version )
.withId( selector.getArtifactId( ) )
- .withArtifactVersion( getArtifactVersion( artifactPath, selector ) );
- if (selector.hasClassifier()) {
- builder.withClassifier( selector.getClassifier( ) );
- }
+ .withArtifactVersion( getArtifactVersion( artifactPath, selector ) )
+ .withClassifier( classifier );
if (selector.hasType()) {
builder.withType( selector.getType( ) );
}
return builder.build( );
}
+ private String getNamespaceFromNamespacePath(final StorageAsset namespacePath) {
+ LinkedList<String> names = new LinkedList<>( );
+ StorageAsset current = namespacePath;
+ while (current.hasParent()) {
+ names.addFirst( current.getName() );
+ }
+ return String.join( ".", names );
+ }
+
+ private Namespace getNamespaceFromArtifactPath( final StorageAsset artifactPath) {
+ final StorageAsset namespacePath = artifactPath.getParent( ).getParent( ).getParent( );
+ final String namespace = getNamespaceFromNamespacePath( namespacePath );
+ return namespaceMap.computeIfAbsent( namespace,
+ myNamespace -> ArchivaNamespace.withRepository( this )
+ .withAsset( namespacePath )
+ .withNamespace( namespace )
+ .build( ) );
+ }
+
+ private Project getProjectFromArtifactPath( final StorageAsset artifactPath) {
+ final StorageAsset projectPath = artifactPath.getParent( ).getParent( );
+ return projectMap.computeIfAbsent( projectPath,
+ myProjectPath -> ArchivaProject.withAsset( projectPath )
+ .withNamespace( getNamespaceFromArtifactPath( artifactPath ) )
+ .withId( projectPath.getName( ) ).build( )
+ );
+ }
+
+ private Version getVersionFromArtifactPath( final StorageAsset artifactPath) {
+ final StorageAsset versionPath = artifactPath.getParent( );
+ return versionMap.computeIfAbsent( versionPath,
+ myVersionPath -> ArchivaVersion.withAsset( versionPath )
+ .withProject( getProjectFromArtifactPath( artifactPath ) )
+ .withVersion( versionPath.getName( ) ).build( ) );
+ }
+
+ private Artifact getArtifactFromPath(final StorageAsset artifactPath) {
+ final Version version = getVersionFromArtifactPath( artifactPath );
+ final ArtifactInfo info = getArtifactInfoFromPath( version.getVersion(), artifactPath );
+ return artifactMap.computeIfAbsent( artifactPath, myArtifactPath ->
+ org.apache.archiva.repository.content.base.ArchivaArtifact.withAsset( artifactPath )
+ .withVersion( version )
+ .withId( info.id )
+ .withClassifier( info.classifier )
+ .withRemainder( info.remainder )
+ .withType( info.type )
+ .withArtifactVersion( info.version )
+ .withContentType( info.contentType )
+ .build( )
+ );
+ }
+
+ private ContentItem getItemFromPath(final StorageAsset itemPath) {
+ if (itemPath.isLeaf()) {
+ return getArtifactFromPath( itemPath );
+ } else {
+ if (versionMap.containsKey( itemPath )) {
+ return versionMap.get( itemPath );
+ }
+ if (projectMap.containsKey( itemPath )) {
+ return projectMap.get( itemPath );
+ }
+ String ns = getNamespaceFromNamespacePath( itemPath );
+ if (namespaceMap.containsKey( ns )) {
+ return namespaceMap.get( ns );
+ }
+ // No cached item, so we have to gather more information:
+ // Check for version directory (contains at least a pom or metadata file)
+ if (itemPath.list( ).stream( ).map(a -> a.getName().toLowerCase()).anyMatch( n ->
+ n.endsWith( ".pom" )
+ || n.startsWith( "maven-metadata" )
+ )) {
+ return versionMap.computeIfAbsent( itemPath,
+ myVersionPath -> ArchivaVersion.withAsset( itemPath )
+ .withProject( (Project)getItemFromPath( itemPath.getParent() ) )
+ .withVersion( itemPath.getName() ).build());
+ } else {
+ // We have to dig further and find the next directory with a pom
+ Optional<StorageAsset> foundFile = StorageUtil.newAssetStream( itemPath )
+ .filter( a -> a.getName().toLowerCase().endsWith( ".pom" )
+ || a.getName().toLowerCase().startsWith( "maven-metadata" ) )
+ .findFirst( );
+ if (foundFile.isPresent())
+ {
+ int level = 0;
+ StorageAsset current = foundFile.get( );
+ while (current.hasParent() && !current.equals(itemPath)) {
+ level++;
+ current = current.getParent( );
+ }
+ // Project path if it is one level up from the found file
+ if (level==2) {
+ return projectMap.computeIfAbsent( itemPath,
+ myItemPath -> getProjectFromArtifactPath( foundFile.get( ) ) );
+ } else {
+ // All other paths are treated as namespace
+ return namespaceMap.computeIfAbsent( ns,
+ myNamespace -> ArchivaNamespace.withRepository( this )
+ .withAsset( itemPath )
+ .withNamespace( ns )
+ .build( ) );
+ }
+ } else {
+ // Don't know what to do with it, so we treat it as namespace path
+ return namespaceMap.computeIfAbsent( ns,
+ myNamespace -> ArchivaNamespace.withRepository( this )
+ .withAsset( itemPath )
+ .withNamespace( ns )
+ .build( ) );
+ }
+
+ }
+ }
+ }
+
+ // Simple object to hold artifact information
+ private class ArtifactInfo {
+ private String id;
+ private String version;
+ private String extension;
+ private String remainder;
+ private String type;
+ private String classifier;
+ private String contentType;
+ }
+
+ private ArtifactInfo getArtifactInfoFromPath(String genericVersion, StorageAsset path) {
+ final ArtifactInfo info = new ArtifactInfo( );
+ info.id = path.getParent( ).getParent( ).getName( );
+ final String fileName = path.getName( );
+ if ( genericVersion.endsWith( "-" + SNAPSHOT ) )
+ {
+ String baseVersion = StringUtils.substringBeforeLast( genericVersion, "-" + SNAPSHOT );
+ String prefix = info.id+"-"+baseVersion+"-";
+ if (fileName.startsWith( prefix ))
+ {
+ String versionPostfix = StringUtils.removeStart( fileName, prefix );
+ Matcher matcher = UNIQUE_SNAPSHOT_PATTERN.matcher( versionPostfix );
+ if (matcher.matches()) {
+ info.version = baseVersion + "-" + matcher.group( 1 );
+ String newPrefix = prefix + info.version;
+ if (fileName.startsWith( newPrefix ))
+ {
+ String classPostfix = StringUtils.removeStart( fileName, newPrefix );
+ Matcher cMatch = CLASSIFIER_PATTERN.matcher( classPostfix );
+ if (cMatch.matches()) {
+ info.classifier = cMatch.group( 1 );
+ info.remainder = cMatch.group( 2 );
+ } else {
+ info.classifier = "";
+ info.remainder = classPostfix;
+ }
+ } else {
+ log.error( "Artifact does not match the maven name pattern {}", path );
+ info.classifier = "";
+ info.remainder = StringUtils.substringAfter( fileName, prefix );
+ }
+ } else {
+ log.error( "Artifact does not match the snapshot version pattern {}", path );
+ info.version = "";
+ info.classifier = "";
+ info.remainder = StringUtils.substringAfter( fileName, prefix );
+ }
+ } else {
+ log.error( "Artifact does not match the maven name pattern: {}", path );
+ info.version = "";
+ info.classifier = "";
+ info.remainder = StringUtils.substringAfterLast( fileName, "." );
+ }
+ } else {
+ String prefix = info.id+"-"+genericVersion;
+ if (fileName.startsWith( prefix ))
+ {
+ info.version=genericVersion;
+ String classPostfix = StringUtils.removeStart( fileName, prefix );
+ Matcher cMatch = CLASSIFIER_PATTERN.matcher( classPostfix );
+ if (cMatch.matches()) {
+ info.classifier = cMatch.group( 1 );
+ info.remainder = cMatch.group( 2 );
+ } else {
+ info.classifier = "";
+ info.remainder = classPostfix;
+ }
+ } else {
+ log.error( "Artifact does not match the version pattern {}", path );
+ info.version = "";
+ info.classifier = "";
+ info.remainder = StringUtils.substringAfterLast( fileName, "." );
+ }
+ }
+ info.extension = StringUtils.substringAfterLast( fileName, "." );
+ info.type = getTypeFromClassifierAndExtension( info.classifier, info.extension );
+ try {
+ info.contentType = Files.probeContentType( path.getFilePath( ) );
+ } catch (IOException e) {
+ info.contentType = "";
+ //
+ }
+ return info;
+
+ }
+
@Override
public Artifact getArtifact( final ItemSelector selector ) throws ContentAccessException
{
@@ -402,11 +637,55 @@ public class ManagedDefaultRepositoryContent
return artifactMap.computeIfAbsent( path, artifactPath -> createArtifact( path, selector, classifier, extension ) );
}
+ private StorageAsset getBasePathFromSelector(ItemSelector selector) {
+ StringBuilder path = new StringBuilder( );
+ if (selector.hasNamespace()) {
+ path.append(String.join( "/", getNamespace( selector ).getNamespacePath( ) ));
+ }
+ if (selector.hasProjectId()) {
+ path.append( "/" ).append( selector.getProjectId( ) );
+ }
+ if (selector.hasVersion()) {
+ path.append( "/" ).append( selector.getVersion( ) );
+ }
+ return getStorage( ).getAsset( path.toString( ) );
+ }
+
+ /*
+ * File filter to select certain artifacts using the selector data.
+ */
+ private Predicate<StorageAsset> getFileFilterFromSelector(final ItemSelector selector) {
+ Predicate<StorageAsset> p = a -> a.isLeaf( );
+ if (selector.hasArtifactId()) {
+ final String pattern = selector.getArtifactId( );
+ p = p.and( a -> StringUtils.startsWithIgnoreCase( a.getName( ), pattern ) );
+ }
+ if (selector.hasArtifactVersion()) {
+ final String pattern = selector.getArtifactVersion( );
+ p = p.and( a -> StringUtils.containsIgnoreCase( a.getName( ), pattern ) );
+ }
+ if (selector.hasExtension()) {
+ final String pattern = "."+selector.getExtension( );
+ p = p.and( a -> StringUtils.endsWithIgnoreCase( a.getName( ), pattern ) );
+ } else if (selector.hasType()) {
+ final String pattern = "."+getArtifactExtension( selector );
+ p = p.and( a -> StringUtils.endsWithIgnoreCase( a.getName( ), pattern ) );
+ }
+ if (selector.hasClassifier()) {
+ final String pattern = "-" + selector.getClassifier( ) + ".";
+ p = p.and( a -> StringUtils.containsIgnoreCase( a.getName( ), pattern ) );
+ } else if (selector.hasType()) {
+ final String pattern = "-" + getClassifierFromType( selector.getType( ) ) + ".";
+ p = p.and( a -> StringUtils.containsIgnoreCase( a.getName( ).toLowerCase( ), pattern ) );
+ }
+ return p;
+ }
+
/*
TBD
*/
@Override
- public List<Artifact> getAllArtifacts( ItemSelector selector ) throws ContentAccessException
+ public List<? extends Artifact> getAllArtifacts( ItemSelector selector ) throws ContentAccessException
{
return null;
}
@@ -415,7 +694,7 @@ public class ManagedDefaultRepositoryContent
TBD
*/
@Override
- public Stream<Artifact> getAllArtifactStream( ItemSelector selector ) throws ContentAccessException
+ public Stream<? extends Artifact> getAllArtifactStream( ItemSelector selector ) throws ContentAccessException
{
return null;
}
@@ -424,7 +703,7 @@ public class ManagedDefaultRepositoryContent
TBD
*/
@Override
- public List<Project> getProjects( Namespace namespace )
+ public List<? extends Project> getProjects( Namespace namespace )
{
return null;
}
@@ -433,7 +712,7 @@ public class ManagedDefaultRepositoryContent
TBD
*/
@Override
- public List<Version> getVersions( Project project )
+ public List<? extends Version> getVersions( Project project )
{
return null;
}
@@ -442,7 +721,7 @@ public class ManagedDefaultRepositoryContent
TBD
*/
@Override
- public List<Artifact> getArtifacts( ContentItem item )
+ public List<? extends Artifact> getArtifacts( ContentItem item )
{
return null;
}
@@ -451,7 +730,7 @@ public class ManagedDefaultRepositoryContent
TBD
*/
@Override
- public List<Artifact> getArtifactsStartingWith( Namespace namespace )
+ public List<? extends Artifact> getArtifactsStartingWith( Namespace namespace )
{
return null;
}
@@ -460,7 +739,7 @@ public class ManagedDefaultRepositoryContent
TBD
*/
@Override
- public Stream<Artifact> getArtifactStream( ContentItem item )
+ public Stream<? extends Artifact> getArtifactStream( ContentItem item )
{
return null;
}
@@ -469,7 +748,7 @@ public class ManagedDefaultRepositoryContent
TBD
*/
@Override
- public Stream<Artifact> getArtifactStreamStartingWith( Namespace namespace )
+ public Stream<? extends Artifact> getArtifactStreamStartingWith( Namespace namespace )
{
return null;
}
@@ -922,6 +1201,10 @@ public class ManagedDefaultRepositoryContent
return repository.getAsset( "" ).getFilePath( );
}
+ private RepositoryStorage getStorage() {
+ return repository.getAsset( "" ).getStorage( );
+ }
+
/**
* Convert a path to an artifact reference.
*