This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git

commit 2257aae023b20646e0b34369be24f5fc1718750f
Author: Martin Stockhammer <[email protected]>
AuthorDate: Mon Jun 1 14:03:03 2020 +0200

    Repository content refactoring
---
 .../repository/BaseRepositoryContentLayout.java    |  27 ++----
 .../repository/ManagedRepositoryContent.java       |   3 +-
 .../repository/ManagedRepositoryContentLayout.java |  19 ++++
 .../mock/ManagedRepositoryContentMock.java         |  94 ++++++++++++++----
 .../scanner/mock/ManagedRepositoryContentMock.java |  87 ++++++++++++-----
 .../apache/archiva/proxy/MetadataTransferTest.java |  30 ++++--
 .../mock/ManagedRepositoryContentMock.java         | 106 +++++++++++++++------
 .../content/AbstractDefaultRepositoryContent.java  |   2 +-
 .../content/ManagedDefaultRepositoryContent.java   |  40 ++++++++
 .../ManagedDefaultRepositoryContentTest.java       |  25 +++++
 .../rest/services/DefaultRepositoriesService.java  |  25 +++--
 11 files changed, 355 insertions(+), 103 deletions(-)

diff --git 
a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/BaseRepositoryContentLayout.java
 
b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/BaseRepositoryContentLayout.java
index 0d8e902..e08ed3c 100644
--- 
a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/BaseRepositoryContentLayout.java
+++ 
b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/BaseRepositoryContentLayout.java
@@ -25,6 +25,7 @@ import org.apache.archiva.model.ProjectReference;
 import org.apache.archiva.model.VersionedReference;
 import org.apache.archiva.repository.content.Artifact;
 import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.DataItem;
 import org.apache.archiva.repository.content.ItemNotFoundException;
 import org.apache.archiva.repository.content.ItemSelector;
 import org.apache.archiva.repository.content.Namespace;
@@ -48,6 +49,7 @@ public interface BaseRepositoryContentLayout extends 
RepositoryContent, ManagedR
     /// *****************   New generation interface **********************
 
 
+
     /**
      * Returns the namespace for the given selected coordinates. The selector 
must specify a namespace. All other
      * coordinates are ignored.
@@ -248,6 +250,14 @@ public interface BaseRepositoryContentLayout extends 
RepositoryContent, ManagedR
      */
     void addArtifact( Path sourceFile, Artifact destination ) throws 
IllegalArgumentException, ContentAccessException;
 
+    /**
+     * Returns the metadata file for the given version.
+     *
+     * @param version the version
+     * @return the metadata file
+     */
+    DataItem getMetadataItem( Version version );
+
 
     /// *****************   End of new generation interface 
**********************
 
@@ -419,22 +429,5 @@ public interface BaseRepositoryContentLayout extends 
RepositoryContent, ManagedR
      */
     String toMetadataPath( ProjectReference reference );
 
-    /**
-     * Given a {@link VersionedReference}, return the path to the metadata for
-     * the specific version of the project.
-     *
-     * @param reference the reference to use.
-     * @return the path to the metadata file, or null if no metadata is 
appropriate.
-     */
-    String toMetadataPath( VersionedReference reference );
-
-    /**
-     * Given an {@link ArchivaArtifact}, return the relative path to the 
artifact.
-     *
-     * @param reference the archiva artifact to use.
-     * @return the relative path to the artifact.
-     */
-    String toPath( ArchivaArtifact reference );
-
 
 }
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 69364af..f4ad5af 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
@@ -30,7 +30,7 @@ import java.util.stream.Stream;
 /**
  * @author Martin Stockhammer <[email protected]>
  */
-public interface ManagedRepositoryContent
+public interface ManagedRepositoryContent extends RepositoryContent
 {
 
 
@@ -43,7 +43,6 @@ public interface ManagedRepositoryContent
     String toPath( ContentItem item );
 
 
-
     /**
      * <p>
      * Convenience method to get the repository id.
diff --git 
a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/ManagedRepositoryContentLayout.java
 
b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/ManagedRepositoryContentLayout.java
index e64f8b2..3bc4736 100644
--- 
a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/ManagedRepositoryContentLayout.java
+++ 
b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/ManagedRepositoryContentLayout.java
@@ -18,6 +18,9 @@ package org.apache.archiva.repository;
  * under the License.
  */
 
+import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.DataItem;
+
 /**
  *
  * Basic interface for content layouts.
@@ -28,5 +31,21 @@ package org.apache.archiva.repository;
  */
 public interface ManagedRepositoryContentLayout
 {
+
+    /**
+     * Returns the repository content, that this layout is attached to.
+     * @return the content instance
+     */
     ManagedRepositoryContent getGenericContent();
+
+    /**
+     * Adapts a generic content item to a specific implementation class.
+     *
+     * @param clazz the target implementation
+     * @param item the content item
+     * @param <T> the target class
+     * @return the adapted instance
+     * @throws LayoutException if the conversion is not possible
+     */
+    <T extends ContentItem> T adaptItem( Class<T> clazz, ContentItem item ) 
throws LayoutException;
 }
diff --git 
a/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java
 
b/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java
index 95ec2aa..bc4569a 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
@@ -32,12 +32,19 @@ import org.apache.archiva.repository.ManagedRepository;
 import org.apache.archiva.repository.BaseRepositoryContentLayout;
 import org.apache.archiva.repository.ManagedRepositoryContentLayout;
 import org.apache.archiva.repository.content.Artifact;
+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.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.ArchivaNamespace;
+import org.apache.archiva.repository.content.base.ArchivaProject;
+import org.apache.archiva.repository.content.base.ArchivaVersion;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.springframework.stereotype.Service;
 
@@ -73,6 +80,52 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
     }
 
     @Override
+    public <T extends ContentItem> T adaptItem( Class<T> clazz, ContentItem 
item ) throws LayoutException
+    {
+        if (clazz.isAssignableFrom( Version.class ))
+        {
+            if ( !item.hasCharacteristic( Version.class ) )
+            {
+                item.setCharacteristic( Version.class, createVersionFromPath( 
item.getAsset() ) );
+            }
+            return (T) item.adapt( Version.class );
+        } else if ( clazz.isAssignableFrom( Project.class )) {
+            if ( !item.hasCharacteristic( Project.class ) )
+            {
+                item.setCharacteristic( Project.class, createProjectFromPath( 
item.getAsset() ) );
+            }
+            return (T) item.adapt( Project.class );
+        } else if ( clazz.isAssignableFrom( Namespace.class )) {
+            if ( !item.hasCharacteristic( Namespace.class ) )
+            {
+                item.setCharacteristic( Namespace.class, 
createNamespaceFromPath( item.getAsset() ) );
+            }
+            return (T) item.adapt( Namespace.class );
+        }
+        throw new LayoutException( "Could not convert item to class " + clazz);
+    }
+
+    private Version createVersionFromPath( StorageAsset asset )
+    {
+        Project proj = createProjectFromPath( asset.getParent( ) );
+        return ArchivaVersion.withRepository( this ).withAsset( asset )
+            .withProject( proj ).withVersion( asset.getName( ) ).build();
+    }
+
+    private Project createProjectFromPath( StorageAsset asset)  {
+        Namespace ns = createNamespaceFromPath( asset );
+        return ArchivaProject.withRepository( this ).withAsset( asset )
+            .withNamespace( ns ).withId( asset.getName( ) ).build( );
+    }
+
+    private Namespace createNamespaceFromPath( StorageAsset asset) {
+        String namespace = asset.getPath( ).replace( "/", "." );
+        return ArchivaNamespace.withRepository( this )
+            .withAsset( asset ).withNamespace( namespace ).build();
+    }
+
+
+    @Override
     public void deleteItem( ContentItem item ) throws ItemNotFoundException, 
ContentAccessException
     {
 
@@ -192,7 +245,14 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
     @Override
     public ContentItem getParent( ContentItem item )
     {
-        return null;
+        try
+        {
+            return toItem( item.getAsset( ).getParent( ) );
+        }
+        catch ( LayoutException e )
+        {
+            throw new RuntimeException( "Bad layout error " + e.getMessage( ) 
);
+        }
     }
 
     @Override
@@ -226,15 +286,29 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
     }
 
     @Override
+    public DataItem getMetadataItem( Version version )
+    {
+        return ArchivaDataItem.withAsset( version.getAsset( ).resolve( 
"maven-metadata.xml" ) ).withId( "maven-metadata.xml" )
+            .withDataType( BaseDataItemTypes.METADATA ).build();
+    }
+
+    @Override
     public ContentItem toItem( String path ) throws LayoutException
     {
-        return null;
+        StorageAsset asset = repository.getAsset( "" ).resolve( path );
+        return toItem( asset );
     }
 
     @Override
-    public ContentItem toItem( StorageAsset assetPath ) throws LayoutException
+    public ContentItem toItem( StorageAsset asset ) throws LayoutException
     {
-        return null;
+        if (asset.isLeaf()) {
+            return ArchivaDataItem.withAsset( asset ).withId( asset.getName() 
).build();
+        } else
+        {
+            return ArchivaContentItem.withRepository( this )
+                .withAsset( asset ).build( );
+        }
     }
 
 
@@ -342,12 +416,6 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
     }
 
     @Override
-    public String toMetadataPath( VersionedReference reference )
-    {
-        return null;
-    }
-
-    @Override
     public String toPath( ArtifactReference reference )
     {
         return null;
@@ -366,12 +434,6 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
     }
 
     @Override
-    public String toPath( ArchivaArtifact reference )
-    {
-        return null;
-    }
-
-    @Override
     public ManagedRepositoryContent getGenericContent( )
     {
         return null;
diff --git 
a/archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/mock/ManagedRepositoryContentMock.java
 
b/archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/mock/ManagedRepositoryContentMock.java
index 7ef1183..89f5169 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
@@ -30,11 +30,15 @@ import org.apache.archiva.model.VersionedReference;
 import org.apache.archiva.repository.*;
 import org.apache.archiva.repository.content.Artifact;
 import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.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.ArchivaNamespace;
+import org.apache.archiva.repository.content.base.ArchivaProject;
+import org.apache.archiva.repository.content.base.ArchivaVersion;
 import org.apache.archiva.repository.storage.fs.FilesystemStorage;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.commons.lang3.StringUtils;
@@ -80,6 +84,52 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
     }
 
     @Override
+    public <T extends ContentItem> T adaptItem( Class<T> clazz, ContentItem 
item ) throws LayoutException
+    {
+        if (clazz.isAssignableFrom( Version.class ))
+        {
+            if ( !item.hasCharacteristic( Version.class ) )
+            {
+                item.setCharacteristic( Version.class, createVersionFromPath( 
item.getAsset() ) );
+            }
+            return (T) item.adapt( Version.class );
+        } else if ( clazz.isAssignableFrom( Project.class )) {
+            if ( !item.hasCharacteristic( Project.class ) )
+            {
+                item.setCharacteristic( Project.class, createProjectFromPath( 
item.getAsset() ) );
+            }
+            return (T) item.adapt( Project.class );
+        } else if ( clazz.isAssignableFrom( Namespace.class )) {
+            if ( !item.hasCharacteristic( Namespace.class ) )
+            {
+                item.setCharacteristic( Namespace.class, 
createNamespaceFromPath( item.getAsset() ) );
+            }
+            return (T) item.adapt( Namespace.class );
+        }
+        throw new LayoutException( "Could not convert item to class " + clazz);
+    }
+
+    private Version createVersionFromPath( StorageAsset asset )
+    {
+        Project proj = createProjectFromPath( asset.getParent( ) );
+        return ArchivaVersion.withRepository( this ).withAsset( asset )
+            .withProject( proj ).withVersion( asset.getName( ) ).build();
+    }
+
+    private Project createProjectFromPath( StorageAsset asset)  {
+        Namespace ns = createNamespaceFromPath( asset );
+        return ArchivaProject.withRepository( this ).withAsset( asset )
+            .withNamespace( ns ).withId( asset.getName( ) ).build( );
+    }
+
+    private Namespace createNamespaceFromPath( StorageAsset asset) {
+        String namespace = asset.getPath( ).replace( "/", "." );
+        return ArchivaNamespace.withRepository( this )
+            .withAsset( asset ).withNamespace( namespace ).build();
+    }
+
+
+    @Override
     public void deleteAllItems( ItemSelector selector, 
Consumer<ItemDeleteStatus> consumer ) throws ContentAccessException, 
IllegalArgumentException
     {
 
@@ -190,7 +240,14 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
     @Override
     public ContentItem getParent( ContentItem item )
     {
-        return null;
+        try
+        {
+            return toItem( item.getAsset( ).getParent( ) );
+        }
+        catch ( LayoutException e )
+        {
+            throw new RuntimeException( "Bad layout conversion " + 
e.getMessage( ) );
+        }
     }
 
     @Override
@@ -224,6 +281,12 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
     }
 
     @Override
+    public DataItem getMetadataItem( Version version )
+    {
+        return null;
+    }
+
+    @Override
     public ContentItem toItem( String path ) throws LayoutException
     {
         return null;
@@ -553,22 +616,6 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
         return path.toString();
     }
 
-    public String toMetadataPath( VersionedReference reference )
-    {
-        StringBuilder path = new StringBuilder();
-
-        path.append( formatAsDirectory( reference.getGroupId() ) ).append( 
PATH_SEPARATOR );
-        path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
-        if ( reference.getVersion() != null )
-        {
-            // add the version only if it is present
-            path.append( VersionUtil.getBaseVersion( reference.getVersion() ) 
).append( PATH_SEPARATOR );
-        }
-        path.append( MAVEN_METADATA );
-
-        return path.toString();
-    }
-
     @Override
     public String toPath( ArtifactReference reference )
     {
@@ -588,12 +635,6 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
     }
 
     @Override
-    public String toPath( ArchivaArtifact reference )
-    {
-        return null;
-    }
-
-    @Override
     public ManagedRepositoryContent getGenericContent( )
     {
         return null;
diff --git 
a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MetadataTransferTest.java
 
b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MetadataTransferTest.java
index 654e498..1a19acf 100644
--- 
a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MetadataTransferTest.java
+++ 
b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MetadataTransferTest.java
@@ -32,6 +32,9 @@ import org.apache.archiva.policies.ChecksumPolicy;
 import org.apache.archiva.policies.ReleasesPolicy;
 import org.apache.archiva.policies.SnapshotsPolicy;
 import org.apache.archiva.repository.BaseRepositoryContentLayout;
+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.metadata.base.MetadataTools;
 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
 import org.apache.archiva.repository.metadata.base.RepositoryMetadataWriter;
@@ -1041,12 +1044,19 @@ public class MetadataTransferTest
     {
         Path expectedFile = managedDefaultDir.resolve(requestedResource);
 
-        VersionedReference metadata = createVersionedReference( 
requestedResource );
-
+        ContentItem item = managedDefaultRepository.toItem( requestedResource 
);
+        if (item instanceof DataItem) {
+            item = managedDefaultRepository.getParent( item );
+        }
+        assertNotNull( item );
         BaseRepositoryContentLayout layout = 
managedDefaultRepository.getLayout( BaseRepositoryContentLayout.class );
+        Version version = layout.adaptItem( Version.class, item );
+        assertNotNull( version );
+        String metaPath = managedDefaultRepository.toPath( 
layout.getMetadataItem(
+            version ) );
+
         StorageAsset downloadedFile = proxyHandler.fetchMetadataFromProxies( 
managedDefaultRepository.getRepository(),
-                                                                     
layout.toMetadataPath(
-                                                                         
metadata ) ).getFile();
+                                                                     
metaPath).getFile();
 
         assertNotNull( "Should have downloaded a file.", downloadedFile );
         assertNoTempFiles( expectedFile );
@@ -1068,12 +1078,16 @@ public class MetadataTransferTest
         throws Exception
     {
         Path expectedFile = managedDefaultDir.resolve(requestedResource);
-        VersionedReference metadata = createVersionedReference( 
requestedResource );
-
+        ContentItem item = managedDefaultRepository.toItem( requestedResource 
);
+        assertNotNull( item );
         BaseRepositoryContentLayout layout = 
managedDefaultRepository.getLayout( BaseRepositoryContentLayout.class );
+        Version version = layout.adaptItem( Version.class, item );
+        assertNotNull( version );
+        String metaPath = managedDefaultRepository.toPath( 
layout.getMetadataItem(
+            version ) );
+        assertNotNull( metaPath );
         StorageAsset downloadedFile = proxyHandler.fetchMetadataFromProxies( 
managedDefaultRepository.getRepository(),
-                                                                     
layout.toMetadataPath(
-                                                                         
metadata ) ).getFile();
+                                                                     metaPath 
).getFile();
 
         assertNull( downloadedFile );
         assertNoTempFiles( expectedFile );
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 ae862ae..4c3d1bf 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
@@ -29,12 +29,19 @@ import org.apache.archiva.model.ProjectReference;
 import org.apache.archiva.model.VersionedReference;
 import org.apache.archiva.repository.*;
 import org.apache.archiva.repository.content.Artifact;
+import org.apache.archiva.repository.content.BaseDataItemTypes;
 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.ArchivaNamespace;
+import org.apache.archiva.repository.content.base.ArchivaProject;
+import org.apache.archiva.repository.content.base.ArchivaVersion;
 import org.apache.archiva.repository.storage.fs.FilesystemStorage;
 import org.apache.archiva.repository.storage.RepositoryStorage;
 import org.apache.archiva.repository.storage.StorageAsset;
@@ -84,6 +91,51 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
     }
 
     @Override
+    public <T extends ContentItem> T adaptItem( Class<T> clazz, ContentItem 
item ) throws LayoutException
+    {
+        if (clazz.isAssignableFrom( Version.class ))
+        {
+            if ( !item.hasCharacteristic( Version.class ) )
+            {
+                item.setCharacteristic( Version.class, createVersionFromPath( 
item.getAsset() ) );
+            }
+            return (T) item.adapt( Version.class );
+        } else if ( clazz.isAssignableFrom( Project.class )) {
+            if ( !item.hasCharacteristic( Project.class ) )
+            {
+                item.setCharacteristic( Project.class, createProjectFromPath( 
item.getAsset() ) );
+            }
+            return (T) item.adapt( Project.class );
+        } else if ( clazz.isAssignableFrom( Namespace.class )) {
+            if ( !item.hasCharacteristic( Namespace.class ) )
+            {
+                item.setCharacteristic( Namespace.class, 
createNamespaceFromPath( item.getAsset() ) );
+            }
+            return (T) item.adapt( Namespace.class );
+        }
+        throw new LayoutException( "Could not convert item to class " + clazz);
+    }
+
+    private Version createVersionFromPath( StorageAsset asset )
+    {
+        Project proj = createProjectFromPath( asset.getParent( ) );
+        return ArchivaVersion.withRepository( this ).withAsset( asset )
+            .withProject( proj ).withVersion( asset.getName( ) ).build();
+    }
+
+    private Project createProjectFromPath( StorageAsset asset)  {
+        Namespace ns = createNamespaceFromPath( asset );
+        return ArchivaProject.withRepository( this ).withAsset( asset )
+            .withNamespace( ns ).withId( asset.getName( ) ).build( );
+    }
+
+    private Namespace createNamespaceFromPath( StorageAsset asset) {
+        String namespace = asset.getPath( ).replace( "/", "." );
+        return ArchivaNamespace.withRepository( this )
+            .withAsset( asset ).withNamespace( namespace ).build();
+    }
+
+    @Override
     public void deleteAllItems( ItemSelector selector, 
Consumer<ItemDeleteStatus> consumer ) throws ContentAccessException, 
IllegalArgumentException
     {
 
@@ -194,7 +246,14 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
     @Override
     public ContentItem getParent( ContentItem item )
     {
-        return null;
+        try
+        {
+            return toItem( item.getAsset( ).getParent( ) );
+        }
+        catch ( LayoutException e )
+        {
+            throw new RuntimeException( "Bad layout conversion " + 
e.getMessage( ) );
+        }
     }
 
     @Override
@@ -228,15 +287,30 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
     }
 
     @Override
+    public DataItem getMetadataItem( Version version )
+    {
+        return ArchivaDataItem.withAsset( version.getAsset( ).resolve( 
"maven-metadata.xml" ) ).withId( "maven-metadata.xml" )
+            .withDataType( BaseDataItemTypes.METADATA ).build();
+    }
+
+    @Override
     public ContentItem toItem( String path ) throws LayoutException
     {
-        return null;
+        StorageAsset asset = repository.getAsset( "" ).resolve( path );
+        return toItem( asset );
     }
 
     @Override
-    public ContentItem toItem( StorageAsset assetPath ) throws LayoutException
+    public ContentItem toItem( StorageAsset asset ) throws LayoutException
     {
-        return null;
+        if (asset.isLeaf()) {
+            return ArchivaDataItem.withAsset( asset ).withId( asset.getName( ) 
).build();
+        } else
+        {
+            return ArchivaContentItem.withRepository( this )
+                .withAsset( asset )
+                .build( );
+        }
     }
 
     @Override
@@ -272,7 +346,7 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
     @Override
     public String toPath( ContentItem item )
     {
-        return null;
+        return item.getAsset( ).getPath( );
     }
 
     @Override
@@ -557,22 +631,6 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
         return path.toString();
     }
 
-    public String toMetadataPath( VersionedReference reference )
-    {
-        StringBuilder path = new StringBuilder();
-
-        path.append( formatAsDirectory( reference.getGroupId() ) ).append( 
PATH_SEPARATOR );
-        path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
-        if ( reference.getVersion() != null )
-        {
-            // add the version only if it is present
-            path.append( VersionUtil.getBaseVersion( reference.getVersion() ) 
).append( PATH_SEPARATOR );
-        }
-        path.append( MAVEN_METADATA );
-
-        return path.toString();
-    }
-
     @Override
     public String toPath( ArtifactReference reference )
     {
@@ -592,12 +650,6 @@ public class ManagedRepositoryContentMock implements 
BaseRepositoryContentLayout
     }
 
     @Override
-    public String toPath( ArchivaArtifact reference )
-    {
-        return null;
-    }
-
-    @Override
     public ManagedRepositoryContent getGenericContent( )
     {
         return null;
diff --git 
a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/AbstractDefaultRepositoryContent.java
 
b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/AbstractDefaultRepositoryContent.java
index 897165b..c43d401 100644
--- 
a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/AbstractDefaultRepositoryContent.java
+++ 
b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/AbstractDefaultRepositoryContent.java
@@ -20,7 +20,6 @@ package org.apache.archiva.repository.maven.content;
 
 import org.apache.archiva.common.utils.VersionUtil;
 import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
-import org.apache.archiva.repository.content.ContentItem;
 import 
org.apache.archiva.repository.maven.metadata.storage.ArtifactMappingProvider;
 import 
org.apache.archiva.repository.maven.metadata.storage.Maven2RepositoryPathTranslator;
 import org.apache.archiva.model.ArchivaArtifact;
@@ -137,6 +136,7 @@ public abstract class AbstractDefaultRepositoryContent 
implements RepositoryCont
 
     }
 
+
     public String toMetadataPath( ProjectReference reference )
     {
         final StringBuilder path = new StringBuilder();
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 12b0935..ab311ee 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
@@ -20,6 +20,7 @@ package org.apache.archiva.repository.maven.content;
 
 import org.apache.archiva.common.filelock.FileLockManager;
 import org.apache.archiva.common.utils.FileUtils;
+import org.apache.archiva.common.utils.VersionUtil;
 import org.apache.archiva.configuration.FileTypes;
 import org.apache.archiva.metadata.maven.MavenMetadataReader;
 import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
@@ -187,6 +188,38 @@ public class ManagedDefaultRepositoryContent
 
 
     @Override
+    public <T extends ContentItem> T adaptItem( Class<T> clazz, ContentItem 
item ) throws LayoutException
+    {
+        if (clazz.isAssignableFrom( Version.class ))
+        {
+            if ( !item.hasCharacteristic( Version.class ) )
+            {
+                item.setCharacteristic( Version.class, createVersionFromPath( 
item.getAsset() ) );
+            }
+            return (T) item.adapt( Version.class );
+        } else if ( clazz.isAssignableFrom( Project.class )) {
+            if ( !item.hasCharacteristic( Project.class ) )
+            {
+                item.setCharacteristic( Project.class, createProjectFromPath( 
item.getAsset() ) );
+            }
+            return (T) item.adapt( Project.class );
+        } else if ( clazz.isAssignableFrom( Namespace.class )) {
+            if ( !item.hasCharacteristic( Namespace.class ) )
+            {
+                item.setCharacteristic( Namespace.class, 
createNamespaceFromPath( item.getAsset() ) );
+            }
+            return (T) item.adapt( Namespace.class );
+        } else if ( clazz.isAssignableFrom( Artifact.class )) {
+            if (!item.hasCharacteristic( Artifact.class )) {
+                item.setCharacteristic( Artifact.class, 
createArtifactFromPath( item.getAsset( ) ) );
+            }
+            return (T) item.adapt( Artifact.class );
+        }
+        throw new LayoutException( "Could not convert item to class " + clazz);
+    }
+
+
+    @Override
     public void deleteAllItems( ItemSelector selector, 
Consumer<ItemDeleteStatus> consumer ) throws ContentAccessException, 
IllegalArgumentException
     {
         try ( Stream<? extends ContentItem> stream = newItemStream( selector, 
false ) )
@@ -1298,6 +1331,13 @@ public class ManagedDefaultRepositoryContent
     }
 
     @Override
+    public DataItem getMetadataItem( Version version ) {
+        StorageAsset metaPath = version.getAsset( ).resolve( MAVEN_METADATA );
+        return getDataItemFromPath( metaPath );
+    }
+
+
+    @Override
     public void deleteVersion( VersionedReference ref ) throws 
ContentNotFoundException, ContentAccessException
     {
         final String path = toPath( ref );
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 70c7021..f465df1 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
@@ -1609,5 +1609,30 @@ public class ManagedDefaultRepositoryContentTest
         assertTrue( new String( content ).startsWith( "test.test.test" ) );
     }
 
+    @Test
+    public void getExistingMetadataItem() {
+        // org/apache/maven/some-ejb/1.0
+        ArchivaItemSelector versionSelector = ArchivaItemSelector.builder( )
+            .withNamespace( "org.apache.maven" )
+            .withProjectId( "some-ejb" )
+            .withVersion( "1.0" ).build( );
+        Version version = repoContent.getVersion( versionSelector );
+        DataItem metaData = repoContent.getMetadataItem( version );
+        assertTrue( metaData.exists( ) );
+        assertEquals( "/org/apache/maven/some-ejb/1.0/maven-metadata.xml", 
metaData.getAsset( ).getPath( ) );
+    }
+
+    @Test
+    public void getNonExistingMetadataItem() {
+        // org/apache/maven/some-ejb/1.0
+        ArchivaItemSelector versionSelector = ArchivaItemSelector.builder( )
+            .withNamespace( "javax.sql" )
+            .withProjectId( "jdbc" )
+            .withVersion( "2.0" ).build( );
+        Version version = repoContent.getVersion( versionSelector );
+        DataItem metaData = repoContent.getMetadataItem( version );
+        assertFalse( metaData.exists( ) );
+        assertEquals( "/javax/sql/jdbc/2.0/maven-metadata.xml", 
metaData.getAsset( ).getPath( ) );
+    }
 
 }
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 f6d11dc..1eca75d 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
@@ -769,14 +769,16 @@ public class DefaultRepositoriesService
             fmt.setTimeZone( timezone );
             ManagedRepository repo = repositoryRegistry.getManagedRepository( 
repositoryId );
 
-            VersionedReference ref = new VersionedReference();
-            ref.setArtifactId( artifact.getArtifactId() );
-            ref.setGroupId( artifact.getGroupId() );
-            ref.setVersion( artifact.getVersion() );
-
             ManagedRepositoryContent repository = getManagedRepositoryContent( 
repositoryId );
             BaseRepositoryContentLayout layout = repository.getLayout( 
BaseRepositoryContentLayout.class );
 
+            ArchivaItemSelector versionSelector = ArchivaItemSelector.builder( 
).withNamespace( artifact.getGroupId( ) )
+                .withProjectId( artifact.getArtifactId( ) )
+                .withVersion( artifact.getVersion( ) ).build( );
+
+            Version version1 = layout.getVersion( versionSelector );
+            String path = layout.toPath( version1 );
+
             ArtifactReference artifactReference = new ArtifactReference();
             artifactReference.setArtifactId( artifact.getArtifactId() );
             artifactReference.setGroupId( artifact.getGroupId() );
@@ -796,8 +798,6 @@ public class DefaultRepositoriesService
 
             MetadataRepository metadataRepository = 
repositorySession.getRepository();
 
-            String path = layout.toMetadataPath( ref );
-
             if ( StringUtils.isNotBlank( artifact.getClassifier() ) )
             {
                 if ( StringUtils.isBlank( artifact.getPackaging() ) )
@@ -835,9 +835,16 @@ public class DefaultRepositoriesService
 
                 // TODO: this should be in the storage mechanism so that it is 
all tied together
                 // delete from file system
-                if ( !snapshotVersion )
+                if ( !snapshotVersion && version1.exists() )
                 {
-                    layout.deleteVersion( ref );
+                    try
+                    {
+                        layout.deleteItem( version1 );
+                    }
+                    catch ( ItemNotFoundException e )
+                    {
+                        log.error( "Could not delete version item {}", 
e.getMessage( ) );
+                    }
                 }
                 else
                 {

Reply via email to