summaryrefslogtreecommitdiffstats
path: root/archiva-modules
diff options
context:
space:
mode:
Diffstat (limited to 'archiva-modules')
-rw-r--r--archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/ArtifactContentEntry.java55
-rw-r--r--archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/BrowseService.java8
-rw-r--r--archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java175
-rw-r--r--archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/BrowseServiceTest.java53
-rw-r--r--archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/RepositoryServlet.java8
5 files changed, 291 insertions, 8 deletions
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/ArtifactContentEntry.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/ArtifactContentEntry.java
index fac87f2ca..7a9b2ff91 100644
--- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/ArtifactContentEntry.java
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/ArtifactContentEntry.java
@@ -31,15 +31,18 @@ public class ArtifactContentEntry
private boolean file;
+ private int depth;
+
public ArtifactContentEntry()
{
// no op
}
- public ArtifactContentEntry( String name, boolean file )
+ public ArtifactContentEntry( String name, boolean file, int depth )
{
this.name = name;
this.file = file;
+ this.depth = depth;
}
public String getName()
@@ -62,6 +65,16 @@ public class ArtifactContentEntry
this.file = file;
}
+ public int getDepth()
+ {
+ return depth;
+ }
+
+ public void setDepth( int depth )
+ {
+ this.depth = depth;
+ }
+
@Override
public String toString()
{
@@ -69,7 +82,47 @@ public class ArtifactContentEntry
sb.append( "ArtifactContentEntry" );
sb.append( "{name='" ).append( name ).append( '\'' );
sb.append( ", file=" ).append( file );
+ sb.append( ", depth=" ).append( depth );
sb.append( '}' );
return sb.toString();
}
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o )
+ {
+ return true;
+ }
+ if ( !( o instanceof ArtifactContentEntry ) )
+ {
+ return false;
+ }
+
+ ArtifactContentEntry that = (ArtifactContentEntry) o;
+
+ if ( depth != that.depth )
+ {
+ return false;
+ }
+ if ( file != that.file )
+ {
+ return false;
+ }
+ if ( !name.equals( that.name ) )
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = name.hashCode();
+ result = 31 * result + ( file ? 1 : 0 );
+ result = 31 * result + depth;
+ return result;
+ }
}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/BrowseService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/BrowseService.java
index ff628931b..0afa9dbc2 100644
--- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/BrowseService.java
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/BrowseService.java
@@ -146,10 +146,16 @@ public interface BrowseService
@QueryParam( "repositoryId" ) String repositoryId )
throws ArchivaRestServiceException;
+ @Path( "artifactContentEntries/{g}/{a}/{v}" )
+ @GET
+ @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
+ @RedbackAuthorization( noPermission = true, noRestriction = true )
List<ArtifactContentEntry> getArtifactContentEntries( @PathParam( "g" ) String groupId,
@PathParam( "a" ) String artifactId,
@PathParam( "v" ) String version,
- @PathParam( "" ) String path,
+ @QueryParam( "c" ) String classifier,
+ @QueryParam( "t" ) String type,
+ @QueryParam( "p" ) String path,
@QueryParam( "repositoryId" ) String repositoryId )
throws ArchivaRestServiceException;
}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java
index 8b0b11983..85a0da594 100644
--- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java
@@ -31,6 +31,11 @@ import org.apache.archiva.metadata.repository.MetadataResolutionException;
import org.apache.archiva.metadata.repository.MetadataResolver;
import org.apache.archiva.metadata.repository.RepositorySession;
import org.apache.archiva.metadata.repository.storage.maven2.MavenProjectFacet;
+import org.apache.archiva.model.ArchivaArtifact;
+import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.RepositoryContentFactory;
+import org.apache.archiva.repository.RepositoryException;
+import org.apache.archiva.repository.RepositoryNotFoundException;
import org.apache.archiva.rest.api.model.Artifact;
import org.apache.archiva.rest.api.model.ArtifactContentEntry;
import org.apache.archiva.rest.api.model.BrowseResult;
@@ -40,6 +45,7 @@ import org.apache.archiva.rest.api.model.TreeEntry;
import org.apache.archiva.rest.api.model.VersionsList;
import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
import org.apache.archiva.rest.api.services.BrowseService;
+import org.apache.archiva.rest.services.utils.ArtifactContentEntryComparator;
import org.apache.archiva.rest.services.utils.TreeDependencyNodeVisitor;
import org.apache.archiva.security.ArchivaSecurityException;
import org.apache.commons.collections.CollectionUtils;
@@ -49,14 +55,19 @@ import org.springframework.stereotype.Service;
import javax.inject.Inject;
import javax.ws.rs.core.Response;
+import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
/**
* @author Olivier Lamy
@@ -71,6 +82,9 @@ public class DefaultBrowseService
@Inject
private DependencyTreeBuilder dependencyTreeBuilder;
+ @Inject
+ private RepositoryContentFactory repositoryContentFactory;
+
public BrowseResult getRootGroups( String repositoryId )
throws ArchivaRestServiceException
{
@@ -594,16 +608,173 @@ public class DefaultBrowseService
}
public List<ArtifactContentEntry> getArtifactContentEntries( String groupId, String artifactId, String version,
- String path, String repositoryId )
+ String classifier, String type, String path,
+ String repositoryId )
throws ArchivaRestServiceException
{
- return null;
+ List<String> selectedRepos = getSelectedRepos( repositoryId );
+ try
+ {
+ for ( String repoId : selectedRepos )
+ {
+
+ ManagedRepositoryContent managedRepositoryContent =
+ repositoryContentFactory.getManagedRepositoryContent( repoId );
+ ArchivaArtifact archivaArtifact = new ArchivaArtifact( groupId, artifactId, version, classifier,
+ StringUtils.isEmpty( type ) ? "jar" : type,
+ repositoryId );
+ File file = managedRepositoryContent.toFile( archivaArtifact );
+ if ( file.exists() )
+ {
+ return readFileEntries( file, path );
+ }
+ }
+ }
+ catch ( IOException e )
+ {
+ log.error( e.getMessage(), e );
+ throw new ArchivaRestServiceException( e.getMessage(),
+ Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
+ }
+ catch ( RepositoryNotFoundException e )
+ {
+ log.error( e.getMessage(), e );
+ throw new ArchivaRestServiceException( e.getMessage(),
+ Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
+ }
+ catch ( RepositoryException e )
+ {
+ log.error( e.getMessage(), e );
+ throw new ArchivaRestServiceException( e.getMessage(),
+ Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
+ }
+ return Collections.emptyList();
}
//---------------------------
// internals
//---------------------------
+ protected List<ArtifactContentEntry> readFileEntries( File file, String filterPath )
+ throws IOException
+ {
+ Map<String, ArtifactContentEntry> artifactContentEntryMap = new HashMap<String, ArtifactContentEntry>();
+ int filterDepth = StringUtils.countMatches( filterPath, "/" );
+ if ( filterDepth == 0 )
+ {
+ filterDepth = 1;
+ }
+ JarFile jarFile = new JarFile( file );
+ try
+ {
+ Enumeration<JarEntry> jarEntryEnumeration = jarFile.entries();
+ while ( jarEntryEnumeration.hasMoreElements() )
+ {
+ JarEntry entry = jarEntryEnumeration.nextElement();
+ String entryName = entry.getName();
+ String entryRootPath = getRootPath( entryName );
+ int depth = StringUtils.countMatches( entryName, "/" );
+ if ( StringUtils.isEmpty( filterPath ) && !artifactContentEntryMap.containsKey( entryRootPath ) )
+ {
+
+ artifactContentEntryMap.put( entryRootPath,
+ new ArtifactContentEntry( entryRootPath, !entry.isDirectory(),
+ depth ) );
+ }
+ else
+ {
+ if ( StringUtils.startsWith( entryName, filterPath ) && ( depth > filterDepth || (
+ !entry.isDirectory() && depth == filterDepth ) ) )
+ {
+ // remove last /
+ String cleanedEntryName = StringUtils.endsWith( entryName, "/" )
+ ? StringUtils.substringBeforeLast( entryName, "/" )
+ : entryName;
+ artifactContentEntryMap.put( cleanedEntryName,
+ new ArtifactContentEntry( cleanedEntryName, !entry.isDirectory(),
+ depth ) );
+ }
+ }
+ }
+
+ if ( StringUtils.isNotEmpty( filterPath ) )
+ {
+ // apply more filtering here
+ // search entries filterPath/blabla
+ Map<String, ArtifactContentEntry> filteredArtifactContentEntryMap =
+ new HashMap<String, ArtifactContentEntry>();
+
+ for ( Map.Entry<String, ArtifactContentEntry> entry : artifactContentEntryMap.entrySet() )
+ {
+ filteredArtifactContentEntryMap.put( entry.getKey(), entry.getValue() );
+ }
+
+ List<ArtifactContentEntry> sorted = getSmallerDepthEntries( filteredArtifactContentEntryMap );
+ if ( sorted == null )
+ {
+ return Collections.emptyList();
+ }
+ Collections.sort( sorted, ArtifactContentEntryComparator.INSTANCE );
+ return sorted;
+ }
+ }
+ finally
+ {
+ if ( jarFile != null )
+ {
+ jarFile.close();
+ }
+ }
+ List<ArtifactContentEntry> sorted = new ArrayList<ArtifactContentEntry>( artifactContentEntryMap.values() );
+ Collections.sort( sorted, ArtifactContentEntryComparator.INSTANCE );
+ return sorted;
+ }
+
+ private List<ArtifactContentEntry> getSmallerDepthEntries( Map<String, ArtifactContentEntry> entries )
+ {
+ int smallestDepth = Integer.MAX_VALUE;
+ Map<Integer, List<ArtifactContentEntry>> perDepthList = new HashMap<Integer, List<ArtifactContentEntry>>();
+ for ( Map.Entry<String, ArtifactContentEntry> entry : entries.entrySet() )
+ {
+
+ ArtifactContentEntry current = entry.getValue();
+
+ if ( current.getDepth() < smallestDepth )
+ {
+ smallestDepth = current.getDepth();
+ }
+
+ List<ArtifactContentEntry> currentList = perDepthList.get( current.getDepth() );
+
+ if ( currentList == null )
+ {
+ currentList = new ArrayList<ArtifactContentEntry>();
+ currentList.add( current );
+ perDepthList.put( current.getDepth(), currentList );
+ }
+ else
+ {
+ currentList.add( current );
+ }
+
+ }
+
+ return perDepthList.get( smallestDepth );
+ }
+
+ /**
+ * @param path
+ * @return org/apache -> org , org -> org
+ */
+ private String getRootPath( String path )
+ {
+ if ( StringUtils.contains( path, '/' ) )
+ {
+ return StringUtils.substringBefore( path, "/" );
+ }
+ return path;
+ }
+
private List<String> getSelectedRepos( String repositoryId )
throws ArchivaRestServiceException
{
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/BrowseServiceTest.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/BrowseServiceTest.java
index cc1bedefe..854886f8a 100644
--- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/BrowseServiceTest.java
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/BrowseServiceTest.java
@@ -19,6 +19,7 @@ package org.apache.archiva.rest.services;
*/
import org.apache.archiva.metadata.model.ProjectVersionMetadata;
+import org.apache.archiva.rest.api.model.ArtifactContentEntry;
import org.apache.archiva.rest.api.model.BrowseResult;
import org.apache.archiva.rest.api.model.BrowseResultEntry;
import org.apache.archiva.rest.api.model.Entry;
@@ -222,4 +223,56 @@ public class BrowseServiceTest
deleteTestRepo( testRepoId );
}
+
+ @Test
+ public void readArtifactContentEntries()
+ throws Exception
+ {
+ String testRepoId = "test-repo";
+ // force guest user creation if not exists
+ if ( getUserService( authorizationHeader ).getGuestUser() == null )
+ {
+ assertNotNull( getUserService( authorizationHeader ).createGuestUser() );
+ }
+
+ createAndIndexRepo( testRepoId, new File( getBasedir(), "src/test/repo-with-osgi" ).getAbsolutePath(), false );
+
+ BrowseService browseService = getBrowseService( authorizationHeader, true );
+
+ List<ArtifactContentEntry> artifactContentEntries =
+ browseService.getArtifactContentEntries( "commons-logging", "commons-logging", "1.1", null, null, null,
+ testRepoId );
+
+ log.info( "artifactContentEntries: {}", artifactContentEntries );
+
+ assertThat( artifactContentEntries ).isNotNull().isNotEmpty().hasSize( 2 ).contains(
+ new ArtifactContentEntry( "org", false, 1 ), new ArtifactContentEntry( "META-INF", false, 1 ) );
+ deleteTestRepo( testRepoId );
+ }
+
+ @Test
+ public void readArtifactContentEntriesRootPath()
+ throws Exception
+ {
+ String testRepoId = "test-repo";
+ // force guest user creation if not exists
+ if ( getUserService( authorizationHeader ).getGuestUser() == null )
+ {
+ assertNotNull( getUserService( authorizationHeader ).createGuestUser() );
+ }
+
+ createAndIndexRepo( testRepoId, new File( getBasedir(), "src/test/repo-with-osgi" ).getAbsolutePath(), false );
+
+ BrowseService browseService = getBrowseService( authorizationHeader, true );
+
+ List<ArtifactContentEntry> artifactContentEntries =
+ browseService.getArtifactContentEntries( "commons-logging", "commons-logging", "1.1", null, null, "org",
+ testRepoId );
+
+ log.info( "artifactContentEntries: {}", artifactContentEntries );
+
+ assertThat( artifactContentEntries ).isNotNull().isNotEmpty().hasSize( 1 ).contains(
+ new ArtifactContentEntry( "org/apache", false, 2 ) );
+ deleteTestRepo( testRepoId );
+ }
}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/RepositoryServlet.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/RepositoryServlet.java
index 4b7d31c30..c9b6e807e 100644
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/RepositoryServlet.java
+++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/RepositoryServlet.java
@@ -22,6 +22,9 @@ package org.apache.archiva.webdav;
import org.apache.archiva.admin.model.RepositoryAdminException;
import org.apache.archiva.admin.model.beans.ManagedRepository;
import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
+import org.apache.archiva.configuration.ArchivaConfiguration;
+import org.apache.archiva.configuration.ConfigurationEvent;
+import org.apache.archiva.configuration.ConfigurationListener;
import org.apache.archiva.security.ServletAuthenticator;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavLocatorFactory;
@@ -35,9 +38,6 @@ import org.apache.jackrabbit.webdav.WebdavRequestImpl;
import org.apache.jackrabbit.webdav.WebdavResponse;
import org.apache.jackrabbit.webdav.WebdavResponseImpl;
import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet;
-import org.apache.archiva.configuration.ArchivaConfiguration;
-import org.apache.archiva.configuration.ConfigurationEvent;
-import org.apache.archiva.configuration.ConfigurationListener;
import org.codehaus.redback.integration.filter.authentication.HttpAuthenticator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -189,7 +189,7 @@ public class RepositoryServlet
if ( !repoDir.mkdirs() )
{
// Skip invalid directories.
- log( "Unable to create missing directory for " + repo.getLocation() );
+ log.info( "Unable to create missing directory for {}", repo.getLocation() );
continue;
}
}