aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Stockhammer <martin_s@apache.org>2020-05-24 18:18:37 +0200
committerMartin Stockhammer <martin_s@apache.org>2020-05-30 20:00:22 +0200
commitac25c7a86fe77f5b0f005f03d9d28dc1f6f8580e (patch)
treed6f1650edea83a7ed04c1ae40cf8e03d70ff8ed0
parent56de9e590b8d040add03b99df2e221eeedde860e (diff)
downloadarchiva-ac25c7a86fe77f5b0f005f03d9d28dc1f6f8580e.tar.gz
archiva-ac25c7a86fe77f5b0f005f03d9d28dc1f6f8580e.zip
Changing content item API
-rw-r--r--archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/GenericManagedRepositoryContent.java141
-rw-r--r--archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/ItemConversionException.java49
-rw-r--r--archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/ManagedRepositoryContent.java96
-rw-r--r--archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/content/ContentItem.java7
-rw-r--r--archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/content/DataItem.java6
-rw-r--r--archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaArtifact.java6
-rw-r--r--archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaContentItem.java168
-rw-r--r--archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaDataItem.java28
-rw-r--r--archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaNamespace.java5
-rw-r--r--archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaProject.java15
-rw-r--r--archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaVersion.java15
-rw-r--r--archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/BaseContentItem.java151
-rw-r--r--archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ContentItemBuilder.java103
-rw-r--r--archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/builder/ArchivaContentItemOptBuilder.java38
-rw-r--r--archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/builder/DataItemOptBuilder.java2
-rw-r--r--archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java24
-rw-r--r--archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/mock/ManagedRepositoryContentMock.java24
-rw-r--r--archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java37
-rw-r--r--archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContent.java1215
-rw-r--r--archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContentTest.java138
-rw-r--r--archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java30
21 files changed, 1584 insertions, 714 deletions
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/GenericManagedRepositoryContent.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/GenericManagedRepositoryContent.java
new file mode 100644
index 000000000..7242f5da9
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/GenericManagedRepositoryContent.java
@@ -0,0 +1,141 @@
+package org.apache.archiva.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.ItemNotFoundException;
+import org.apache.archiva.repository.content.ItemSelector;
+import org.apache.archiva.repository.storage.StorageAsset;
+
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface GenericManagedRepositoryContent
+{
+ /**
+ * Delete all items that match the given selector. The type and number of deleted items
+ * depend on the specific selector:
+ * <ul>
+ * <li>namespace: the complete namespace is deleted (recursively if the recurse flag is set)</li>
+ * <li>project: the complete project and all contained versions are deleted</li>
+ * <li>version: the version inside the project is deleted (project is required)</li>
+ * <li>artifactId: all artifacts that match the id (project and version are required)</li>
+ * <li>artifactVersion: all artifacts that match the version (project and version are required)</li>
+ * <li></li>
+ * </ul>
+ *
+ * @param selector the item selector that selects the artifacts to delete
+ * @param consumer a consumer of the items that will be called after deletion
+ * @returns the list of items that are deleted
+ * @throws ContentAccessException if the deletion was not possible or only partly successful, because the access
+ * to the artifacts failed
+ * @throws IllegalArgumentException if the selector does not specify valid artifacts to delete
+ */
+ void deleteAllItems( ItemSelector selector, Consumer<ItemDeleteStatus> consumer ) throws ContentAccessException, IllegalArgumentException;
+
+ /**
+ * 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
+ * @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 a item for the given selector. The type of the returned item depends on the
+ * selector.
+ *
+ * @param selector the item selector
+ * @return the content item that matches the given selector
+ * @throws ContentAccessException if an error occured while accessing the backend
+ * @throws IllegalArgumentException if the selector does not select a valid content item
+ */
+ ContentItem getItem( ItemSelector selector ) throws ContentAccessException, IllegalArgumentException;
+
+ /**
+ * Returns a stream of items that match the given selector. It may return a stream of mixed types,
+ * like namespaces, projects, versions and artifacts. It will not select a specific type.
+ * The selector can specify the '*' pattern for all fields.
+ * The returned elements will be provided by depth first.
+ *
+ * @param selector the item selector that specifies the items
+ * @return the stream of content items
+ * @throws ContentAccessException if the access to the underlying storage failed
+ * @throws IllegalArgumentException if a illegal coordinate combination was provided
+ */
+ Stream<? extends ContentItem> newItemStream( ItemSelector selector, boolean parallel ) throws ContentAccessException, IllegalArgumentException;
+
+ /**
+ * Returns the item that matches the given path. The item at the path must not exist.
+ *
+ * @param path the path string that points to the item
+ * @return the content item if the path is a valid item path
+ * @throws LayoutException if the path is not valid for the repository layout
+ */
+ ContentItem toItem( String path ) throws LayoutException;
+
+ /**
+ * Returns the item that matches the given asset path. The asset must not exist.
+ *
+ * @param assetPath the path to the artifact or directory
+ * @return the item, if it is a valid path for the repository layout
+ * @throws LayoutException if the path is not valid for the repository
+ */
+ ContentItem toItem( StorageAsset assetPath ) throws LayoutException;
+
+ /**
+ * 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 );
+
+ /**
+ * Returns the parent of the item.
+ * @param item the current item
+ * @return the parent item, or <code>null</code> if no such item exists
+ */
+ ContentItem getParent(ContentItem item);
+
+ /**
+ * Returns the list of children items.
+ * @param item the current item
+ * @return the list of children, or a empty list, if no children exist
+ */
+ List<? extends ContentItem> getChildren( ContentItem item);
+
+ /**
+ * Tries to apply the given characteristic to the content item. If the layout does not allow this,
+ * it will throw a <code>LayoutException</code>.
+ *
+ * @param clazz the characteristic class to apply
+ * @param item the content item
+ * @param <T> The characteristic
+ * @return the applied characteristic
+ */
+ <T extends ContentItem> T applyCharacteristic(Class<T> clazz, ContentItem item) throws LayoutException;
+}
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/ItemConversionException.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/ItemConversionException.java
new file mode 100644
index 000000000..2290111f2
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/ItemConversionException.java
@@ -0,0 +1,49 @@
+package org.apache.archiva.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class ItemConversionException extends RuntimeException
+{
+ public ItemConversionException( )
+ {
+ }
+
+ public ItemConversionException( String message )
+ {
+ super( message );
+ }
+
+ public ItemConversionException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public ItemConversionException( Throwable cause )
+ {
+ super( cause );
+ }
+
+ public ItemConversionException( String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace )
+ {
+ super( message, cause, enableSuppression, writableStackTrace );
+ }
+}
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 a093c8a6d..9b2b318b9 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
@@ -45,54 +45,11 @@ import java.util.stream.Stream;
*
* This interface
*/
-public interface ManagedRepositoryContent extends RepositoryContent
+public interface ManagedRepositoryContent extends RepositoryContent, GenericManagedRepositoryContent
{
/// ***************** New generation interface **********************
- /**
- * Delete all items that match the given selector. The type and number of deleted items
- * depend on the specific selector:
- * <ul>
- * <li>namespace: the complete namespace is deleted (recursively if the recurse flag is set)</li>
- * <li>project: the complete project and all contained versions are deleted</li>
- * <li>version: the version inside the project is deleted (project is required)</li>
- * <li>artifactId: all artifacts that match the id (project and version are required)</li>
- * <li>artifactVersion: all artifacts that match the version (project and version are required)</li>
- * <li></li>
- * </ul>
- *
- * @param selector the item selector that selects the artifacts to delete
- * @param consumer a consumer of the items that will be called after deletion
- * @returns the list of items that are deleted
- * @throws ContentAccessException if the deletion was not possible or only partly successful, because the access
- * to the artifacts failed
- * @throws IllegalArgumentException if the selector does not specify valid artifacts to delete
- */
- void deleteAllItems( ItemSelector selector, Consumer<ItemDeleteStatus> consumer) throws ContentAccessException, IllegalArgumentException;
-
- /**
- * 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
- * @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 a item for the given selector. The type of the returned item depends on the
- * selector.
- *
- * @param selector the item selector
- * @return the content item that matches the given selector
- * @throws ContentAccessException if an error occured while accessing the backend
- * @throws IllegalArgumentException if the selector does not select a valid content item
- */
- ContentItem getItem(ItemSelector selector) throws ContentAccessException, IllegalArgumentException;
/**
* Returns the namespace for the given selected coordinates. The selector must specify a namespace. All other
@@ -211,19 +168,6 @@ public interface ManagedRepositoryContent extends RepositoryContent
*/
Stream<? extends Artifact> newArtifactStream( ItemSelector selector) throws ContentAccessException;
- /**
- * Returns a stream of items that match the given selector. It may return a stream of mixed types,
- * like namespaces, projects, versions and artifacts. It will not select a specific type.
- * The selector can specify the '*' pattern for all fields.
- * The returned elements will be provided by depth first.
- *
- * @param selector the item selector that specifies the items
- * @return the stream of content items
- * @throws ContentAccessException if the access to the underlying storage failed
- * @throws IllegalArgumentException if a illegal coordinate combination was provided
- */
- Stream<? extends ContentItem> newItemStream(ItemSelector selector, boolean parallel) throws ContentAccessException, IllegalArgumentException;
-
/**
* Return the projects that are part of the given namespace.
@@ -264,6 +208,16 @@ public interface ManagedRepositoryContent extends RepositoryContent
*/
List<? extends Version> getVersions( ItemSelector selector ) throws ContentAccessException, IllegalArgumentException;
+ /**
+ * Returns all found artifact versions that can be found for the given selector. The selector must specify at least
+ * a project.
+ *
+ * @param selector the item selector that must specify at least a project
+ * @return the list of artifact versions
+ * @throws ContentAccessException if the access to the underlying storage failed
+ * @throws IllegalArgumentException if the selector does not have project information
+ */
+ List<String> getArtifactVersions( ItemSelector selector ) throws ContentAccessException, IllegalArgumentException;
/**
* Return all the artifacts of a given content item (namespace, project, version)
@@ -289,14 +243,6 @@ public interface ManagedRepositoryContent extends RepositoryContent
/**
- * 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
@@ -306,26 +252,6 @@ public interface ManagedRepositoryContent extends RepositoryContent
void addArtifact( Path sourceFile, Artifact destination ) throws IllegalArgumentException, ContentAccessException;
- /**
- * Returns the item that matches the given path. The item at the path must not exist.
- *
- * @param path the path string that points to the item
- * @return the content item if the path is a valid item path
- * @throws LayoutException if the path is not valid for the repository layout
- */
- ContentItem toItem(String path) throws LayoutException;
-
-
- /**
- * Returns the item that matches the given asset path. The asset must not exist.
- *
- * @param assetPath the path to the artifact or directory
- * @return the item, if it is a valid path for the repository layout
- * @throws LayoutException if the path is not valid for the repository
- */
- ContentItem toItem(StorageAsset assetPath) throws LayoutException;
-
-
/// ***************** End of new generation interface **********************
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/content/ContentItem.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/content/ContentItem.java
index 8efdd8461..68aca2d8b 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/content/ContentItem.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/content/ContentItem.java
@@ -19,6 +19,7 @@ package org.apache.archiva.repository.content;
* under the License.
*/
+import org.apache.archiva.repository.ItemConversionException;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.UnsupportedConversionException;
import org.apache.archiva.repository.storage.StorageAsset;
@@ -34,7 +35,7 @@ public interface ContentItem
* @param <T> the class or interface
* @return the specific project implementation
*/
- <T extends Project> T adapt( Class<T> clazz ) throws UnsupportedConversionException;
+ <T extends ContentItem> T adapt( Class<T> clazz ) throws ItemConversionException;
/**
* Returns <code>true</code>, if this project supports the given adaptor class.
@@ -43,7 +44,9 @@ public interface ContentItem
* @param <T> the type
* @return <code>true/code>, if the implementation is supported, otherwise false
*/
- <T extends Project> boolean supports( Class<T> clazz );
+ <T extends ContentItem> boolean hasCharacteristic( Class<T> clazz );
+
+ <T extends ContentItem> void setCharacteristic( Class<T> clazz, T item );
/**
* Additional attributes
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/content/DataItem.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/content/DataItem.java
index 32dc00ee5..5d315b54a 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/content/DataItem.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/content/DataItem.java
@@ -29,12 +29,6 @@ public interface DataItem extends ContentItem
{
/**
- * Returns the parent of the data item
- * @return the parent item, which is either a Version, Project or Namespace
- */
- ContentItem getParent( );
-
- /**
* Returns the identifier of the data item.
* @return the identifier string
*/
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaArtifact.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaArtifact.java
index 26b0449ba..b65fa7400 100644
--- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaArtifact.java
+++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaArtifact.java
@@ -22,8 +22,6 @@ package org.apache.archiva.repository.content.base;
import org.apache.archiva.repository.content.Artifact;
import org.apache.archiva.repository.content.ArtifactType;
import org.apache.archiva.repository.content.BaseArtifactTypes;
-import org.apache.archiva.repository.content.ContentItem;
-import org.apache.archiva.repository.content.DataItem;
import org.apache.archiva.repository.content.Version;
import org.apache.archiva.repository.content.base.builder.ArtifactOptBuilder;
import org.apache.archiva.repository.content.base.builder.ArtifactVersionBuilder;
@@ -52,7 +50,7 @@ import org.apache.commons.lang3.StringUtils;
*
* @author Martin Stockhammer <martin_s@apache.org>
*/
-public class ArchivaArtifact extends ArchivaContentItem implements Artifact
+public class ArchivaArtifact extends BaseContentItem implements Artifact
{
private String id;
private String artifactVersion;
@@ -135,8 +133,6 @@ public class ArchivaArtifact extends ArchivaContentItem implements Artifact
{
if ( this == o ) return true;
if ( o == null || getClass( ) != o.getClass( ) ) return false;
- if ( !super.equals( o ) ) return false;
-
ArchivaArtifact that = (ArchivaArtifact) o;
if ( !id.equals( that.id ) ) return false;
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaContentItem.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaContentItem.java
index 7e15d61be..acba93b4f 100644
--- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaContentItem.java
+++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaContentItem.java
@@ -21,105 +21,39 @@ package org.apache.archiva.repository.content.base;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.Namespace;
import org.apache.archiva.repository.content.Project;
-import org.apache.archiva.repository.content.base.builder.OptBuilder;
+import org.apache.archiva.repository.content.Version;
+import org.apache.archiva.repository.content.base.builder.ArchivaContentItemOptBuilder;
import org.apache.archiva.repository.content.base.builder.WithAssetBuilder;
-import org.apache.archiva.repository.content.base.builder.WithRepositoryBuilder;
import org.apache.archiva.repository.storage.StorageAsset;
-import org.apache.commons.lang3.StringUtils;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
/**
* Abstract implementation of ContentItem interface.
* <p>
* The attribute map is created, when the first values are put to the map.
*/
-public abstract class ArchivaContentItem implements ContentItem
+public class ArchivaContentItem extends BaseContentItem implements ContentItem
{
- private Map<String, String> attributes;
- private ManagedRepositoryContent repository;
- private StorageAsset asset;
-
- @Override
- public <T extends Project> T adapt( Class<T> clazz )
- {
- return (T) this;
- }
-
- @Override
- public <T extends Project> boolean supports( Class<T> clazz )
- {
- return clazz != null && clazz.isAssignableFrom( this.getClass( ) );
- }
-
-
- /**
- * Does lazy initialization of the attributes map.
- * Returns a unmodifiable map.
- *
- * @return unmodifiable map of attributes
- */
- @Override
- public Map<String, String> getAttributes( )
- {
- if ( this.attributes == null )
- {
- return Collections.emptyMap( );
- }
- else
- {
- return Collections.unmodifiableMap( this.attributes );
- }
- }
/**
- * Adds a attribute value. The key must not be <code>null</code>.
+ * Creates the builder for creating new archiva project instances.
+ * You have to set all required attributes before you can call the build() method.
*
- * @param key the attribute key
- * @param value the attribute value
- * @throws IllegalArgumentException if the key is <code>null</code> or empty
+ * @param storageAsset the asset
+ * @return a builder instance
*/
- public void putAttribute( String key, String value ) throws IllegalArgumentException
- {
- if ( this.attributes == null )
- {
- this.attributes = new HashMap<>( );
- }
- if ( StringUtils.isEmpty( key ) )
- {
- throw new IllegalArgumentException( "Key value must not be empty or null" );
- }
- this.attributes.put( key, value );
- }
-
- @Override
- public String getAttribute( String key )
+ public static ArchivaContentItemOptBuilder withAsset( StorageAsset storageAsset )
{
- if ( this.attributes == null )
- {
- return null;
- }
- else
- {
- return this.attributes.get( key );
- }
+ return new ArchivaContentItemBuilder().withAsset( storageAsset );
}
- @Override
- public ManagedRepositoryContent getRepository( )
+ public static WithAssetBuilder<ArchivaContentItemOptBuilder> withRepository( ManagedRepositoryContent repository )
{
- return repository;
+ return new ArchivaContentItemBuilder().withRepository( repository );
}
- @Override
- public StorageAsset getAsset( )
- {
- return asset;
- }
@Override
public boolean equals( Object o )
@@ -150,86 +84,56 @@ public abstract class ArchivaContentItem implements ContentItem
*/
- /**
- * Builder for content item. Must be extended by subclasses.
- * The builder uses chained interfaces for building the required attributes. That means you have to set
- * some certain attributes, before you can build the content item instance via the {@link #build()} method.
- * <p>
- * Subclasses should extend from this class and provide the interface/class for the destination item,
- * a interface for the optional attributes and a interface that is returned after the last required attribute is
- * set.
- * <p>
- * The interface for optional attributes should inherit from {@link OptBuilder}
- *
- * @param <I> the item class that should be built
- * @param <O> the class/interface for the optional attributes
- * @param <N> the class/interface for the next (required) attribute after the base attributes are set
- */
- protected abstract static class ContentItemBuilder<I extends ArchivaContentItem, O extends OptBuilder<I, O>, N>
- implements WithRepositoryBuilder, WithAssetBuilder<N>,
- OptBuilder<I, O>
+ public static final class ArchivaContentItemBuilder extends ContentItemBuilder<ArchivaContentItem, ArchivaContentItemOptBuilder, ArchivaContentItemOptBuilder>
+ implements ArchivaContentItemOptBuilder
{
- protected I item;
-
- protected ContentItemBuilder( I item )
+ private ArchivaContentItemBuilder( )
{
- this.item = item;
+ super( new ArchivaContentItem() );
}
- protected abstract O getOptBuilder( );
-
- protected abstract N getNextBuilder( );
+ @Override
+ public ArchivaContentItemOptBuilder getOptBuilder( )
+ {
+ return this;
+ }
@Override
- public WithAssetBuilder<N> withRepository( ManagedRepositoryContent repository )
+ public ArchivaContentItemOptBuilder getNextBuilder( )
{
- if ( repository == null )
- {
- throw new IllegalArgumentException( "Repository may not be null" );
- }
- ( (ArchivaContentItem) item ).repository = repository;
return this;
}
+
@Override
- public N withAsset( StorageAsset asset )
+ public ArchivaContentItemOptBuilder withNamespace( Namespace namespace )
{
- if ( asset == null )
- {
- throw new IllegalArgumentException( "Asset may not be null" );
- }
- ( (ArchivaContentItem) item ).asset = asset;
- return getNextBuilder( );
+ item.setCharacteristic( Namespace.class, namespace );
+ return this;
}
@Override
- public O withAttribute( String key, String value )
+ public ArchivaContentItemOptBuilder withProject( Project project )
{
- if ( StringUtils.isEmpty( key ) )
- {
- throw new IllegalArgumentException( "Attribute key may not be null" );
- }
- item.putAttribute( key, value );
- return getOptBuilder( );
+ item.setCharacteristic( Project.class, project );
+ return this;
}
- protected void setRepository( ManagedRepositoryContent repository )
+ @Override
+ public ArchivaContentItemOptBuilder withVersion( Version version )
{
- ( (ArchivaContentItem) item ).repository = repository;
+ item.setCharacteristic( Version.class, version );
+ return this;
}
@Override
- public I build( )
+ public ArchivaContentItem build( )
{
+ super.build( );
return item;
}
-
}
- @Override
- public boolean exists( )
- {
- return asset.exists( );
- }
+
}
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaDataItem.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaDataItem.java
index cb13e1832..c825bb316 100644
--- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaDataItem.java
+++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaDataItem.java
@@ -19,9 +19,7 @@ package org.apache.archiva.repository.content.base;
* under the License.
*/
-import org.apache.archiva.repository.content.BaseArtifactTypes;
import org.apache.archiva.repository.content.BaseDataItemTypes;
-import org.apache.archiva.repository.content.ContentItem;
import org.apache.archiva.repository.content.DataItem;
import org.apache.archiva.repository.content.DataItemType;
import org.apache.archiva.repository.content.base.builder.DataItemOptBuilder;
@@ -49,10 +47,9 @@ import org.apache.commons.lang3.StringUtils;
*
* @author Martin Stockhammer <martin_s@apache.org>
*/
-public class ArchivaDataItem extends ArchivaContentItem implements DataItem
+public class ArchivaDataItem extends BaseContentItem implements DataItem
{
private String id;
- private ContentItem parent;
private String contentType;
private DataItemType dataItemType;
@@ -68,12 +65,6 @@ public class ArchivaDataItem extends ArchivaContentItem implements DataItem
}
@Override
- public ContentItem getParent( )
- {
- return parent;
- }
-
- @Override
public String getContentType( )
{
return contentType;
@@ -109,7 +100,6 @@ public class ArchivaDataItem extends ArchivaContentItem implements DataItem
ArchivaDataItem that = (ArchivaDataItem) o;
if ( !id.equals( that.id ) ) return false;
- if ( !parent.equals( that.parent ) ) return false;
return dataItemType.equals(that.dataItemType );
}
@@ -118,7 +108,6 @@ public class ArchivaDataItem extends ArchivaContentItem implements DataItem
{
int result = super.hashCode( );
result = 31 * result + id.hashCode( );
- result = 31 * result + parent.hashCode( );
result = 31 * result + dataItemType.hashCode( );
return result;
}
@@ -126,9 +115,8 @@ public class ArchivaDataItem extends ArchivaContentItem implements DataItem
@Override
public String toString( )
{
- final StringBuilder sb = new StringBuilder( "ArchivaArtifact{" );
+ final StringBuilder sb = new StringBuilder( "ArchivaDataItem{" );
sb.append( "id='" ).append( id ).append( '\'' );
- sb.append( ", parent=" ).append( parent );
sb.append( ", contentType='" ).append( contentType ).append( '\'' );
sb.append( ", artifactType=" ).append( dataItemType );
sb.append( '}' );
@@ -168,18 +156,6 @@ public class ArchivaDataItem extends ArchivaContentItem implements DataItem
}
@Override
- public DataItemOptBuilder withParent( ContentItem parent )
- {
- if ( parent == null )
- {
- throw new IllegalArgumentException( "version may not be null" );
- }
- item.parent = parent;
- super.setRepository( parent.getRepository( ) );
- return this;
- }
-
- @Override
public DataItemOptBuilder withId( String id )
{
if ( StringUtils.isEmpty( id ) )
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaNamespace.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaNamespace.java
index b85f25a60..9982ea0de 100644
--- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaNamespace.java
+++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaNamespace.java
@@ -38,7 +38,7 @@ import java.util.regex.PatternSyntaxException;
* @author Martin Stockhammer <martin_s@apache.org>
* @since 3.0
*/
-public class ArchivaNamespace extends ArchivaContentItem implements Namespace
+public class ArchivaNamespace extends BaseContentItem implements Namespace
{
private String namespace;
private List<String> namespacePath;
@@ -72,10 +72,9 @@ public class ArchivaNamespace extends ArchivaContentItem implements Namespace
{
if ( this == o ) return true;
if ( o == null || getClass( ) != o.getClass( ) ) return false;
- if ( !super.equals( o ) ) return false;
-
ArchivaNamespace that = (ArchivaNamespace) o;
+ if (!repository.equals( that.repository )) return false;
return namespace.equals( that.namespace );
}
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaProject.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaProject.java
index ac72f6217..9fb9a0cf6 100644
--- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaProject.java
+++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaProject.java
@@ -19,11 +19,15 @@ package org.apache.archiva.repository.content.base;
* under the License.
*/
+import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.content.Namespace;
import org.apache.archiva.repository.content.Project;
import org.apache.archiva.repository.content.base.builder.ProjectOptBuilder;
import org.apache.archiva.repository.content.base.builder.ProjectWithIdBuilder;
+import org.apache.archiva.repository.content.base.builder.WithAssetBuilder;
+import org.apache.archiva.repository.content.base.builder.WithNamespaceBuilder;
import org.apache.archiva.repository.content.base.builder.WithNamespaceObjectBuilder;
+import org.apache.archiva.repository.content.base.builder.WithProjectBuilder;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.commons.lang3.StringUtils;
@@ -38,7 +42,7 @@ import org.apache.commons.lang3.StringUtils;
* @author Martin Stockhammer <martin_s@apache.org>
* @since 3.0
*/
-public class ArchivaProject extends ArchivaContentItem implements Project
+public class ArchivaProject extends BaseContentItem implements Project
{
private Namespace namespace;
private String id;
@@ -62,6 +66,11 @@ public class ArchivaProject extends ArchivaContentItem implements Project
return new Builder( ).withAsset( storageAsset );
}
+ public static WithAssetBuilder<WithNamespaceObjectBuilder> withRepository( ManagedRepositoryContent repository )
+ {
+ return new ArchivaProject.Builder( ).withRepository( repository );
+ }
+
@Override
public Namespace getNamespace( )
{
@@ -80,10 +89,10 @@ public class ArchivaProject extends ArchivaContentItem implements Project
{
if ( this == o ) return true;
if ( o == null || getClass( ) != o.getClass( ) ) return false;
- if ( !super.equals( o ) ) return false;
ArchivaProject that = (ArchivaProject) o;
+ if (!repository.equals( that.repository )) return false;
if ( !namespace.equals( that.namespace ) ) return false;
return id.equals( that.id );
}
@@ -100,7 +109,7 @@ public class ArchivaProject extends ArchivaContentItem implements Project
@Override
public String toString( )
{
- return id + ", namespace="+namespace.toString();
+ return "ArchivaProject{ "+id + ", namespace="+namespace.toString()+"}";
}
/*
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaVersion.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaVersion.java
index e10d3b1c5..c553c3bfc 100644
--- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaVersion.java
+++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ArchivaVersion.java
@@ -19,9 +19,12 @@ package org.apache.archiva.repository.content.base;
* under the License.
*/
+import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.content.Project;
import org.apache.archiva.repository.content.Version;
import org.apache.archiva.repository.content.base.builder.VersionOptBuilder;
+import org.apache.archiva.repository.content.base.builder.WithAssetBuilder;
+import org.apache.archiva.repository.content.base.builder.WithNamespaceBuilder;
import org.apache.archiva.repository.content.base.builder.WithProjectBuilder;
import org.apache.archiva.repository.content.base.builder.WithVersionBuilder;
import org.apache.archiva.repository.storage.StorageAsset;
@@ -41,7 +44,7 @@ import java.util.regex.PatternSyntaxException;
* <p>
* Two instances are equal, if the project and the version match in addition to the base attributes repository and asset.
*/
-public class ArchivaVersion extends ArchivaContentItem implements Version
+public class ArchivaVersion extends BaseContentItem implements Version
{
private String version;
@@ -66,6 +69,11 @@ public class ArchivaVersion extends ArchivaContentItem implements Version
return new Builder( ).withAsset( storageAsset );
}
+ public static WithAssetBuilder<WithProjectBuilder> withRepository( ManagedRepositoryContent repository )
+ {
+ return new ArchivaVersion.Builder( ).withRepository( repository );
+ }
+
@Override
public List<String> getVersionSegments( )
{
@@ -90,10 +98,9 @@ public class ArchivaVersion extends ArchivaContentItem implements Version
{
if ( this == o ) return true;
if ( o == null || getClass( ) != o.getClass( ) ) return false;
- if ( !super.equals( o ) ) return false;
ArchivaVersion that = (ArchivaVersion) o;
-
+ if (!repository.equals( that.repository )) return false;
if ( !version.equals( that.version ) ) return false;
return project.equals( that.project );
}
@@ -110,7 +117,7 @@ public class ArchivaVersion extends ArchivaContentItem implements Version
@Override
public String toString( )
{
- return version+", project="+project.toString();
+ return "ArchivaVersion{ "+version+", project="+project.toString()+"}";
}
private static final class Builder extends ContentItemBuilder<ArchivaVersion, VersionOptBuilder, WithProjectBuilder>
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/BaseContentItem.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/BaseContentItem.java
new file mode 100644
index 000000000..3866131ec
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/BaseContentItem.java
@@ -0,0 +1,151 @@
+package org.apache.archiva.repository.content.base;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.repository.ItemConversionException;
+import org.apache.archiva.repository.LayoutException;
+import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.storage.StorageAsset;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public abstract class BaseContentItem implements ContentItem
+{
+ protected ManagedRepositoryContent repository;
+ protected StorageAsset asset;
+ private Map<String, String> attributes;
+ private Map<Class<?>, ContentItem> characteristics = new HashMap<>( );
+ private Set<Class<?>> failedConversions = new HashSet<>( );
+
+ @Override
+ public <T extends ContentItem> T adapt( Class<T> clazz ) throws ItemConversionException
+ {
+ if (characteristics.containsKey( clazz )) {
+ return (T) characteristics.get( clazz );
+ } else {
+ for ( Map.Entry<Class<?>, ? extends ContentItem> cEntry : characteristics.entrySet()) {
+ if (clazz.isAssignableFrom( cEntry.getKey() )) {
+ return (T) cEntry.getValue( );
+ }
+ }
+ try {
+ return repository.applyCharacteristic( clazz, this );
+ } catch ( LayoutException e ) {
+ throw new ItemConversionException( "Could not convert item to " + clazz, e );
+ }
+ }
+ }
+
+ @Override
+ public <T extends ContentItem> boolean hasCharacteristic( Class<T> clazz )
+ {
+ if (clazz == null) {
+ return false;
+ }
+ if ( characteristics.containsKey( clazz )
+ || characteristics.keySet( ).stream( ).anyMatch( cClass -> clazz.isAssignableFrom( cClass ) ) ) {
+ return true;
+ };
+ return false;
+ }
+
+ /**
+ * Does lazy initialization of the attributes map.
+ * Returns a unmodifiable map.
+ *
+ * @return unmodifiable map of attributes
+ */
+ @Override
+ public Map<String, String> getAttributes( )
+ {
+ if ( this.attributes == null )
+ {
+ return Collections.emptyMap( );
+ }
+ else
+ {
+ return Collections.unmodifiableMap( this.attributes );
+ }
+ }
+
+ /**
+ * Adds a attribute value. The key must not be <code>null</code>.
+ *
+ * @param key the attribute key
+ * @param value the attribute value
+ * @throws IllegalArgumentException if the key is <code>null</code> or empty
+ */
+ public void putAttribute( String key, String value ) throws IllegalArgumentException
+ {
+ if ( this.attributes == null )
+ {
+ this.attributes = new HashMap<>( );
+ }
+ if ( StringUtils.isEmpty( key ) )
+ {
+ throw new IllegalArgumentException( "Key value must not be empty or null" );
+ }
+ this.attributes.put( key, value );
+ }
+
+ @Override
+ public String getAttribute( String key )
+ {
+ if ( this.attributes == null )
+ {
+ return null;
+ }
+ else
+ {
+ return this.attributes.get( key );
+ }
+ }
+
+ @Override
+ public ManagedRepositoryContent getRepository( )
+ {
+ return repository;
+ }
+
+ @Override
+ public StorageAsset getAsset( )
+ {
+ return asset;
+ }
+
+ @Override
+ public boolean exists( )
+ {
+ return asset.exists( );
+ }
+
+ public <T extends ContentItem> void setCharacteristic( Class<T> clazz, T item )
+ {
+ this.characteristics.put( clazz, item );
+ }
+}
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ContentItemBuilder.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ContentItemBuilder.java
new file mode 100644
index 000000000..dd3a53db7
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/ContentItemBuilder.java
@@ -0,0 +1,103 @@
+package org.apache.archiva.repository.content.base;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.content.base.builder.OptBuilder;
+import org.apache.archiva.repository.content.base.builder.WithAssetBuilder;
+import org.apache.archiva.repository.content.base.builder.WithRepositoryBuilder;
+import org.apache.archiva.repository.storage.StorageAsset;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Builder for content item. Must be extended by subclasses.
+ * The builder uses chained interfaces for building the required attributes. That means you have to set
+ * some certain attributes, before you can build the content item instance via the {@link #build()} method.
+ * <p>
+ * Subclasses should extend from this class and provide the interface/class for the destination item,
+ * a interface for the optional attributes and a interface that is returned after the last required attribute is
+ * set.
+ * <p>
+ * The interface for optional attributes should inherit from {@link OptBuilder}
+ *
+ * @param <I> the item class that should be built
+ * @param <O> the class/interface for the optional attributes
+ * @param <N> the class/interface for the next (required) attribute after the base attributes are set
+ */
+abstract class ContentItemBuilder<I extends BaseContentItem, O extends OptBuilder<I, O>, N>
+ implements WithRepositoryBuilder, WithAssetBuilder<N>,
+ OptBuilder<I, O>
+{
+
+ protected I item;
+
+ protected ContentItemBuilder( I item )
+ {
+ this.item = item;
+ }
+
+ protected abstract O getOptBuilder( );
+
+ protected abstract N getNextBuilder( );
+
+ @Override
+ public WithAssetBuilder<N> withRepository( ManagedRepositoryContent repository )
+ {
+ if ( repository == null )
+ {
+ throw new IllegalArgumentException( "Repository may not be null" );
+ }
+ ( (BaseContentItem) item ).repository = repository;
+ return this;
+ }
+
+ @Override
+ public N withAsset( StorageAsset asset )
+ {
+ if ( asset == null )
+ {
+ throw new IllegalArgumentException( "Asset may not be null" );
+ }
+ ( (BaseContentItem) item ).asset = asset;
+ return getNextBuilder( );
+ }
+
+ @Override
+ public O withAttribute( String key, String value )
+ {
+ if ( StringUtils.isEmpty( key ) )
+ {
+ throw new IllegalArgumentException( "Attribute key may not be null" );
+ }
+ item.putAttribute( key, value );
+ return getOptBuilder( );
+ }
+
+ protected void setRepository( ManagedRepositoryContent repository )
+ {
+ item.repository = repository;
+ }
+
+ @Override
+ public I build( )
+ {
+ return item;
+ }
+
+}
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/builder/ArchivaContentItemOptBuilder.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/builder/ArchivaContentItemOptBuilder.java
new file mode 100644
index 000000000..36ca84375
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/builder/ArchivaContentItemOptBuilder.java
@@ -0,0 +1,38 @@
+package org.apache.archiva.repository.content.base.builder;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.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.ArchivaContentItem;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface ArchivaContentItemOptBuilder extends OptBuilder<ArchivaContentItem, ArchivaContentItemOptBuilder>
+{
+ ArchivaContentItemOptBuilder withNamespace( Namespace namespace );
+
+ ArchivaContentItemOptBuilder withProject( Project project );
+
+ ArchivaContentItemOptBuilder withVersion( Version version );
+
+ ArchivaContentItem build();
+}
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/builder/DataItemOptBuilder.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/builder/DataItemOptBuilder.java
index 04da17d13..445946ec2 100644
--- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/builder/DataItemOptBuilder.java
+++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/content/base/builder/DataItemOptBuilder.java
@@ -32,8 +32,6 @@ public interface DataItemOptBuilder
extends OptBuilder<ArchivaDataItem, DataItemOptBuilder>
{
- DataItemOptBuilder withParent( ContentItem parent );
-
DataItemOptBuilder withContentType( String contentType );
DataItemOptBuilder withDataType( DataItemType type );
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 dfd770380..2e7871d00 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
@@ -164,6 +164,12 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent
}
@Override
+ public List<String> getArtifactVersions( ItemSelector selector ) throws ContentAccessException, IllegalArgumentException
+ {
+ return null;
+ }
+
+ @Override
public List<? extends Artifact> getArtifacts( ContentItem item ) throws ContentAccessException
{
return null;
@@ -182,6 +188,24 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent
}
@Override
+ public ContentItem getParent( ContentItem item )
+ {
+ return null;
+ }
+
+ @Override
+ public List<? extends ContentItem> getChildren( ContentItem item )
+ {
+ return null;
+ }
+
+ @Override
+ public <T extends ContentItem> T applyCharacteristic( Class<T> clazz, ContentItem item ) throws LayoutException
+ {
+ return null;
+ }
+
+ @Override
public void addArtifact( Path sourceFile, Artifact destination ) throws IllegalArgumentException
{
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 7bbf51736..8a9442a36 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
@@ -164,6 +164,12 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent
}
@Override
+ public List<String> getArtifactVersions( ItemSelector selector ) throws ContentAccessException, IllegalArgumentException
+ {
+ return null;
+ }
+
+ @Override
public List<? extends Artifact> getArtifacts( ContentItem item ) throws ContentAccessException
{
return null;
@@ -182,6 +188,24 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent
}
@Override
+ public ContentItem getParent( ContentItem item )
+ {
+ return null;
+ }
+
+ @Override
+ public List<? extends ContentItem> getChildren( ContentItem item )
+ {
+ return null;
+ }
+
+ @Override
+ public <T extends ContentItem> T applyCharacteristic( Class<T> clazz, ContentItem item ) throws LayoutException
+ {
+ return null;
+ }
+
+ @Override
public void addArtifact( Path sourceFile, Artifact destination ) throws IllegalArgumentException
{
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 6d3d60a0f..fea65d10f 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
@@ -47,6 +47,7 @@ import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
@@ -83,6 +84,12 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent
}
@Override
+ public void deleteAllItems( ItemSelector selector, Consumer<ItemDeleteStatus> consumer ) throws ContentAccessException, IllegalArgumentException
+ {
+
+ }
+
+ @Override
public void deleteItem( ContentItem item ) throws ItemNotFoundException, ContentAccessException
{
@@ -131,6 +138,12 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent
}
@Override
+ public Stream<? extends ContentItem> newItemStream( ItemSelector selector, boolean parallel ) throws ContentAccessException, IllegalArgumentException
+ {
+ return null;
+ }
+
+ @Override
public List<? extends Project> getProjects( Namespace namespace ) throws ContentAccessException
{
return null;
@@ -155,6 +168,12 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent
}
@Override
+ public List<String> getArtifactVersions( ItemSelector selector ) throws ContentAccessException, IllegalArgumentException
+ {
+ return null;
+ }
+
+ @Override
public List<? extends Artifact> getArtifacts( ContentItem item ) throws ContentAccessException
{
return null;
@@ -173,6 +192,24 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent
}
@Override
+ public ContentItem getParent( ContentItem item )
+ {
+ return null;
+ }
+
+ @Override
+ public List<? extends ContentItem> getChildren( ContentItem item )
+ {
+ return null;
+ }
+
+ @Override
+ public <T extends ContentItem> T applyCharacteristic( Class<T> clazz, ContentItem item ) throws LayoutException
+ {
+ return null;
+ }
+
+ @Override
public void addArtifact( Path sourceFile, Artifact destination ) throws IllegalArgumentException
{
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 af42632d6..51e3018e3 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
@@ -24,24 +24,30 @@ import org.apache.archiva.configuration.FileTypes;
import org.apache.archiva.metadata.maven.MavenMetadataReader;
import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
import org.apache.archiva.model.ArchivaArtifact;
+import org.apache.archiva.model.ArchivaRepositoryMetadata;
import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.model.ProjectReference;
import org.apache.archiva.model.VersionedReference;
import org.apache.archiva.repository.ContentAccessException;
import org.apache.archiva.repository.ContentNotFoundException;
import org.apache.archiva.repository.EditableManagedRepository;
+import org.apache.archiva.repository.ItemDeleteStatus;
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.ArtifactType;
+import org.apache.archiva.repository.content.BaseArtifactTypes;
+import org.apache.archiva.repository.content.BaseDataItemTypes;
import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.DataItem;
+import org.apache.archiva.repository.content.DataItemType;
import org.apache.archiva.repository.content.ItemNotFoundException;
import org.apache.archiva.repository.content.ItemSelector;
-import org.apache.archiva.repository.content.BaseArtifactTypes;
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.ArchivaContentItem;
import org.apache.archiva.repository.content.base.ArchivaItemSelector;
import org.apache.archiva.repository.content.base.ArchivaNamespace;
import org.apache.archiva.repository.content.base.ArchivaProject;
@@ -49,6 +55,7 @@ import org.apache.archiva.repository.content.base.ArchivaVersion;
import org.apache.archiva.repository.content.base.builder.ArtifactOptBuilder;
import org.apache.archiva.repository.maven.metadata.storage.ArtifactMappingProvider;
import org.apache.archiva.repository.maven.metadata.storage.DefaultArtifactMappingProvider;
+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;
@@ -57,6 +64,7 @@ import org.apache.commons.lang3.StringUtils;
import javax.inject.Inject;
import javax.inject.Named;
+import javax.naming.Name;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
@@ -67,6 +75,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
+import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -86,7 +95,8 @@ public class ManagedDefaultRepositoryContent
private FileTypes filetypes;
- public void setFileTypes(FileTypes fileTypes) {
+ public void setFileTypes( FileTypes fileTypes )
+ {
this.filetypes = fileTypes;
}
@@ -95,7 +105,7 @@ public class ManagedDefaultRepositoryContent
private FileLockManager lockManager;
@Inject
- @Named("repositoryPathTranslator#maven2")
+ @Named( "repositoryPathTranslator#maven2" )
private RepositoryPathTranslator pathTranslator;
@Inject
@@ -121,17 +131,17 @@ public class ManagedDefaultRepositoryContent
* the hierarchical structure.
* TODO: Better use a object cache? E.g. our spring cache implementation?
*/
- 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<>( );
+ private ReferenceMap<StorageAsset, ContentItem> itemMap = new ReferenceMap<>( );
+ private ReferenceMap<StorageAsset, DataItem> dataItemMap = new ReferenceMap<>( );
- public ManagedDefaultRepositoryContent() {
- super(Collections.singletonList( new DefaultArtifactMappingProvider() ));
+ public ManagedDefaultRepositoryContent( )
+ {
+ super( Collections.singletonList( new DefaultArtifactMappingProvider( ) ) );
}
- public ManagedDefaultRepositoryContent(ManagedRepository repository, FileTypes fileTypes, FileLockManager lockManager) {
- super(Collections.singletonList( new DefaultArtifactMappingProvider() ));
+ public ManagedDefaultRepositoryContent( ManagedRepository repository, FileTypes fileTypes, FileLockManager lockManager )
+ {
+ super( Collections.singletonList( new DefaultArtifactMappingProvider( ) ) );
setFileTypes( fileTypes );
this.lockManager = lockManager;
setRepository( repository );
@@ -139,40 +149,74 @@ public class ManagedDefaultRepositoryContent
public ManagedDefaultRepositoryContent( ManagedRepository repository, List<? extends ArtifactMappingProvider> artifactMappingProviders, FileTypes fileTypes, FileLockManager lockManager )
{
- super(artifactMappingProviders==null ? Collections.singletonList( new DefaultArtifactMappingProvider() ) : artifactMappingProviders);
+ super( artifactMappingProviders == null ? Collections.singletonList( new DefaultArtifactMappingProvider( ) ) : artifactMappingProviders );
setFileTypes( fileTypes );
this.lockManager = lockManager;
setRepository( repository );
}
- private StorageAsset getAssetByPath(String assetPath) {
+ private StorageAsset getAssetByPath( String assetPath )
+ {
return getStorage( ).getAsset( assetPath );
}
- private StorageAsset getAsset(String namespace) {
- String namespacePath = formatAsDirectory( namespace.trim() );
- if (StringUtils.isEmpty( namespacePath )) {
+ private StorageAsset getAsset( String namespace )
+ {
+ String namespacePath = formatAsDirectory( namespace.trim( ) );
+ if ( StringUtils.isEmpty( namespacePath ) )
+ {
namespacePath = "";
}
- return getAssetByPath(namespacePath);
+ return getAssetByPath( namespacePath );
}
- private StorageAsset getAsset(String namespace, String project) {
+ private StorageAsset getAsset( String namespace, String project )
+ {
return getAsset( namespace ).resolve( project );
}
- private StorageAsset getAsset(String namespace, String project, String version) {
+ 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) {
+ private StorageAsset getAsset( String namespace, String project, String version, String fileName )
+ {
return getAsset( namespace, project, version ).resolve( fileName );
}
/// ************* Start of new generation interface ******************
+
+ @Override
+ public void deleteAllItems( ItemSelector selector, Consumer<ItemDeleteStatus> consumer ) throws ContentAccessException, IllegalArgumentException
+ {
+ try ( Stream<? extends ContentItem> stream = newItemStream( selector, false ) )
+ {
+ stream.forEach( item -> {
+ try
+ {
+ deleteItem( item );
+ consumer.accept( new ItemDeleteStatus( item ) );
+ }
+ catch ( ItemNotFoundException e )
+ {
+ consumer.accept( new ItemDeleteStatus( item, ItemDeleteStatus.ITEM_NOT_FOUND, e ) );
+ }
+ catch ( Exception e )
+ {
+ consumer.accept( new ItemDeleteStatus( item, ItemDeleteStatus.DELETION_FAILED, e ) );
+ }
+ catch ( Throwable e )
+ {
+ consumer.accept( new ItemDeleteStatus( item, ItemDeleteStatus.UNKNOWN, e ) );
+ }
+ } );
+ }
+ }
+
/**
* Removes the item from the filesystem. For namespaces, projects and versions it deletes
* recursively.
@@ -180,11 +224,11 @@ public class ManagedDefaultRepositoryContent
* parallel to projects. Which means deleting a namespaces also deletes the sub namespaces and
* not only the projects of the given namespace. Better run the delete for each project of
* a namespace.
- *
+ * <p>
* Artifacts are deleted as provided. No related artifacts will be deleted.
*
* @param item the item that should be removed
- * @throws ItemNotFoundException if the item does not exist
+ * @throws ItemNotFoundException if the item does not exist
* @throws ContentAccessException if some error occurred while accessing the filesystem
*/
@Override
@@ -194,9 +238,9 @@ public class ManagedDefaultRepositoryContent
final Path itemPath = item.getAsset( ).getFilePath( );
if ( !Files.exists( itemPath ) )
{
- throw new ItemNotFoundException( "The item " + item.toString() + "does not exist in the repository " + getId( ) );
+ throw new ItemNotFoundException( "The item " + item.toString( ) + "does not exist in the repository " + getId( ) );
}
- if ( !itemPath.toAbsolutePath().startsWith( baseDirectory.toAbsolutePath() ) )
+ 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 );
@@ -205,10 +249,12 @@ public class ManagedDefaultRepositoryContent
}
try
{
- if (Files.isDirectory( itemPath ))
+ if ( Files.isDirectory( itemPath ) )
{
FileUtils.deleteDirectory( itemPath );
- } else {
+ }
+ else
+ {
Files.deleteIfExists( itemPath );
}
}
@@ -222,13 +268,20 @@ public class ManagedDefaultRepositoryContent
@Override
public ContentItem getItem( ItemSelector selector ) throws ContentAccessException, IllegalArgumentException
{
- if (selector.hasVersion() && selector.hasArtifactId()) {
+ if ( selector.hasVersion( ) && selector.hasArtifactId( ) )
+ {
return getArtifact( selector );
- } else if (selector.hasProjectId() && selector.hasVersion()) {
+ }
+ else if ( selector.hasProjectId( ) && selector.hasVersion( ) )
+ {
return getVersion( selector );
- } else if (selector.hasProjectId()) {
+ }
+ else if ( selector.hasProjectId( ) )
+ {
return getProject( selector );
- } else {
+ }
+ else
+ {
return getNamespace( selector );
}
}
@@ -236,191 +289,199 @@ public class ManagedDefaultRepositoryContent
@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( );
- });
+ StorageAsset nsPath = getAsset( namespaceSelector.getNamespace() );
+ return getNamespaceFromPath( nsPath );
}
@Override
public Project getProject( final ItemSelector selector ) throws ContentAccessException, IllegalArgumentException
{
- if (!selector.hasProjectId()) {
+ if ( !selector.hasProjectId( ) )
+ {
throw new IllegalArgumentException( "Project id must be set" );
}
final StorageAsset path = getAsset( selector.getNamespace( ), selector.getProjectId( ) );
- return projectMap.computeIfAbsent( path, projectPath -> {
- final Namespace ns = getNamespace( selector );
- return ArchivaProject.withAsset( projectPath ).withNamespace( ns ).withId( selector.getProjectId( ) ).build( );
- }
- );
+ return getProjectFromPath( path );
}
@Override
public Version getVersion( final ItemSelector selector ) throws ContentAccessException, IllegalArgumentException
{
- if (!selector.hasProjectId()) {
+ if ( !selector.hasProjectId( ) )
+ {
throw new IllegalArgumentException( "Project id must be set" );
}
- if (!selector.hasVersion() ) {
+ if ( !selector.hasVersion( ) )
+ {
throw new IllegalArgumentException( "Version must be set" );
}
- final StorageAsset path = getAsset(selector.getNamespace(), selector.getProjectId(), selector.getVersion());
- return versionMap.computeIfAbsent( path, versionPath -> {
- final Project project = getProject( selector );
- return ArchivaVersion.withAsset( path )
- .withProject( project )
- .withVersion( selector.getVersion( ) ).build();
- } );
+ final StorageAsset path = getAsset( selector.getNamespace( ), selector.getProjectId( ), selector.getVersion( ) );
+ return getVersionFromPath( path );
}
-
-
-
- public Artifact createArtifact(final StorageAsset artifactPath, final ItemSelector selector,
- final String classifier, final String extension) {
- Version version = getVersion(selector);
+ public Artifact createArtifact( final StorageAsset artifactPath, final ItemSelector selector,
+ final String classifier, final String extension )
+ {
+ Version version = getVersion( selector );
ArtifactOptBuilder builder = org.apache.archiva.repository.content.base.ArchivaArtifact.withAsset( artifactPath )
.withVersion( version )
.withId( selector.getArtifactId( ) )
.withArtifactVersion( mavenContentHelper.getArtifactVersion( artifactPath, selector ) )
.withClassifier( classifier );
- if (selector.hasType()) {
+ if ( selector.hasType( ) )
+ {
builder.withType( selector.getType( ) );
}
return builder.build( );
}
- public Namespace getNamespaceFromArtifactPath( final StorageAsset artifactPath) {
+ public Namespace getNamespaceFromArtifactPath( final StorageAsset artifactPath )
+ {
final StorageAsset namespacePath = artifactPath.getParent( ).getParent( ).getParent( );
- final String namespace = MavenContentHelper.getNamespaceFromNamespacePath( namespacePath );
- return namespaceMap.computeIfAbsent( namespace,
- myNamespace -> ArchivaNamespace.withRepository( this )
- .withAsset( namespacePath )
- .withNamespace( namespace )
- .build( ) );
+ return getNamespaceFromPath( namespacePath );
}
- public Namespace getNamespaceFromPath( final StorageAsset namespacePath) {
+ public Namespace getNamespaceFromPath( final StorageAsset nsPath )
+ {
+ ContentItem item = itemMap.computeIfAbsent( nsPath,
+ path -> createNamespaceFromPath( nsPath ) );
+ if (!item.hasCharacteristic( Namespace.class )) {
+ item.setCharacteristic( Namespace.class, createNamespaceFromPath( nsPath ) );
+ }
+ return item.adapt( Namespace.class );
+ }
+
+ public Namespace createNamespaceFromPath( final StorageAsset namespacePath) {
final String namespace = MavenContentHelper.getNamespaceFromNamespacePath( namespacePath );
- return namespaceMap.computeIfAbsent( namespace,
- myNamespace -> ArchivaNamespace.withRepository( this )
- .withAsset( namespacePath )
- .withNamespace( namespace )
- .build( ) );
- }
-
- private Project getProjectFromPath( final StorageAsset projectPath) {
- return projectMap.computeIfAbsent( projectPath,
- myProjectPath -> ArchivaProject.withAsset( projectPath )
- .withNamespace( getNamespaceFromPath( projectPath.getParent() ) )
- .withId( projectPath.getName( ) ).build( )
+ return ArchivaNamespace.withRepository( this )
+ .withAsset( namespacePath )
+ .withNamespace( namespace )
+ .build( );
+ }
+
+ private Project getProjectFromPath( final StorageAsset path )
+ {
+ ContentItem item = itemMap.computeIfAbsent( path, projectPath ->
+ createProjectFromPath( projectPath )
);
+ if (!item.hasCharacteristic( Project.class )) {
+ item.setCharacteristic( Project.class, createProjectFromPath( path ) );
+ }
+ return item.adapt( Project.class );
+ }
+
+ private Project createProjectFromPath( final StorageAsset projectPath ) {
+ Namespace namespace = getNamespaceFromPath( projectPath.getParent( ) );
+ return ArchivaProject.withRepository( this ).withAsset( projectPath )
+ .withNamespace( namespace )
+ .withId( projectPath.getName( ) ).build( );
}
- private Project getProjectFromArtifactPath( final StorageAsset artifactPath) {
+ 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( )
- );
+ return getProjectFromPath( projectPath );
}
- private Version getVersionFromArtifactPath( final StorageAsset artifactPath) {
+ 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( ) );
+ return getVersionFromPath( versionPath );
}
- private Artifact getArtifactFromPath(final StorageAsset artifactPath) {
+ private Version getVersionFromPath( StorageAsset path )
+ {
+ ContentItem item = itemMap.computeIfAbsent( path, versionPath ->
+ createVersionFromPath( versionPath )
+ );
+ if (!item.hasCharacteristic( Version.class )) {
+ item.setCharacteristic( Version.class, createVersionFromPath( path ) );
+ }
+ return item.adapt( Version.class );
+ }
+
+ private Version createVersionFromPath(StorageAsset path) {
+ Project proj = getProjectFromPath( path.getParent( ) );
+ return ArchivaVersion.withRepository( this ).withAsset( path )
+ .withProject( proj ).withVersion(path.getName()).build();
+ }
+
+ private Artifact getArtifactFromPath( final StorageAsset artifactPath )
+ {
+ DataItem item = dataItemMap.computeIfAbsent( artifactPath, myArtifactPath ->
+ createArtifactFromPath( myArtifactPath )
+ );
+ if (!item.hasCharacteristic( Artifact.class )) {
+ item.setCharacteristic( Artifact.class, createArtifactFromPath( artifactPath ) );
+ }
+ return item.adapt( Artifact.class );
+ }
+
+ private Artifact createArtifactFromPath( 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 )
- .withArtifactType( info.artifactType )
+ final ArtifactInfo info = getArtifactInfoFromPath( version.getVersion( ), artifactPath );
+ return 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 )
+ .withArtifactType( info.artifactType )
+ .build( );
+ }
+
+ private String getContentType(StorageAsset artifactPath) {
+ try
+ {
+ return Files.probeContentType( artifactPath.getFilePath( ) );
+
+ }
+ catch ( IOException e )
+ {
+ return "";
+ }
+ }
+
+ private DataItem getDataItemFromPath( final StorageAsset artifactPath )
+ {
+ final String extension = StringUtils.substringAfterLast( artifactPath.getName( ), "." );
+ final String contentType = getContentType( artifactPath );
+ return dataItemMap.computeIfAbsent( artifactPath, myArtifactPath ->
+ org.apache.archiva.repository.content.base.ArchivaDataItem.withAsset( artifactPath )
+ .withId( artifactPath.getName( ) )
+ .withContentType( 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 = MavenContentHelper.getNamespaceFromNamespacePath( itemPath );
- if (namespaceMap.containsKey( ns )) {
- return namespaceMap.get( ns );
+ private ContentItem getItemFromPath( final StorageAsset itemPath )
+ {
+ if ( itemPath.isLeaf( ) )
+ {
+ if (dataItemMap.containsKey( itemPath )) {
+ return dataItemMap.get( itemPath );
}
- // 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" )
- )) {
- return versionMap.computeIfAbsent( itemPath,
- myVersionPath -> ArchivaVersion.withAsset( itemPath )
- .withProject( (Project)getItemFromPath( itemPath.getParent() ) )
- .withVersion( itemPath.getName() ).build());
+ return getDataItemFromPath( itemPath );
+ }
+ else
+ {
+ if (itemMap.containsKey( itemPath )) {
+ return itemMap.get( itemPath );
} 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( ) );
- }
-
+ return ArchivaContentItem.withRepository( this ).withAsset( itemPath ).build();
}
}
}
// Simple object to hold artifact information
- private class ArtifactInfo {
+ private class ArtifactInfo
+ {
private String id;
private String version;
private String extension;
@@ -432,7 +493,8 @@ public class ManagedDefaultRepositoryContent
private ArtifactType artifactType = BaseArtifactTypes.MAIN;
}
- private ArtifactInfo getArtifactInfoFromPath(String genericVersion, StorageAsset path) {
+ private ArtifactInfo getArtifactInfoFromPath( String genericVersion, StorageAsset path )
+ {
final ArtifactInfo info = new ArtifactInfo( );
info.asset = path;
info.id = path.getParent( ).getParent( ).getName( );
@@ -440,51 +502,64 @@ public class ManagedDefaultRepositoryContent
if ( genericVersion.endsWith( "-" + SNAPSHOT ) )
{
String baseVersion = StringUtils.substringBeforeLast( genericVersion, "-" + SNAPSHOT );
- String prefix = info.id+"-"+baseVersion+"-";
- if (fileName.startsWith( prefix ))
+ 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()) {
+ if ( matcher.matches( ) )
+ {
info.version = baseVersion + "-" + matcher.group( 1 );
String newPrefix = info.id + "-" + info.version;
- if (fileName.startsWith( newPrefix ))
+ if ( fileName.startsWith( newPrefix ) )
{
String classPostfix = StringUtils.removeStart( fileName, newPrefix );
Matcher cMatch = CLASSIFIER_PATTERN.matcher( classPostfix );
- if (cMatch.matches()) {
+ if ( cMatch.matches( ) )
+ {
info.classifier = cMatch.group( 1 );
info.remainder = cMatch.group( 2 );
- } else {
+ }
+ else
+ {
info.classifier = "";
info.remainder = classPostfix;
}
- } else {
+ }
+ else
+ {
log.debug( "Artifact does not match the maven name pattern {}", path );
info.artifactType = BaseArtifactTypes.UNKNOWN;
info.classifier = "";
info.remainder = StringUtils.substringAfter( fileName, prefix );
}
- } else {
+ }
+ else
+ {
log.debug( "Artifact does not match the snapshot version pattern {}", path );
info.artifactType = BaseArtifactTypes.UNKNOWN;
// This is just a guess. No guarantee to the get a usable version.
info.version = StringUtils.removeStart( fileName, info.id + '-' );
- String postfix = StringUtils.substringAfterLast( info.version, "." ).toLowerCase();
- while (COMMON_EXTENSIONS.matcher(postfix).matches()) {
+ String postfix = StringUtils.substringAfterLast( info.version, "." ).toLowerCase( );
+ while ( COMMON_EXTENSIONS.matcher( postfix ).matches( ) )
+ {
info.version = StringUtils.substringBeforeLast( info.version, "." );
- postfix = StringUtils.substringAfterLast( info.version, "." ).toLowerCase();
+ postfix = StringUtils.substringAfterLast( info.version, "." ).toLowerCase( );
}
info.classifier = "";
info.remainder = StringUtils.substringAfter( fileName, prefix );
}
- } else {
+ }
+ else
+ {
log.debug( "Artifact does not match the maven name pattern: {}", path );
- if ( fileName.contains( "-"+baseVersion ) )
+ if ( fileName.contains( "-" + baseVersion ) )
+ {
+ info.id = StringUtils.substringBefore( fileName, "-" + baseVersion );
+ }
+ else
{
- info.id = StringUtils.substringBefore( fileName, "-"+baseVersion );
- } else {
info.id = fileName;
}
info.artifactType = BaseArtifactTypes.UNKNOWN;
@@ -492,24 +567,34 @@ public class ManagedDefaultRepositoryContent
info.classifier = "";
info.remainder = StringUtils.substringAfterLast( fileName, "." );
}
- } else {
- String prefix = info.id+"-"+genericVersion;
- if (fileName.startsWith( prefix ))
+ }
+ else
+ {
+ String prefix = info.id + "-" + genericVersion;
+ if ( fileName.startsWith( prefix ) )
{
- info.version=genericVersion;
+ info.version = genericVersion;
String classPostfix = StringUtils.removeStart( fileName, prefix );
Matcher cMatch = CLASSIFIER_PATTERN.matcher( classPostfix );
- if (cMatch.matches()) {
+ if ( cMatch.matches( ) )
+ {
info.classifier = cMatch.group( 1 );
info.remainder = cMatch.group( 2 );
- } else {
+ }
+ else
+ {
info.classifier = "";
info.remainder = classPostfix;
}
- } else {
- if (fileName.contains( "-"+genericVersion )) {
- info.id = StringUtils.substringBefore( fileName, "-"+genericVersion );
- } else {
+ }
+ else
+ {
+ if ( fileName.contains( "-" + genericVersion ) )
+ {
+ info.id = StringUtils.substringBefore( fileName, "-" + genericVersion );
+ }
+ else
+ {
info.id = fileName;
}
log.debug( "Artifact does not match the version pattern {}", path );
@@ -521,19 +606,27 @@ public class ManagedDefaultRepositoryContent
}
info.extension = StringUtils.substringAfterLast( fileName, "." );
info.type = MavenContentHelper.getTypeFromClassifierAndExtension( info.classifier, info.extension );
- try {
+ try
+ {
info.contentType = Files.probeContentType( path.getFilePath( ) );
- } catch (IOException e) {
+ }
+ catch ( IOException e )
+ {
info.contentType = "";
//
}
- if (MavenContentHelper.METADATA_FILENAME.equalsIgnoreCase( fileName )) {
+ if ( MavenContentHelper.METADATA_FILENAME.equalsIgnoreCase( fileName ) )
+ {
info.artifactType = BaseArtifactTypes.METADATA;
- } else if (MavenContentHelper.METADATA_REPOSITORY_FILENAME.equalsIgnoreCase( fileName )) {
+ }
+ else if ( MavenContentHelper.METADATA_REPOSITORY_FILENAME.equalsIgnoreCase( fileName ) )
+ {
info.artifactType = MavenTypes.REPOSITORY_METADATA;
- } else if (StringUtils.isNotEmpty( info.remainder ) && StringUtils.countMatches( info.remainder, "." )>=2) {
+ }
+ else if ( StringUtils.isNotEmpty( info.remainder ) && StringUtils.countMatches( info.remainder, "." ) >= 2 )
+ {
String mainFile = StringUtils.substringBeforeLast( fileName, "." );
- if (path.getParent().resolve( mainFile ).exists())
+ if ( path.getParent( ).resolve( mainFile ).exists( ) )
{
info.artifactType = BaseArtifactTypes.RELATED;
}
@@ -545,17 +638,20 @@ public class ManagedDefaultRepositoryContent
@Override
public Artifact getArtifact( final ItemSelector selector ) throws ContentAccessException
{
- if (!selector.hasProjectId( )) {
+ if ( !selector.hasProjectId( ) )
+ {
throw new IllegalArgumentException( "Project id must be set" );
}
- if (!selector.hasVersion( )) {
+ if ( !selector.hasVersion( ) )
+ {
throw new IllegalArgumentException( "Version must be set" );
}
- if (!selector.hasArtifactId( )) {
+ if ( !selector.hasArtifactId( ) )
+ {
throw new IllegalArgumentException( "Artifact id must be set" );
}
- final StorageAsset artifactDir = getAsset(selector.getNamespace(), selector.getProjectId(),
- selector.getVersion());
+ final StorageAsset artifactDir = getAsset( selector.getNamespace( ), selector.getProjectId( ),
+ selector.getVersion( ) );
final String artifactVersion = mavenContentHelper.getArtifactVersion( artifactDir, selector );
final String classifier = MavenContentHelper.getClassifier( selector );
final String extension = MavenContentHelper.getArtifactExtension( selector );
@@ -563,7 +659,7 @@ public class ManagedDefaultRepositoryContent
final String fileName = MavenContentHelper.getArtifactFileName( artifactId, artifactVersion, classifier, extension );
final StorageAsset path = getAsset( selector.getNamespace( ), selector.getProjectId( ),
selector.getVersion( ), fileName );
- return artifactMap.computeIfAbsent( path, artifactPath -> createArtifact( path, selector, classifier, extension ) );
+ return getArtifactFromPath( path );
}
/**
@@ -575,7 +671,7 @@ public class ManagedDefaultRepositoryContent
return namespace.getAsset( ).list( ).stream( )
.filter( a -> a.isContainer( ) )
.map( a -> getProjectFromPath( a ) )
- .collect( Collectors.toList());
+ .collect( Collectors.toList( ) );
}
@Override
@@ -586,6 +682,7 @@ public class ManagedDefaultRepositoryContent
/**
* Returns a version object for each directory that is a direct child of the project directory.
+ *
* @param project the project for which the versions should be returned
* @return the list of versions or a empty list, if not version was found
*/
@@ -596,41 +693,70 @@ public class ManagedDefaultRepositoryContent
return asset.list( ).stream( ).filter( a -> a.isContainer( ) )
.map( a -> ArchivaVersion.withAsset( a )
.withProject( project )
- .withVersion( a.getName() ).build() )
+ .withVersion( a.getName( ) ).build( ) )
.collect( Collectors.toList( ) );
}
/**
- * If the selector specifies a version, all artifact versions are returned, which means for snapshot
- * versions the artifact versions are returned too.
+ * Returns the versions that can be found for the given selector.
*
* @param selector the item selector. At least namespace and projectId must be set.
* @return the list of version objects or a empty list, if the selector does not match a version
- * @throws ContentAccessException if the access to the underlying backend failed
+ * @throws ContentAccessException if the access to the underlying backend failed
* @throws IllegalArgumentException if the selector has no projectId specified
*/
@Override
public List<? extends Version> getVersions( final ItemSelector selector ) throws ContentAccessException, IllegalArgumentException
{
- if (!selector.hasProjectId()) {
+ if ( !selector.hasProjectId( ) )
+ {
log.error( "Bad item selector for version list: {}", selector );
throw new IllegalArgumentException( "Project id not set, while retrieving versions." );
}
final Project project = getProject( selector );
- if (selector.hasVersion()) {
+ if ( selector.hasVersion( ) )
+ {
final StorageAsset asset = getAsset( selector.getNamespace( ), selector.getProjectId( ), selector.getVersion( ) );
return asset.list( ).stream( ).map( a -> getArtifactInfoFromPath( selector.getVersion( ), a ) )
.filter( ai -> StringUtils.isNotEmpty( ai.version ) )
- .map( v -> ArchivaVersion.withAsset( v.asset.getParent() )
- .withProject( project ).withVersion( v.version )
- .withAttribute(SNAPSHOT_ARTIFACT_VERSION,"true").build() )
- .distinct()
+ .map( v -> getVersionFromArtifactPath( v.asset ) )
+ .distinct( )
.collect( Collectors.toList( ) );
- } else {
+ }
+ else
+ {
return getVersions( project );
}
}
+ public List<String> getArtifactVersions( final ItemSelector selector ) throws ContentAccessException, IllegalArgumentException
+ {
+ if ( !selector.hasProjectId( ) )
+ {
+ log.error( "Bad item selector for version list: {}", selector );
+ throw new IllegalArgumentException( "Project id not set, while retrieving versions." );
+ }
+ final Project project = getProject( selector );
+ if ( selector.hasVersion( ) )
+ {
+ final StorageAsset asset = getAsset( selector.getNamespace( ), selector.getProjectId( ), selector.getVersion( ) );
+ return asset.list( ).stream( ).map( a -> getArtifactInfoFromPath( selector.getVersion( ), a ) )
+ .filter( ai -> StringUtils.isNotEmpty( ai.version ) )
+ .map( v -> v.version )
+ .distinct( )
+ .collect( Collectors.toList( ) );
+ }
+ else
+ {
+ return project.getAsset( ).list( ).stream( ).map( a -> getVersionFromPath( a ) )
+ .flatMap( v -> v.getAsset( ).list( ).stream( ).map( a -> getArtifactInfoFromPath( v.getVersion( ), a ) ) )
+ .filter( ai -> StringUtils.isNotEmpty( ai.version ) )
+ .map( v -> v.version )
+ .distinct( )
+ .collect( Collectors.toList( ) );
+ }
+ }
+
/**
* See {@link #newArtifactStream(ItemSelector)}. This method collects the stream into a list.
@@ -642,8 +768,9 @@ public class ManagedDefaultRepositoryContent
@Override
public List<? extends Artifact> getArtifacts( ItemSelector selector ) throws ContentAccessException
{
- try(Stream<? extends Artifact> stream = newArtifactStream( selector )) {
- return stream.collect( Collectors.toList());
+ try ( Stream<? extends Artifact> stream = newArtifactStream( selector ) )
+ {
+ return stream.collect( Collectors.toList( ) );
}
}
@@ -651,33 +778,44 @@ public class ManagedDefaultRepositoryContent
/*
* File filter to select certain artifacts using the selector data.
*/
- private Predicate<StorageAsset> getFileFilterFromSelector(final ItemSelector selector) {
+ private Predicate<StorageAsset> getArtifactFileFilterFromSelector( final ItemSelector selector )
+ {
Predicate<StorageAsset> p = a -> a.isLeaf( );
- StringBuilder fileNamePattern = new StringBuilder("^" );
- if (selector.hasArtifactId()) {
- fileNamePattern.append( Pattern.quote(selector.getArtifactId( )) ).append("-");
- } else {
- fileNamePattern.append("[A-Za-z0-9_\\-.]+-");
+ StringBuilder fileNamePattern = new StringBuilder( "^" );
+ if ( selector.hasArtifactId( ) )
+ {
+ fileNamePattern.append( Pattern.quote( selector.getArtifactId( ) ) ).append( "-" );
+ }
+ else
+ {
+ fileNamePattern.append( "[A-Za-z0-9_\\-.]+-" );
}
- if (selector.hasArtifactVersion()) {
- if ( selector.getArtifactVersion( ).contains("*")) {
+ if ( selector.hasArtifactVersion( ) )
+ {
+ if ( selector.getArtifactVersion( ).contains( "*" ) )
+ {
String[] tokens = StringUtils.splitByWholeSeparator( selector.getArtifactVersion( ), "*" );
- for (String currentToken : tokens) {
- if (!currentToken.equals("")) {
+ for ( String currentToken : tokens )
+ {
+ if ( !currentToken.equals( "" ) )
+ {
fileNamePattern.append( Pattern.quote( currentToken ) );
}
fileNamePattern.append( "[A-Za-z0-9_\\-.]*" );
}
- } else
+ }
+ else
{
fileNamePattern.append( Pattern.quote( selector.getArtifactVersion( ) ) );
}
- } else {
+ }
+ else
+ {
fileNamePattern.append( "[A-Za-z0-9_\\-.]+" );
}
String classifier = selector.hasClassifier( ) ? selector.getClassifier( ) :
( selector.hasType( ) ? MavenContentHelper.getClassifierFromType( selector.getType( ) ) : null );
- if (classifier != null)
+ if ( classifier != null )
{
if ( "*".equals( classifier ) )
{
@@ -685,25 +823,32 @@ public class ManagedDefaultRepositoryContent
}
else
{
- fileNamePattern.append("-").append( Pattern.quote( classifier ) ).append( "\\." );
+ fileNamePattern.append( "-" ).append( Pattern.quote( classifier ) ).append( "\\." );
}
- } else {
+ }
+ else
+ {
fileNamePattern.append( "\\." );
}
String extension = selector.hasExtension( ) ? selector.getExtension( ) :
( selector.hasType( ) ? MavenContentHelper.getArtifactExtension( selector ) : null );
- if (extension != null) {
- if (selector.includeRelatedArtifacts())
+ if ( extension != null )
+ {
+ if ( selector.includeRelatedArtifacts( ) )
+ {
+ fileNamePattern.append( Pattern.quote( extension ) ).append( "(\\.[A-Za-z0-9]+)?" );
+ }
+ else
{
- fileNamePattern.append( Pattern.quote( extension ) ).append("(\\.[A-Za-z0-9]+)?");
- } else {
fileNamePattern.append( Pattern.quote( extension ) );
}
- } else {
+ }
+ else
+ {
fileNamePattern.append( "[A-Za-z0-9.]+" );
}
- final Pattern pattern = Pattern.compile( fileNamePattern.toString() );
- return p.and( a -> pattern.matcher( a.getName( ) ).matches());
+ final Pattern pattern = Pattern.compile( fileNamePattern.toString( ) );
+ return p.and( a -> pattern.matcher( a.getName( ) ).matches( ) );
}
@@ -725,11 +870,11 @@ public class ManagedDefaultRepositoryContent
* To select only artifacts that match the layout you should add the artifact id and artifact version
* (can contain a '*' pattern).</li>
* </ul>
- *
+ * <p>
* The '*' pattern can be used in classifiers and artifact versions and match zero or more characters.
- *
+ * <p>
* There is no determinate order of the elements in the stream.
- *
+ * <p>
* Returned streams are auto closable and should be used in a try-with-resources statement.
*
* @param selector the item selector
@@ -740,28 +885,34 @@ public class ManagedDefaultRepositoryContent
{
String projectId = selector.hasProjectId( ) ? selector.getProjectId( ) : ( selector.hasArtifactId( ) ? selector.getArtifactId( )
: null );
- final Predicate<StorageAsset> filter = getFileFilterFromSelector( selector );
- if (projectId!=null && selector.hasVersion()) {
+ final Predicate<StorageAsset> filter = getArtifactFileFilterFromSelector( selector );
+ if ( projectId != null && selector.hasVersion( ) )
+ {
return getAsset( selector.getNamespace( ), projectId, selector.getVersion( ) )
.list( ).stream( ).filter( filter )
.map( this::getArtifactFromPath );
- } else if (projectId!=null) {
+ }
+ else if ( projectId != null )
+ {
final StorageAsset projDir = getAsset( selector.getNamespace( ), projectId );
return projDir.list( ).stream( )
- .map(a -> a.isContainer( ) ? a.list( ) : Arrays.asList( a ) )
+ .map( a -> a.isContainer( ) ? a.list( ) : Arrays.asList( a ) )
.flatMap( List::stream )
.filter( filter )
.map( this::getArtifactFromPath );
- } else
+ }
+ else
{
StorageAsset namespaceDir = getAsset( selector.getNamespace( ) );
- if (selector.recurse())
+ if ( selector.recurse( ) )
{
return StorageUtil.newAssetStream( namespaceDir, true )
.filter( filter )
- .map( this::getArtifactFromPath );
+ .map( this::getArtifactFromPath );
- } else {
+ }
+ else
+ {
// We descend into 2 subdirectories (project and version)
return namespaceDir.list( ).stream( )
.map( a -> a.isContainer( ) ? a.list( ) : Arrays.asList( a ) )
@@ -783,13 +934,15 @@ public class ManagedDefaultRepositoryContent
@Override
public List<? extends Artifact> getArtifacts( ContentItem item )
{
- try(Stream<? extends Artifact> stream = newArtifactStream( item )) {
- return stream.collect( Collectors.toList());
+ try ( Stream<? extends Artifact> stream = newArtifactStream( item ) )
+ {
+ return stream.collect( Collectors.toList( ) );
}
}
/**
* Returns all artifacts
+ *
* @param item
* @return
* @throws ContentAccessException
@@ -801,20 +954,21 @@ public class ManagedDefaultRepositoryContent
public Stream<? extends Artifact> newArtifactStream( Project item ) throws ContentAccessException
{
- return newArtifactStream( ArchivaItemSelector.builder( ).withNamespace( item.getNamespace( ).getNamespace() )
- .withProjectId( item.getId() ).build( ) );
+ return newArtifactStream( ArchivaItemSelector.builder( ).withNamespace( item.getNamespace( ).getNamespace( ) )
+ .withProjectId( item.getId( ) ).build( ) );
}
public Stream<? extends Artifact> newArtifactStream( Version item ) throws ContentAccessException
{
- return newArtifactStream( ArchivaItemSelector.builder( ).withNamespace( item.getProject().getNamespace( ).getNamespace() )
- .withProjectId( item.getProject().getId() )
- .withVersion( item.getVersion() ).build( ) );
+ return newArtifactStream( ArchivaItemSelector.builder( ).withNamespace( item.getProject( ).getNamespace( ).getNamespace( ) )
+ .withProjectId( item.getProject( ).getId( ) )
+ .withVersion( item.getVersion( ) ).build( ) );
}
/**
* Returns all related artifacts that match the given artifact. That means all artifacts that have
* the same filename plus an additional extension, e.g. ${fileName}.sha2
+ *
* @param item the artifact
* @return the stream of artifacts
* @throws ContentAccessException
@@ -828,6 +982,7 @@ public class ManagedDefaultRepositoryContent
return v.getAsset( ).list( ).stream( ).filter( filter )
.map( a -> getArtifactFromPath( a ) );
}
+
/**
* Returns the stream of artifacts that are children of the given item.
*
@@ -838,21 +993,162 @@ public class ManagedDefaultRepositoryContent
@Override
public Stream<? extends Artifact> newArtifactStream( ContentItem item ) throws ContentAccessException
{
- if (item instanceof Namespace) {
+ if ( item instanceof Namespace )
+ {
return newArtifactStream( ( (Namespace) item ) );
- } else if (item instanceof Project) {
+ }
+ else if ( item instanceof Project )
+ {
return newArtifactStream( (Project) item );
- } else if (item instanceof Version) {
+ }
+ else if ( item instanceof Version )
+ {
return newArtifactStream( (Version) item );
- } else if (item instanceof Artifact) {
+ }
+ else if ( item instanceof Artifact )
+ {
return newArtifactStream( (Artifact) item );
- } else
+ }
+ else
{
log.warn( "newArtifactStream for unsupported item requested: {}", item.getClass( ).getName( ) );
return Stream.empty( );
}
}
+ private void appendPatternRegex( StringBuilder builder, String name )
+ {
+ String[] patternArray = name.split( "[*]" );
+ for ( int i = 0; i < patternArray.length - 1; i++ )
+ {
+ builder.append( Pattern.quote( patternArray[i] ) )
+ .append( "[A-Za-z0-9_\\-]*" );
+ }
+ builder.append( Pattern.quote( patternArray[patternArray.length - 1] ) );
+ }
+
+ Predicate<StorageAsset> getItemFileFilterFromSelector( ItemSelector selector )
+ {
+ if ( !selector.hasNamespace( ) && !selector.hasProjectId( ) )
+ {
+ throw new IllegalArgumentException( "Selector must have at least namespace and projectid" );
+ }
+ StringBuilder pathMatcher = new StringBuilder( "^" );
+ if ( selector.hasNamespace( ) )
+ {
+ String path = "/" + String.join( "/", selector.getNamespace( ).split( "\\." ) );
+ if ( path.contains( "*" ) )
+ {
+ appendPatternRegex( pathMatcher, path );
+ }
+ else
+ {
+ pathMatcher.append( Pattern.quote( path ) );
+ }
+
+ }
+ if ( selector.hasProjectId( ) )
+ {
+ pathMatcher.append( "/" );
+ if ( selector.getProjectId( ).contains( "*" ) )
+ {
+ appendPatternRegex( pathMatcher, selector.getProjectId( ) );
+ }
+ else
+ {
+ pathMatcher.append( Pattern.quote( selector.getProjectId( ) ) );
+ }
+ }
+ if ( selector.hasVersion( ) )
+ {
+ pathMatcher.append( "/" );
+ if ( selector.getVersion( ).contains( "*" ) )
+ {
+ appendPatternRegex( pathMatcher, selector.getVersion( ) );
+ }
+ else
+ {
+ pathMatcher.append( Pattern.quote( selector.getVersion( ) ) );
+ }
+ }
+ pathMatcher.append( ".*" );
+ final Pattern pathPattern = Pattern.compile( pathMatcher.toString( ) );
+ final Predicate<StorageAsset> pathPredicate = ( StorageAsset asset ) -> pathPattern.matcher( asset.getPath( ) ).matches( );
+ if ( selector.hasArtifactId( ) || selector.hasArtifactVersion( ) || selector.hasClassifier( )
+ || selector.hasType( ) || selector.hasExtension( ) )
+ {
+ return getArtifactFileFilterFromSelector( selector ).and( pathPredicate );
+ }
+ else
+ {
+ return pathPredicate;
+ }
+ }
+
+ /**
+ * Returns a concatenation of the asset and its children as stream, if they exist.
+ * It descends <code>level+1</code> levels down.
+ *
+ * @param a the asset to start from
+ * @param level the number of child levels to descend. 0 means only the children of the given asset, 1 means the children of childrens of the given asset, ...
+ * @return the stream of storage assets
+ */
+ private Stream<StorageAsset> getChildrenDF( StorageAsset a, int level )
+ {
+ if ( a.isContainer( ) )
+ {
+ if (level>0) {
+ return Stream.concat( a.list().stream( ).flatMap( ch -> getChildrenDF( ch, level - 1 ) ), Stream.of( a ) );
+ } else
+ {
+ return Stream.concat( a.list( ).stream( ), Stream.of( a ) );
+ }
+ }
+ else
+ {
+ return Stream.of( a );
+ }
+ }
+
+ @Override
+ public Stream<? extends ContentItem> newItemStream( ItemSelector selector, boolean parallel ) throws ContentAccessException, IllegalArgumentException
+ {
+ final Predicate<StorageAsset> filter = getItemFileFilterFromSelector( selector );
+ StorageAsset startDir;
+ if (selector.getNamespace().contains("*")) {
+ startDir = getAsset( "" );
+ } else if ( selector.hasProjectId( ) && selector.getProjectId().contains("*") )
+ {
+ startDir = getAsset( selector.getNamespace( ) );
+ } else if ( selector.hasProjectId() && selector.hasVersion() && selector.getVersion().contains("*")) {
+ startDir = getAsset( selector.getNamespace( ), selector.getProjectId( ) );
+ }
+ else if ( selector.hasProjectId( ) && selector.hasVersion( ) )
+ {
+ startDir = getAsset( selector.getNamespace( ), selector.getProjectId( ), selector.getVersion() );
+ }
+ else if ( selector.hasProjectId( ) )
+ {
+ startDir = getAsset( selector.getNamespace( ), selector.getProjectId( ) );
+ }
+ else
+ {
+ startDir = getAsset( selector.getNamespace( ) );
+ if ( !selector.recurse( ) )
+ {
+ // We descend into 2 subdirectories (project and version)
+ return startDir.list( ).stream( )
+ .flatMap( a -> getChildrenDF( a, 1 ) )
+ .map( this::getItemFromPath );
+ }
+ }
+ ;
+ return StorageUtil.newAssetStream( startDir, parallel )
+ .filter( filter )
+ .map( this::getItemFromPath );
+
+ }
+
/**
* Checks, if the asset/file queried by the given selector exists.
*/
@@ -862,6 +1158,52 @@ public class ManagedDefaultRepositoryContent
return getItem( selector ).getAsset( ).exists( );
}
+ @Override
+ public ContentItem getParent( ContentItem item )
+ {
+ return getItemFromPath( item.getAsset( ).getParent( ) );
+ }
+
+ @Override
+ public List<? extends ContentItem> getChildren( ContentItem item )
+ {
+ if (item.getAsset().isLeaf()) {
+ return Collections.emptyList( );
+ } else {
+ return item.getAsset( ).list( ).stream( ).map( a -> getItemFromPath( a ) ).collect( Collectors.toList( ) );
+ }
+ }
+
+ @Override
+ public <T extends ContentItem> T applyCharacteristic( Class<T> clazz, ContentItem item ) throws LayoutException
+ {
+ if (item.getAsset().isLeaf()) {
+ if (clazz.isAssignableFrom( Artifact.class )) {
+ Artifact artifact = getArtifactFromPath( item.getAsset( ) );
+ item.setCharacteristic( Artifact.class, artifact );
+ return (T) artifact;
+ } else {
+ throw new LayoutException( "Could not adapt file to clazz " + clazz );
+ }
+ } else {
+ if (clazz.isAssignableFrom( Version.class )) {
+ Version version = getVersionFromPath( item.getAsset( ) );
+ item.setCharacteristic( Version.class, version );
+ return (T) version;
+ } else if (clazz.isAssignableFrom( Project.class )) {
+ Project project = getProjectFromPath( item.getAsset( ) );
+ item.setCharacteristic( Project.class, project );
+ return (T) project;
+ } else if (clazz.isAssignableFrom( Namespace.class )) {
+ Namespace ns = getNamespaceFromPath( item.getAsset( ) );
+ item.setCharacteristic( Namespace.class, ns );
+ return (T) ns;
+ } else {
+ throw new LayoutException( "Cannot adapt directory to clazz " + clazz );
+ }
+ }
+ }
+
/**
* Moves the file to the artifact destination
*/
@@ -871,14 +1213,15 @@ public class ManagedDefaultRepositoryContent
try
{
StorageAsset asset = destination.getAsset( );
- if (!asset.exists()) {
- asset.create();
+ if ( !asset.exists( ) )
+ {
+ asset.create( );
}
asset.replaceDataFromFile( sourceFile );
}
catch ( IOException e )
{
- log.error( "Could not push data to asset source={} destination={}. {}", sourceFile, destination.getAsset().getFilePath(), e.getMessage( ) );
+ log.error( "Could not push data to asset source={} destination={}. {}", sourceFile, destination.getAsset( ).getFilePath( ), e.getMessage( ) );
throw new ContentAccessException( e.getMessage( ), e );
}
}
@@ -887,11 +1230,13 @@ public class ManagedDefaultRepositoryContent
public ContentItem toItem( String path ) throws LayoutException
{
StorageAsset asset = getRepository( ).getAsset( path );
- if (asset.isLeaf())
+ if ( asset.isLeaf( ) )
{
ItemSelector selector = getPathParser( ).toItemSelector( path );
return getItem( selector );
- } else {
+ }
+ else
+ {
return getItemFromPath( asset );
}
}
@@ -906,22 +1251,26 @@ public class ManagedDefaultRepositoryContent
/**
* Returns a version reference from the coordinates
- * @param groupId the group id
+ *
+ * @param groupId the group id
* @param artifactId the artifact id
- * @param version the version
+ * @param version the version
* @return the versioned reference object
*/
@Override
- public VersionedReference toVersion( String groupId, String artifactId, String version ) {
- return new VersionedReference().groupId( groupId ).artifactId( artifactId ).version( version );
+ public VersionedReference toVersion( String groupId, String artifactId, String version )
+ {
+ return new VersionedReference( ).groupId( groupId ).artifactId( artifactId ).version( version );
}
/**
* Return the version the artifact is part of
+ *
* @param artifactReference
* @return
*/
- public VersionedReference toVersion( ArtifactReference artifactReference) {
+ public VersionedReference toVersion( ArtifactReference artifactReference )
+ {
return toVersion( artifactReference.getGroupId( ), artifactReference.getArtifactId( ), artifactReference.getVersion( ) );
}
@@ -930,13 +1279,13 @@ public class ManagedDefaultRepositoryContent
public void deleteVersion( VersionedReference ref ) throws ContentNotFoundException, ContentAccessException
{
final String path = toPath( ref );
- final Path deleteTarget = getRepoDir().resolve(path);
- if ( !Files.exists(deleteTarget) )
+ final Path deleteTarget = getRepoDir( ).resolve( path );
+ if ( !Files.exists( deleteTarget ) )
{
- log.warn( "Version path for repository {} does not exist: {}", getId(), deleteTarget );
- throw new ContentNotFoundException( "Version not found for repository "+getId()+": "+path );
+ log.warn( "Version path for repository {} does not exist: {}", getId( ), deleteTarget );
+ throw new ContentNotFoundException( "Version not found for repository " + getId( ) + ": " + path );
}
- if ( Files.isDirectory(deleteTarget) )
+ if ( Files.isDirectory( deleteTarget ) )
{
try
{
@@ -945,11 +1294,13 @@ public class ManagedDefaultRepositoryContent
catch ( IOException e )
{
log.error( "Could not delete file path {}: {}", deleteTarget, e.getMessage( ), e );
- throw new ContentAccessException( "Error while trying to delete path "+path+" from repository "+getId()+": "+e.getMessage( ), e );
+ throw new ContentAccessException( "Error while trying to delete path " + path + " from repository " + getId( ) + ": " + e.getMessage( ), e );
}
- } else {
- log.warn( "Version path for repository {} is not a directory {}", getId(), deleteTarget );
- throw new ContentNotFoundException( "Version path for repository "+getId()+" is not directory: " + path );
+ }
+ else
+ {
+ log.warn( "Version path for repository {} is not a directory {}", getId( ), deleteTarget );
+ throw new ContentNotFoundException( "Version path for repository " + getId( ) + " is not directory: " + path );
}
}
@@ -959,12 +1310,12 @@ public class ManagedDefaultRepositoryContent
{
final String path = toPath( ref );
final Path deleteTarget = getRepoDir( ).resolve( path );
- if ( !Files.exists(deleteTarget) )
+ if ( !Files.exists( deleteTarget ) )
{
- log.warn( "Project path for repository {} does not exist: {}", getId(), deleteTarget );
- throw new ContentNotFoundException( "Project not found for repository "+getId()+": "+path );
+ log.warn( "Project path for repository {} does not exist: {}", getId( ), deleteTarget );
+ throw new ContentNotFoundException( "Project not found for repository " + getId( ) + ": " + path );
}
- if ( Files.isDirectory(deleteTarget) )
+ if ( Files.isDirectory( deleteTarget ) )
{
try
{
@@ -973,13 +1324,13 @@ public class ManagedDefaultRepositoryContent
catch ( IOException e )
{
log.error( "Could not delete file path {}: {}", deleteTarget, e.getMessage( ), e );
- throw new ContentAccessException( "Error while trying to delete path "+path+" from repository "+getId()+": "+e.getMessage( ), e );
+ throw new ContentAccessException( "Error while trying to delete path " + path + " from repository " + getId( ) + ": " + e.getMessage( ), e );
}
}
else
{
- log.warn( "Project path for repository {} is not a directory {}", getId(), deleteTarget );
- throw new ContentNotFoundException( "Project path for repository "+getId()+" is not directory: " + path );
+ log.warn( "Project path for repository {} is not a directory {}", getId( ), deleteTarget );
+ throw new ContentNotFoundException( "Project path for repository " + getId( ) + " is not directory: " + path );
}
}
@@ -987,7 +1338,7 @@ public class ManagedDefaultRepositoryContent
@Override
public void deleteProject( String namespace, String projectId ) throws ContentNotFoundException, ContentAccessException
{
- this.deleteProject( new ProjectReference().groupId( namespace ).artifactId( projectId ) );
+ this.deleteProject( new ProjectReference( ).groupId( namespace ).artifactId( projectId ) );
}
@Override
@@ -996,25 +1347,29 @@ public class ManagedDefaultRepositoryContent
final String path = toPath( ref );
final Path repoDir = getRepoDir( );
Path deleteTarget = repoDir.resolve( path );
- if ( Files.exists(deleteTarget) )
+ if ( Files.exists( deleteTarget ) )
{
try
{
- if (Files.isDirectory( deleteTarget ))
+ if ( Files.isDirectory( deleteTarget ) )
{
org.apache.archiva.common.utils.FileUtils.deleteDirectory( deleteTarget );
- } else {
+ }
+ else
+ {
Files.delete( deleteTarget );
}
}
catch ( IOException e )
{
log.error( "Could not delete file path {}: {}", deleteTarget, e.getMessage( ), e );
- throw new ContentAccessException( "Error while trying to delete path "+path+" from repository "+getId()+": "+e.getMessage( ), e );
+ throw new ContentAccessException( "Error while trying to delete path " + path + " from repository " + getId( ) + ": " + e.getMessage( ), e );
}
- } else {
- log.warn( "Artifact path for repository {} does not exist: {}", getId(), deleteTarget );
- throw new ContentNotFoundException( "Artifact not found for repository "+getId()+": "+path );
+ }
+ else
+ {
+ log.warn( "Artifact path for repository {} does not exist: {}", getId( ), deleteTarget );
+ throw new ContentNotFoundException( "Artifact not found for repository " + getId( ) + ": " + path );
}
}
@@ -1025,11 +1380,12 @@ public class ManagedDefaultRepositoryContent
{
final String path = toPath( groupId );
final Path deleteTarget = getRepoDir( ).resolve( path );
- if (!Files.exists(deleteTarget)) {
- log.warn( "Namespace path for repository {} does not exist: {}", getId(), deleteTarget );
- throw new ContentNotFoundException( "Namespace not found for repository "+getId()+": "+path );
+ if ( !Files.exists( deleteTarget ) )
+ {
+ log.warn( "Namespace path for repository {} does not exist: {}", getId( ), deleteTarget );
+ throw new ContentNotFoundException( "Namespace not found for repository " + getId( ) + ": " + path );
}
- if ( Files.isDirectory(deleteTarget) )
+ if ( Files.isDirectory( deleteTarget ) )
{
try
{
@@ -1038,19 +1394,21 @@ public class ManagedDefaultRepositoryContent
catch ( IOException e )
{
log.error( "Could not delete file path {}: {}", deleteTarget, e.getMessage( ), e );
- throw new ContentAccessException( "Error while trying to delete path "+path+" from repository "+getId()+": "+e.getMessage( ), e );
+ throw new ContentAccessException( "Error while trying to delete path " + path + " from repository " + getId( ) + ": " + e.getMessage( ), e );
}
- } else {
- log.warn( "Namespace path for repository {} is not a directory {}", getId(), deleteTarget );
- throw new ContentNotFoundException( "Namespace path for repository "+getId()+" is not directory: " + path );
+ }
+ else
+ {
+ log.warn( "Namespace path for repository {} is not a directory {}", getId( ), deleteTarget );
+ throw new ContentNotFoundException( "Namespace path for repository " + getId( ) + " is not directory: " + path );
}
}
@Override
- public String getId()
+ public String getId( )
{
- return repository.getId();
+ return repository.getId( );
}
@Override
@@ -1058,45 +1416,59 @@ public class ManagedDefaultRepositoryContent
throws ContentNotFoundException, LayoutException, ContentAccessException
{
StorageAsset artifactDir = toFile( reference );
- if ( !artifactDir.exists())
+ if ( !artifactDir.exists( ) )
{
throw new ContentNotFoundException(
- "Unable to get related artifacts using a non-existant directory: " + artifactDir.getPath() );
+ "Unable to get related artifacts using a non-existant directory: " + artifactDir.getPath( ) );
}
- if ( !artifactDir.isContainer() )
+ if ( !artifactDir.isContainer( ) )
{
throw new ContentNotFoundException(
- "Unable to get related artifacts using a non-directory: " + artifactDir.getPath() );
+ "Unable to get related artifacts using a non-directory: " + artifactDir.getPath( ) );
}
// First gather up the versions found as artifacts in the managed repository.
- try (Stream<? extends StorageAsset> stream = artifactDir.list().stream() ) {
- return stream.filter(asset -> !asset.isContainer()).map(path -> {
- try {
- ArtifactReference artifact = toArtifactReference(path.getPath());
- if( artifact.getGroupId().equals( reference.getGroupId() ) && artifact.getArtifactId().equals(
- reference.getArtifactId() ) && artifact.getVersion().equals( reference.getVersion() )) {
+ try ( Stream<? extends StorageAsset> stream = artifactDir.list( ).stream( ) )
+ {
+ return stream.filter( asset -> !asset.isContainer( ) ).map( path -> {
+ try
+ {
+ ArtifactReference artifact = toArtifactReference( path.getPath( ) );
+ if ( artifact.getGroupId( ).equals( reference.getGroupId( ) ) && artifact.getArtifactId( ).equals(
+ reference.getArtifactId( ) ) && artifact.getVersion( ).equals( reference.getVersion( ) ) )
+ {
return artifact;
- } else {
+ }
+ else
+ {
return null;
}
- } catch (LayoutException e) {
- log.debug( "Not processing file that is not an artifact: {}", e.getMessage() );
+ }
+ catch ( LayoutException e )
+ {
+ log.debug( "Not processing file that is not an artifact: {}", e.getMessage( ) );
return null;
}
- }).filter(Objects::nonNull).collect(Collectors.toList());
- } catch (RuntimeException e) {
+ } ).filter( Objects::nonNull ).collect( Collectors.toList( ) );
+ }
+ catch ( RuntimeException e )
+ {
Throwable cause = e.getCause( );
- if (cause!=null) {
- if (cause instanceof LayoutException) {
- throw (LayoutException)cause;
- } else
+ if ( cause != null )
+ {
+ if ( cause instanceof LayoutException )
+ {
+ throw (LayoutException) cause;
+ }
+ else
{
throw new ContentAccessException( cause.getMessage( ), cause );
}
- } else {
+ }
+ else
+ {
throw new ContentAccessException( e.getMessage( ), e );
}
}
@@ -1105,41 +1477,49 @@ public class ManagedDefaultRepositoryContent
/*
* Create the filter for various combinations of classifier and type
*/
- private Predicate<ArtifactReference> getChecker(ArtifactReference referenceObject, String extension) {
+ private Predicate<ArtifactReference> getChecker( ArtifactReference referenceObject, String extension )
+ {
// TODO: Check, if extension is the correct parameter here
// We compare type with extension which works for artifacts like .jar.md5 but may
// be not the best way.
- if (referenceObject.getClassifier()!=null && referenceObject.getType()!=null) {
- return ((ArtifactReference a) ->
- referenceObject.getGroupId().equals( a.getGroupId() )
- && referenceObject.getArtifactId().equals( a.getArtifactId() )
- && referenceObject.getVersion( ).equals( a.getVersion( ) )
- && ( (a.getType()==null)
- || referenceObject.getType().equals( a.getType() )
- || a.getType().startsWith(extension) )
- && referenceObject.getClassifier().equals( a.getClassifier() )
+ if ( referenceObject.getClassifier( ) != null && referenceObject.getType( ) != null )
+ {
+ return ( ( ArtifactReference a ) ->
+ referenceObject.getGroupId( ).equals( a.getGroupId( ) )
+ && referenceObject.getArtifactId( ).equals( a.getArtifactId( ) )
+ && referenceObject.getVersion( ).equals( a.getVersion( ) )
+ && ( ( a.getType( ) == null )
+ || referenceObject.getType( ).equals( a.getType( ) )
+ || a.getType( ).startsWith( extension ) )
+ && referenceObject.getClassifier( ).equals( a.getClassifier( ) )
);
- } else if (referenceObject.getClassifier()!=null && referenceObject.getType()==null){
- return ((ArtifactReference a) ->
- referenceObject.getGroupId().equals( a.getGroupId() )
- && referenceObject.getArtifactId().equals( a.getArtifactId() )
+ }
+ else if ( referenceObject.getClassifier( ) != null && referenceObject.getType( ) == null )
+ {
+ return ( ( ArtifactReference a ) ->
+ referenceObject.getGroupId( ).equals( a.getGroupId( ) )
+ && referenceObject.getArtifactId( ).equals( a.getArtifactId( ) )
&& referenceObject.getVersion( ).equals( a.getVersion( ) )
- && referenceObject.getClassifier().equals( a.getClassifier() )
+ && referenceObject.getClassifier( ).equals( a.getClassifier( ) )
);
- } else if (referenceObject.getClassifier()==null && referenceObject.getType()!=null){
- return ((ArtifactReference a) ->
- referenceObject.getGroupId().equals( a.getGroupId() )
- && referenceObject.getArtifactId().equals( a.getArtifactId() )
+ }
+ else if ( referenceObject.getClassifier( ) == null && referenceObject.getType( ) != null )
+ {
+ return ( ( ArtifactReference a ) ->
+ referenceObject.getGroupId( ).equals( a.getGroupId( ) )
+ && referenceObject.getArtifactId( ).equals( a.getArtifactId( ) )
&& referenceObject.getVersion( ).equals( a.getVersion( ) )
- && ( (a.getType()==null)
- || referenceObject.getType().equals( a.getType() )
- || a.getType().startsWith(extension) )
+ && ( ( a.getType( ) == null )
+ || referenceObject.getType( ).equals( a.getType( ) )
+ || a.getType( ).startsWith( extension ) )
);
- } else {
- return ((ArtifactReference a) ->
- referenceObject.getGroupId().equals( a.getGroupId() )
- && referenceObject.getArtifactId().equals( a.getArtifactId() )
+ }
+ else
+ {
+ return ( ( ArtifactReference a ) ->
+ referenceObject.getGroupId( ).equals( a.getGroupId( ) )
+ && referenceObject.getArtifactId( ).equals( a.getArtifactId( ) )
&& referenceObject.getVersion( ).equals( a.getVersion( ) )
);
}
@@ -1148,23 +1528,29 @@ public class ManagedDefaultRepositoryContent
}
@Override
- public String getRepoRoot()
+ public String getRepoRoot( )
{
- return convertUriToPath( repository.getLocation() );
+ return convertUriToPath( repository.getLocation( ) );
}
- private String convertUriToPath( URI uri ) {
- if (uri.getScheme()==null) {
- return Paths.get(uri.getPath()).toString();
- } else if ("file".equals(uri.getScheme())) {
- return Paths.get(uri).toString();
- } else {
- return uri.toString();
+ private String convertUriToPath( URI uri )
+ {
+ if ( uri.getScheme( ) == null )
+ {
+ return Paths.get( uri.getPath( ) ).toString( );
+ }
+ else if ( "file".equals( uri.getScheme( ) ) )
+ {
+ return Paths.get( uri ).toString( );
+ }
+ else
+ {
+ return uri.toString( );
}
}
@Override
- public ManagedRepository getRepository()
+ public ManagedRepository getRepository( )
{
return repository;
}
@@ -1173,7 +1559,7 @@ public class ManagedDefaultRepositoryContent
public boolean hasContent( ArtifactReference reference ) throws ContentAccessException
{
StorageAsset artifactFile = toFile( reference );
- return artifactFile.exists() && !artifactFile.isContainer();
+ return artifactFile.exists( ) && !artifactFile.isContainer( );
}
@Override
@@ -1190,7 +1576,7 @@ public class ManagedDefaultRepositoryContent
catch ( IOException e )
{
String path = toPath( reference );
- log.error("Could not read directory from repository {} - {}: ", getId(), path, e.getMessage(), e);
+ log.error( "Could not read directory from repository {} - {}: ", getId( ), path, e.getMessage( ), e );
throw new ContentAccessException( "Could not read path from repository " + getId( ) + ": " + path, e );
}
}
@@ -1199,18 +1585,22 @@ public class ManagedDefaultRepositoryContent
public void setRepository( final ManagedRepository repo )
{
this.repository = repo;
- if (repo!=null) {
- if (repository instanceof EditableManagedRepository) {
- ((EditableManagedRepository) repository).setContent(this);
+ if ( repo != null )
+ {
+ if ( repository instanceof EditableManagedRepository )
+ {
+ ( (EditableManagedRepository) repository ).setContent( this );
}
}
}
- private Path getRepoDir() {
+ private Path getRepoDir( )
+ {
return repository.getAsset( "" ).getFilePath( );
}
- private RepositoryStorage getStorage() {
+ private RepositoryStorage getStorage( )
+ {
return repository.getAsset( "" ).getStorage( );
}
@@ -1224,15 +1614,19 @@ public class ManagedDefaultRepositoryContent
public ArtifactReference toArtifactReference( String path )
throws LayoutException
{
- String repoPath = convertUriToPath( repository.getLocation() );
- if ( ( path != null ) && path.startsWith( repoPath ) && repoPath.length() > 0 )
+ String repoPath = convertUriToPath( repository.getLocation( ) );
+ if ( ( path != null ) && path.startsWith( repoPath ) && repoPath.length( ) > 0 )
+ {
+ return super.toArtifactReference( path.substring( repoPath.length( ) + 1 ) );
+ }
+ else
{
- return super.toArtifactReference( path.substring( repoPath.length() + 1 ) );
- } else {
repoPath = path;
- if (repoPath!=null) {
- while (repoPath.startsWith("/")) {
- repoPath = repoPath.substring(1);
+ if ( repoPath != null )
+ {
+ while ( repoPath.startsWith( "/" ) )
+ {
+ repoPath = repoPath.substring( 1 );
}
}
return super.toArtifactReference( repoPath );
@@ -1241,20 +1635,23 @@ public class ManagedDefaultRepositoryContent
// The variant with runtime exception for stream usage
- private ArtifactReference toArtifactRef(String path) {
- try {
- return toArtifactReference(path);
- } catch (LayoutException e) {
- throw new RuntimeException(e);
+ private ArtifactReference toArtifactRef( String path )
+ {
+ try
+ {
+ return toArtifactReference( path );
+ }
+ catch ( LayoutException e )
+ {
+ throw new RuntimeException( e );
}
}
-
@Override
public StorageAsset toFile( ArtifactReference reference )
{
- return repository.getAsset(toPath(reference));
+ return repository.getAsset( toPath( reference ) );
}
@Override
@@ -1274,52 +1671,56 @@ public class ManagedDefaultRepositoryContent
*
* @param reference the reference to the versioned reference to search within
* @return the ArtifactReference to the first artifact located within the versioned reference. or null if
- * no artifact was found within the versioned reference.
- * @throws java.io.IOException if the versioned reference is invalid (example: doesn't exist, or isn't a directory)
+ * no artifact was found within the versioned reference.
+ * @throws java.io.IOException if the versioned reference is invalid (example: doesn't exist, or isn't a directory)
* @throws LayoutException
*/
private ArtifactReference getFirstArtifact( VersionedReference reference )
throws ContentNotFoundException, LayoutException, IOException
{
- try(Stream<ArtifactReference> stream = newArtifactStream( reference ))
+ try ( Stream<ArtifactReference> stream = newArtifactStream( reference ) )
{
return stream.findFirst( ).orElse( null );
- } catch (RuntimeException e) {
+ }
+ catch ( RuntimeException e )
+ {
throw new ContentNotFoundException( e.getMessage( ), e.getCause( ) );
}
}
- private Stream<ArtifactReference> newArtifactStream( VersionedReference reference) throws ContentNotFoundException, LayoutException, IOException {
+ private Stream<ArtifactReference> newArtifactStream( VersionedReference reference ) throws ContentNotFoundException, LayoutException, IOException
+ {
final Path repoBase = getRepoDir( );
String path = toMetadataPath( reference );
- Path versionDir = repoBase.resolve( path ).getParent();
- if ( !Files.exists(versionDir) )
+ Path versionDir = repoBase.resolve( path ).getParent( );
+ if ( !Files.exists( versionDir ) )
{
throw new ContentNotFoundException( "Unable to gather the list of artifacts on a non-existant directory: "
- + versionDir.toAbsolutePath() );
+ + versionDir.toAbsolutePath( ) );
}
- if ( !Files.isDirectory(versionDir) )
+ if ( !Files.isDirectory( versionDir ) )
{
throw new ContentNotFoundException(
- "Unable to gather the list of snapshot versions on a non-directory: " + versionDir.toAbsolutePath() );
+ "Unable to gather the list of snapshot versions on a non-directory: " + versionDir.toAbsolutePath( ) );
}
- return Files.list(versionDir).filter(Files::isRegularFile)
- .map(p -> repoBase.relativize(p).toString())
- .filter(p -> !filetypes.matchesDefaultExclusions(p))
- .filter(filetypes::matchesArtifactPattern)
- .map(this::toArtifactRef);
+ return Files.list( versionDir ).filter( Files::isRegularFile )
+ .map( p -> repoBase.relativize( p ).toString( ) )
+ .filter( p -> !filetypes.matchesDefaultExclusions( p ) )
+ .filter( filetypes::matchesArtifactPattern )
+ .map( this::toArtifactRef );
}
- public List<ArtifactReference> getArtifacts(VersionedReference reference) throws ContentNotFoundException, LayoutException, ContentAccessException
+ public List<ArtifactReference> getArtifacts( VersionedReference reference ) throws ContentNotFoundException, LayoutException, ContentAccessException
{
- try (Stream<ArtifactReference> stream = newArtifactStream( reference ))
+ try ( Stream<ArtifactReference> stream = newArtifactStream( reference ) )
{
return stream.collect( Collectors.toList( ) );
- } catch ( IOException e )
+ }
+ catch ( IOException e )
{
String path = toPath( reference );
- log.error("Could not read directory from repository {} - {}: ", getId(), path, e.getMessage(), e);
+ log.error( "Could not read directory from repository {} - {}: ", getId( ), path, e.getMessage( ), e );
throw new ContentAccessException( "Could not read path from repository " + getId( ) + ": " + path, e );
}
@@ -1328,14 +1729,18 @@ public class ManagedDefaultRepositoryContent
private boolean hasArtifact( VersionedReference reference )
{
- try(Stream<ArtifactReference> stream = newArtifactStream( reference ))
+ try ( Stream<ArtifactReference> stream = newArtifactStream( reference ) )
{
return stream.anyMatch( e -> true );
- } catch (ContentNotFoundException e) {
+ }
+ catch ( ContentNotFoundException e )
+ {
return false;
- } catch ( LayoutException | IOException e) {
+ }
+ catch ( LayoutException | IOException e )
+ {
// We throw the runtime exception for better stream handling
- throw new RuntimeException(e);
+ throw new RuntimeException( e );
}
}
@@ -1344,9 +1749,19 @@ public class ManagedDefaultRepositoryContent
this.filetypes = filetypes;
}
- public void setMavenContentHelper( MavenContentHelper contentHelper) {
+ public void setMavenContentHelper( MavenContentHelper contentHelper )
+ {
this.mavenContentHelper = contentHelper;
}
+ public MavenMetadataReader getMetadataReader( )
+ {
+ return metadataReader;
+ }
+
+ public void setMetadataReader( MavenMetadataReader metadataReader )
+ {
+ this.metadataReader = metadataReader;
+ }
}
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContentTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContentTest.java
index 05e45f99a..03bcb0282 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContentTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContentTest.java
@@ -23,6 +23,7 @@ import org.apache.archiva.common.utils.VersionComparator;
import org.apache.archiva.configuration.ArchivaConfiguration;
import org.apache.archiva.configuration.FileType;
import org.apache.archiva.configuration.FileTypes;
+import org.apache.archiva.metadata.maven.MavenMetadataReader;
import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.model.ProjectReference;
import org.apache.archiva.model.VersionedReference;
@@ -34,17 +35,20 @@ import org.apache.archiva.repository.RepositoryContent;
import org.apache.archiva.repository.content.Artifact;
import org.apache.archiva.repository.content.BaseArtifactTypes;
import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.DataItem;
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.ArchivaContentItem;
+import org.apache.archiva.repository.content.base.ArchivaDataItem;
import org.apache.archiva.repository.content.base.ArchivaItemSelector;
import org.apache.archiva.repository.maven.MavenManagedRepository;
import org.apache.archiva.repository.maven.metadata.storage.ArtifactMappingProvider;
+import org.apache.archiva.repository.metadata.MetadataReader;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
import org.junit.Test;
@@ -59,11 +63,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileTime;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
-import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -91,6 +91,10 @@ public class ManagedDefaultRepositoryContentTest
MavenContentHelper contentHelper;
@Inject
+ @Named( "metadataReader#maven" )
+ MavenMetadataReader metadataReader;
+
+ @Inject
FileLockManager fileLockManager;
private Path getRepositoryPath(String repoName) {
@@ -120,6 +124,7 @@ public class ManagedDefaultRepositoryContentTest
repoContent = new ManagedDefaultRepositoryContent(repository, artifactMappingProviders, fileTypes, fileLockManager);
repoContent.setMavenContentHelper( contentHelper );
+ repoContent.setMetadataReader( metadataReader );
//repoContent = (ManagedRepositoryContent) lookup( ManagedRepositoryContent.class, "default" );
}
@@ -128,7 +133,7 @@ public class ManagedDefaultRepositoryContentTest
public void testGetVersionsSnapshotA()
throws Exception
{
- assertVersions( "snap_shots_a", "1.0-alpha-11-SNAPSHOT",
+ assertArtifactVersions( "snap_shots_a", "1.0-alpha-11-SNAPSHOT",
new String[]{ "1.0-alpha-11-SNAPSHOT", "1.0-alpha-11-20070221.194724-2",
"1.0-alpha-11-20070302.212723-3", "1.0-alpha-11-20070303.152828-4",
"1.0-alpha-11-20070305.215149-5", "1.0-alpha-11-20070307.170909-6",
@@ -205,6 +210,31 @@ public class ManagedDefaultRepositoryContentTest
}
+ private void assertArtifactVersions( String artifactId, String version, String[] expectedVersions )
+ throws Exception
+ {
+ // Use the test metadata-repository, which is already setup for
+ // These kind of version tests.
+ Path repoDir = getRepositoryPath( "metadata-repository" );
+ ((EditableManagedRepository)repoContent.getRepository()).setLocation( repoDir.toAbsolutePath().toUri() );
+
+ // Request the versions.
+
+ // Sort the list (for asserts later)
+ final VersionComparator comparator = new VersionComparator( );
+
+ ItemSelector selector = ArchivaItemSelector.builder( )
+ .withNamespace( "org.apache.archiva.metadata.tests" )
+ .withProjectId( artifactId )
+ .withVersion( version )
+ .build( );
+ List<String> versions = repoContent.getArtifactVersions( selector ).stream()
+ .sorted( comparator ).collect( Collectors.toList());
+ assertArrayEquals( expectedVersions, versions.toArray( ) );
+
+
+ }
+
@Test
public void getTestGetProjectWithIllegalArgs() {
ItemSelector selector = ArchivaItemSelector.builder( )
@@ -558,10 +588,10 @@ public class ManagedDefaultRepositoryContentTest
assertEquals( 2, results.size( ) );
Artifact mainArtifact = results.stream( ).filter( a -> a.getFileName( ).equals( "jdbc-2.0.jar" ) ).findFirst( ).get( );
assertNotNull( mainArtifact );
- assertEquals( BaseArtifactTypes.MAIN, mainArtifact.getArtifactType( ) );
+ assertEquals( BaseArtifactTypes.MAIN, mainArtifact.getDataType( ) );
Artifact metaArtifact = results.stream( ).filter( a -> a.getFileName( ).equals( "maven-metadata-repository.xml" ) ).findFirst( ).get( );
assertNotNull( metaArtifact );
- assertEquals( MavenTypes.REPOSITORY_METADATA, metaArtifact.getArtifactType( ) );
+ assertEquals( MavenTypes.REPOSITORY_METADATA, metaArtifact.getDataType( ) );
}
@Test
@@ -598,7 +628,7 @@ public class ManagedDefaultRepositoryContentTest
assertNotNull( artifact );
assertEquals( "pom", artifact.getExtension( ) );
- assertEquals( BaseArtifactTypes.MAIN, artifact.getArtifactType( ) );
+ assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) );
assertEquals( "1.3-SNAPSHOT", artifact.getVersion( ).getVersion( ) );
assertEquals( "1.3-20070725.210059-1", artifact.getArtifactVersion( ) );
assertEquals( ".pom", artifact.getRemainder( ) );
@@ -614,7 +644,7 @@ public class ManagedDefaultRepositoryContentTest
assertNotNull( artifact );
assertEquals( "md5", artifact.getExtension( ) );
- assertEquals( BaseArtifactTypes.RELATED, artifact.getArtifactType( ) );
+ assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) );
assertEquals( "1.3-SNAPSHOT", artifact.getVersion( ).getVersion( ) );
assertEquals( "1.3-20070725.210059-1", artifact.getArtifactVersion( ) );
assertEquals( ".pom.md5", artifact.getRemainder( ) );
@@ -629,7 +659,7 @@ public class ManagedDefaultRepositoryContentTest
artifact = results.stream( ).filter( a -> a.getFileName( ).equals( "maven-metadata.xml" ) )
.findFirst( ).get( );
assertNotNull( artifact );
- assertEquals( BaseArtifactTypes.METADATA, artifact.getArtifactType( ) );
+ assertEquals( BaseArtifactTypes.METADATA, artifact.getDataType( ) );
assertEquals( "1.3-SNAPSHOT", artifact.getVersion( ).getVersion( ) );
assertEquals( "xml", artifact.getExtension( ) );
}
@@ -668,7 +698,7 @@ public class ManagedDefaultRepositoryContentTest
assertEquals( 1, results.size( ) );
Artifact artifact = results.get( 0 );
assertEquals( "pom", artifact.getExtension( ) );
- assertEquals( BaseArtifactTypes.MAIN, artifact.getArtifactType( ) );
+ assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) );
}
@Test
@@ -711,13 +741,13 @@ public class ManagedDefaultRepositoryContentTest
.findFirst( ).get( );
assertNotNull( artifact );
assertEquals( "pom", artifact.getExtension( ) );
- assertEquals( BaseArtifactTypes.MAIN, artifact.getArtifactType( ) );
+ assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) );
artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "axis2-1.3-20070731.113304-21.pom.sha1" ) )
.findFirst( ).get( );
assertNotNull( artifact );
assertEquals( "sha1", artifact.getExtension( ) );
- assertEquals( BaseArtifactTypes.RELATED, artifact.getArtifactType( ) );
+ assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) );
}
@@ -752,19 +782,19 @@ public class ManagedDefaultRepositoryContentTest
.findFirst( ).get( );
assertNotNull( artifact );
assertEquals( "xml", artifact.getExtension( ) );
- assertEquals( BaseArtifactTypes.METADATA, artifact.getArtifactType( ) );
+ assertEquals( BaseArtifactTypes.METADATA, artifact.getDataType( ) );
artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "maven-downloader-1.0-sources.jar" ) )
.findFirst( ).get( );
assertNotNull( artifact );
- assertEquals( BaseArtifactTypes.MAIN, artifact.getArtifactType( ) );
+ assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) );
assertEquals( "sources", artifact.getClassifier( ) );
assertEquals( "java-source", artifact.getType( ) );
artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "maven-downloader-1.0-sources.jar.sha1" ) )
.findFirst( ).get( );
assertNotNull( artifact );
- assertEquals( BaseArtifactTypes.RELATED, artifact.getArtifactType( ) );
+ assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) );
assertEquals( "sources", artifact.getClassifier( ) );
assertEquals( "sha1", artifact.getType( ) );
assertEquals( ".jar.sha1", artifact.getRemainder( ) );
@@ -994,6 +1024,59 @@ public class ManagedDefaultRepositoryContentTest
assertNotNull( artifact );
}
+
+ @Test
+ public void testNewItemStreamWithNamespace1() {
+ ItemSelector selector = ArchivaItemSelector.builder( )
+ .withNamespace( "org.apache.axis2" )
+ .build();
+
+ Stream<? extends ContentItem> stream = repoContent.newItemStream( selector, false );
+ List<? extends ContentItem> result = stream.collect( Collectors.toList( ) );
+ assertEquals( 41, result.size( ) );
+ ContentItem item = result.get( 39 );
+ Version version = item.adapt( Version.class );
+ assertNotNull( version );
+ assertEquals( "1.3-SNAPSHOT", version.getVersion( ) );
+ Project project = result.get( 40 ).adapt( Project.class );
+ assertNotNull( project );
+ assertEquals( "axis2", project.getId( ) );
+ assertTrue( result.stream( ).anyMatch( a -> "axis2-1.3-20070725.210059-1.pom".equals( a.getAsset( ).getName( ) ) ) );
+ }
+
+// @Test
+// public void testNewItemStreamWithNamespace2() {
+// ItemSelector selector = ArchivaItemSelector.builder( )
+// .withNamespace( "org.apache.maven" )
+// .build();
+//
+// Stream<? extends ContentItem> stream = repoContent.newItemStream( selector, false );
+// List<? extends ContentItem> result = stream.collect( Collectors.toList( ) );
+// int versions = 0;
+// int projects = 0;
+// int artifacts = 0;
+// int namespaces = 0;
+// int dataitems = 0;
+// for (int i=0; i<result.size(); i++) {
+// ContentItem ci = result.get( i );
+// System.out.println( i + ": " + result.get( i ) + " - " +result.get(i).getClass().getName() + " - " + result.get(i).getAsset().getPath() );
+// if (ci instanceof Version) {
+// versions++;
+// } else if (ci instanceof Project) {
+// projects++;
+// } else if (ci instanceof Namespace) {
+// namespaces++;
+// } else if (ci instanceof Artifact) {
+// artifacts++;
+// } else if (ci instanceof DataItem ) {
+// dataitems++;
+// }
+// }
+// System.out.println( "namespaces=" + namespaces + ", projects=" + projects + ", versions=" + versions + ", artifacts=" + artifacts + ", dataitems=" + dataitems );
+// assertEquals( 170, result.size( ) );
+// assertEquals( 92, result.stream( ).filter( a -> a instanceof Artifact ).count( ) );
+// }
+
@Test
public void testGetArtifactFromContentItem() {
ItemSelector selector = ArchivaItemSelector.builder( )
@@ -1053,17 +1136,17 @@ public class ManagedDefaultRepositoryContentTest
String path = "/org/apache/maven/shared";
ContentItem item = repoContent.toItem( path );
assertNotNull( item );
- assertTrue( item instanceof Namespace );
+ assertTrue( item instanceof ArchivaContentItem );
path = "/org/apache/maven/shared/maven-downloader";
item = repoContent.toItem( path );
assertNotNull( item );
- assertTrue( item instanceof Project );
+ assertTrue( item instanceof ArchivaContentItem );
path = "/org/apache/maven/shared/maven-downloader/1.1";
item = repoContent.toItem( path );
assertNotNull( item );
- assertTrue( item instanceof Version );
+ assertTrue( item instanceof ArchivaContentItem );
path = "/org/apache/maven/shared/maven-downloader/1.1/maven-downloader-1.1.jar";
item = repoContent.toItem( path );
@@ -1078,22 +1161,22 @@ public class ManagedDefaultRepositoryContentTest
StorageAsset path = repoContent.getRepository().getAsset("/org/apache/maven/shared");
ContentItem item = repoContent.toItem( path );
assertNotNull( item );
- assertTrue( item instanceof Namespace );
+ assertTrue( item instanceof ArchivaContentItem );
path = repoContent.getRepository( ).getAsset( "/org/apache/maven/shared/maven-downloader" );
item = repoContent.toItem( path );
assertNotNull( item );
- assertTrue( item instanceof Project );
+ assertTrue( item instanceof ArchivaContentItem );
path = repoContent.getRepository( ).getAsset( "/org/apache/maven/shared/maven-downloader/1.1" );
item = repoContent.toItem( path );
assertNotNull( item );
- assertTrue( item instanceof Version );
+ assertTrue( item instanceof ArchivaContentItem );
path = repoContent.getRepository( ).getAsset( "/org/apache/maven/shared/maven-downloader/1.1/maven-downloader-1.1.jar" );
item = repoContent.toItem( path );
assertNotNull( item );
- assertTrue( item instanceof Artifact );
+ assertTrue( item instanceof DataItem );
}
@@ -1197,18 +1280,18 @@ public class ManagedDefaultRepositoryContentTest
Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "samplejar-1.0.jar" ) )
.findFirst().get();
assertNotNull( artifact );
- assertEquals( BaseArtifactTypes.MAIN, artifact.getArtifactType( ) );
+ assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) );
artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "samplejar-1.0.jar.md5" ) )
.findFirst().get();
assertNotNull( artifact );
- assertEquals( BaseArtifactTypes.RELATED, artifact.getArtifactType( ) );
+ assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) );
assertEquals( "md5", artifact.getExtension( ) );
artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "samplejar-1.0.jar.sha1" ) )
.findFirst().get();
assertNotNull( artifact );
- assertEquals( BaseArtifactTypes.RELATED, artifact.getArtifactType( ) );
+ assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) );
assertEquals( "sha1", artifact.getExtension( ) );
}
@@ -1546,4 +1629,5 @@ public class ManagedDefaultRepositoryContentTest
assertTrue( new String( content ).startsWith( "test.test.test" ) );
}
+
}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java
index 8d0a77b08..6c0f7c124 100644
--- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java
@@ -52,6 +52,7 @@ import org.apache.archiva.repository.RepositoryNotFoundException;
import org.apache.archiva.repository.RepositoryRegistry;
import org.apache.archiva.repository.RepositoryType;
import org.apache.archiva.repository.content.ItemNotFoundException;
+import org.apache.archiva.repository.content.Version;
import org.apache.archiva.repository.content.base.ArchivaItemSelector;
import org.apache.archiva.repository.storage.fs.FsStorageUtil;
import org.apache.archiva.repository.storage.RepositoryStorage;
@@ -663,28 +664,19 @@ public class DefaultRepositoriesService
{
ManagedRepositoryContent repository = getManagedRepositoryContent( repositoryId );
- VersionedReference ref = new VersionedReference();
- ref.setArtifactId( projectId );
- ref.setGroupId( namespace );
- ref.setVersion( version );
-
- repository.deleteVersion( ref );
-
- ArtifactReference artifactReference = new ArtifactReference();
- artifactReference.setGroupId( namespace );
- artifactReference.setArtifactId( projectId );
- artifactReference.setVersion( version );
+ ArchivaItemSelector selector = ArchivaItemSelector.builder( )
+ .withNamespace( namespace )
+ .withProjectId( projectId )
+ .withVersion( version )
+ .build( );
+ Version versionItem = repository.getVersion( selector );
+ if (versionItem!=null && versionItem.exists()) {
+ repository.deleteItem( versionItem );
+ }
MetadataRepository metadataRepository = repositorySession.getRepository();
- List<ArtifactReference> related = repository.getRelatedArtifacts( repository.toVersion(artifactReference) );
- log.debug( "related: {}", related );
- for ( ArtifactReference artifactRef : related )
- {
- repository.deleteArtifact( artifactRef );
- }
-
Collection<ArtifactMetadata> artifacts =
metadataRepository.getArtifacts(repositorySession , repositoryId, namespace, projectId, version );
@@ -695,7 +687,7 @@ public class DefaultRepositoriesService
metadataRepository.removeProjectVersion(repositorySession , repositoryId, namespace, projectId, version );
}
- catch ( MetadataRepositoryException | MetadataResolutionException | RepositoryException | LayoutException e )
+ catch ( MetadataRepositoryException | MetadataResolutionException | RepositoryException | ItemNotFoundException e )
{
throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
}