From aec61cb5258038d6d61b610ea71101066f44ad8c Mon Sep 17 00:00:00 2001 From: Martin Stockhammer Date: Mon, 9 Mar 2020 21:25:09 +0100 Subject: [PATCH] Updating content interface and improving predicate generator --- .../repository/ManagedRepositoryContent.java | 33 +------ .../repository/content/ItemSelector.java | 64 +++++++++++- .../mock/ManagedRepositoryContentMock.java | 4 +- .../mock/ManagedRepositoryContentMock.java | 4 +- .../mock/ManagedRepositoryContentMock.java | 4 +- .../ManagedDefaultRepositoryContent.java | 98 +++++++++---------- 6 files changed, 121 insertions(+), 86 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 9a25aa6b1..ce819eb12 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 @@ -49,7 +49,8 @@ public interface ManagedRepositoryContent extends RepositoryContent /// ***************** New generation interface ********************** /** - * Removes the specified content item and all content stored under the given item. + * Removes the specified content item and if the item is a container or directory, + * all content stored under the given item. * * @param item the item. * @throws ItemNotFoundException if the item cannot be found @@ -170,7 +171,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 getAllArtifacts( ItemSelector selector) throws ContentAccessException; + List getArtifacts( ItemSelector selector) throws ContentAccessException; /** * Returns the artifacts that match the given selector. It is up to the repository implementation @@ -185,7 +186,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 getAllArtifactStream( ItemSelector selector) throws ContentAccessException; + Stream getArtifactStream( ItemSelector selector) throws ContentAccessException; /** @@ -236,17 +237,6 @@ public interface ManagedRepositoryContent extends RepositoryContent */ 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 - * @param recurse true, if all sub namespaces should be searched too, otherwise false - * @return a list of artifacts or a empty list, if no artifacts are available for the specified namespace - */ - List getArtifacts( Namespace namespace, boolean recurse ) 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. @@ -261,21 +251,6 @@ public interface ManagedRepositoryContent extends RepositoryContent 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 - * @param recurse true, if all sub namespaces should be searched too, otherwise false - * @return a stream of artifacts. The stream is auto closable. You should always make sure, that the stream - * is closed after use. - */ - Stream getArtifactStream( Namespace namespace, boolean recurse ) throws ContentAccessException; - - /** * Returns true, if the selector coordinates point to a existing item in the repository. * diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/content/ItemSelector.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/content/ItemSelector.java index 8a4aeb055..6bff84363 100644 --- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/content/ItemSelector.java +++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/content/ItemSelector.java @@ -29,26 +29,86 @@ import java.util.Map; public interface ItemSelector { - String getProjectId( ); - + /** + * Selects the namespace to search for. You can use the {@link #searchSubNamespaces()} flag + * to decide, if only the given namespace or the namespace and all sub namespaces (if they exist) should be + * queried. If empty, the root namespace is searched. + * @return the namespace to search + */ String getNamespace( ); + /** + * Selects the project id to search for. If empty all projects are searched. + * @return the project id + */ + String getProjectId( ); + + /** + * Selects the version to search for. If empty all versions are searched. + * @return the version + */ String getVersion( ); + /** + * Selects a specific artifact version. This may be different from the version, e.g. + * for SNAPSHOT versions. If empty, the artifact version will be ignored. + * @return the artifact version or empty string + */ String getArtifactVersion( ); + /** + * Returns the artifact id to search for. If empty, all artifacts are returned. + * @return the artifact id or a empty string + */ String getArtifactId( ); + /** + * Returns the type to search for. If empty, the type is ignored. + * @return the type or a empty string. + */ String getType( ); + /** + * Returns the classifier string used for querying, or empty string if no classifier. + * If it returns a '*' than all classifiers should be selected. + * @return the classifier string + */ String getClassifier( ); + /** + * Returns the attribute to search for or null, if the + * attribute key should not be used for search. + * @param key the attribute key + * @return + */ String getAttribute( String key ); + /** + * The extension of the file/asset. + * @return + */ String getExtension( ); + /** + * The map of attributes to search for + * @return + */ Map getAttributes( ); + /** + * Returns true, if not only the given namespace but all sub namespaces + * of the given namespace should be queried too. + */ + boolean searchSubNamespaces(); + + /** + * true, if all files/assets should be returned that match the given selector, + * or false, if only the main assets should be returned. + * Related assets are e.g. hash files or signature files. + * @return true, if all assets should be found otherwise false + */ + boolean findRelatedArtifacts(); + default boolean hasNamespace( ) { return !StringUtils.isEmpty( getNamespace( ) ); 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 d58769bf4..d24710135 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 @@ -127,13 +127,13 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent } @Override - public List getAllArtifacts( ItemSelector selector ) throws ContentAccessException + public List getArtifacts( ItemSelector selector ) throws ContentAccessException { return null; } @Override - public Stream getAllArtifactStream( ItemSelector selector ) throws ContentAccessException + public Stream getArtifactStream( ItemSelector selector ) 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 d0f8b2c44..55d424019 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 @@ -128,13 +128,13 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent } @Override - public List getAllArtifacts( ItemSelector selector ) throws ContentAccessException + public List getArtifacts( ItemSelector selector ) throws ContentAccessException { return null; } @Override - public Stream getAllArtifactStream( ItemSelector selector ) throws ContentAccessException + public Stream getArtifactStream( ItemSelector selector ) throws ContentAccessException { return null; } 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 b1b990860..09c5aab4b 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 @@ -132,13 +132,13 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent } @Override - public List getAllArtifacts( ItemSelector selector ) throws ContentAccessException + public List getArtifacts( ItemSelector selector ) throws ContentAccessException { return null; } @Override - public Stream getAllArtifactStream( ItemSelector selector ) throws ContentAccessException + public Stream getArtifactStream( ItemSelector selector ) throws ContentAccessException { return null; } diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContent.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContent.java index e8f49c019..de7de971c 100644 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContent.java +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContent.java @@ -516,62 +516,60 @@ public class ManagedDefaultRepositoryContent */ private Predicate getFileFilterFromSelector(final ItemSelector selector) { Predicate p = a -> a.isLeaf( ); + StringBuilder fileNamePattern = new StringBuilder("^" ); if (selector.hasArtifactId()) { - final String pattern = selector.getArtifactId( ); - p = p.and( a -> StringUtils.startsWithIgnoreCase( a.getName( ), pattern ) ); + fileNamePattern.append( Pattern.quote(selector.getArtifactId( )) ).append("-"); + } else { + fileNamePattern.append("[A-Za-z0-9_\\-.]+-"); } if (selector.hasArtifactVersion()) { - final String pattern = selector.getArtifactVersion( ); - p = p.and( a -> StringUtils.containsIgnoreCase( a.getName( ), pattern ) ); + fileNamePattern.append( Pattern.quote(selector.getArtifactVersion( )) ); + } else { + fileNamePattern.append( "[A-Za-z0-9_\\-.]+" ); } - if (selector.hasExtension()) { - final String pattern = "."+selector.getExtension( ); - p = p.and( a -> StringUtils.endsWithIgnoreCase( a.getName( ), pattern ) ); - } else if (selector.hasType()) { - final String pattern = "."+ MavenContentHelper.getArtifactExtension( selector ); - p = p.and( a -> StringUtils.endsWithIgnoreCase( a.getName( ), pattern ) ); + String classifier = selector.hasClassifier( ) ? selector.getClassifier( ) : + ( selector.hasType( ) ? MavenContentHelper.getClassifierFromType( selector.getType( ) ) : null ); + if (classifier != null) + { + if ( "*".equals( classifier ) ) + { + fileNamePattern.append( "-[A-Za-z0-9]+\\." ); + } + else + { + fileNamePattern.append("-").append( Pattern.quote( classifier ) ).append( "\\." ); + } + } else { + fileNamePattern.append( "\\." ); } - if (selector.hasClassifier()) { - final String pattern = "-" + selector.getClassifier( ) + "."; - p = p.and( a -> StringUtils.containsIgnoreCase( a.getName( ), pattern ) ); - } else if (selector.hasType()) { - final String pattern = "-" + MavenContentHelper.getClassifierFromType( selector.getType( ) ) + "."; - p = p.and( a -> StringUtils.containsIgnoreCase( a.getName( ).toLowerCase( ), pattern ) ); + String extension = selector.hasExtension( ) ? selector.getExtension( ) : + ( selector.hasType( ) ? MavenContentHelper.getArtifactExtension( selector ) : null ); + if (extension != null) { + fileNamePattern.append( Pattern.quote( extension ) ); + } else { + fileNamePattern.append( ".*" ); } - return p; - } - - /* - TBD - */ - @Override - public List getAllArtifacts( ItemSelector selector ) throws ContentAccessException - { - return null; + final Pattern pattern = Pattern.compile( fileNamePattern.toString() ); + return p.and( a -> pattern.matcher( a.getName( ) ).matches()); } - /* - TBD - */ - @Override - public Stream getAllArtifactStream( ItemSelector selector ) throws ContentAccessException - { - return null; - } - /* - TBD + /** + * Returns all the subdirectories of the given namespace directory as project. */ @Override public List getProjects( Namespace namespace ) { - return null; + return namespace.getAsset( ).list( ).stream( ) + .filter( a -> a.isContainer( ) ) + .map( a -> getProjectFromArtifactPath( a ) ) + .collect( Collectors.toList()); } @Override public List getProjects( ItemSelector selector ) throws ContentAccessException, IllegalArgumentException { - return null; + return getProjects( getNamespace( selector ) ); } /** @@ -621,11 +619,12 @@ public class ManagedDefaultRepositoryContent } } + /* - TBD - */ + TBD + */ @Override - public List getArtifacts( ContentItem item ) + public List getArtifacts( ItemSelector selector ) throws ContentAccessException { return null; } @@ -634,36 +633,37 @@ public class ManagedDefaultRepositoryContent TBD */ @Override - public List getArtifacts( Namespace namespace, boolean recurse ) + public Stream getArtifactStream( ItemSelector selector ) throws ContentAccessException { return null; } /* - TBD - */ + TBD + */ @Override - public Stream getArtifactStream( ContentItem item ) + public List getArtifacts( ContentItem item ) { return null; } + /* TBD */ @Override - public Stream getArtifactStream( Namespace namespace, boolean recurse ) + public Stream getArtifactStream( ContentItem item ) { return null; } - /* - TBD + /** + * Checks, if the asset/file queried by the given selector exists. */ @Override public boolean hasContent( ItemSelector selector ) { - return false; + return getItem( selector ).getAsset( ).exists( ); } /* -- 2.39.5