aboutsummaryrefslogtreecommitdiffstats
path: root/archiva-modules
diff options
context:
space:
mode:
authorOlivier Lamy <olamy@apache.org>2014-05-20 15:04:47 +1000
committerOlivier Lamy <olamy@apache.org>2014-05-20 15:04:47 +1000
commit85047d3bb6163b3223ec9a4b90dae2a968d6bcb6 (patch)
tree0bb1aea69b92646fda9877707da91d266be28252 /archiva-modules
parenta78b6070bc5c8e866011b6602b196a7c17f42c7d (diff)
downloadarchiva-85047d3bb6163b3223ec9a4b90dae2a968d6bcb6.tar.gz
archiva-85047d3bb6163b3223ec9a4b90dae2a968d6bcb6.zip
[MRM-1843] provide mechanism to obtain the latest version of an artifact
start download api currently redirect
Diffstat (limited to 'archiva-modules')
-rw-r--r--archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/archiva/indexer/search/MavenRepositorySearch.java62
-rw-r--r--archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/archiva/indexer/search/SearchFields.java17
-rw-r--r--archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/SearchService.java15
-rw-r--r--archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/AbstractRestService.java29
-rw-r--r--archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultSearchService.java50
5 files changed, 152 insertions, 21 deletions
diff --git a/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/archiva/indexer/search/MavenRepositorySearch.java b/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/archiva/indexer/search/MavenRepositorySearch.java
index 2a41526e2..848ca78c1 100644
--- a/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/archiva/indexer/search/MavenRepositorySearch.java
+++ b/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/archiva/indexer/search/MavenRepositorySearch.java
@@ -29,16 +29,23 @@ import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException;
import org.apache.archiva.indexer.util.SearchUtil;
import org.apache.commons.lang.StringUtils;
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Query;
import org.apache.maven.index.ArtifactInfo;
import org.apache.maven.index.FlatSearchRequest;
import org.apache.maven.index.FlatSearchResponse;
import org.apache.maven.index.MAVEN;
import org.apache.maven.index.NexusIndexer;
import org.apache.maven.index.OSGI;
+import org.apache.maven.index.QueryCreator;
+import org.apache.maven.index.SearchType;
import org.apache.maven.index.context.IndexCreator;
import org.apache.maven.index.context.IndexingContext;
+import org.apache.maven.index.expr.SearchExpression;
+import org.apache.maven.index.expr.SearchTyped;
import org.apache.maven.index.expr.SourcedSearchExpression;
import org.apache.maven.index.expr.UserInputSearchExpression;
import org.slf4j.Logger;
@@ -58,7 +65,7 @@ import java.util.Set;
/**
* RepositorySearch implementation which uses the Maven Indexer for searching.
*/
-@Service("repositorySearch#maven")
+@Service( "repositorySearch#maven" )
public class MavenRepositorySearch
implements RepositorySearch
{
@@ -66,6 +73,8 @@ public class MavenRepositorySearch
private NexusIndexer indexer;
+ private QueryCreator queryCreator;
+
private ManagedRepositoryAdmin managedRepositoryAdmin;
private ProxyConnectorAdmin proxyConnectorAdmin;
@@ -83,6 +92,7 @@ public class MavenRepositorySearch
throws PlexusSisuBridgeException
{
this.indexer = plexusSisuBridge.lookup( NexusIndexer.class );
+ this.queryCreator = plexusSisuBridge.lookup( QueryCreator.class );
this.managedRepositoryAdmin = managedRepositoryAdmin;
this.mavenIndexerUtils = mavenIndexerUtils;
this.proxyConnectorAdmin = proxyConnectorAdmin;
@@ -153,28 +163,35 @@ public class MavenRepositorySearch
BooleanQuery q = new BooleanQuery();
if ( StringUtils.isNotBlank( searchFields.getGroupId() ) )
{
- q.add( indexer.constructQuery( MAVEN.GROUP_ID, new UserInputSearchExpression( searchFields.getGroupId() ) ),
- Occur.MUST );
+ q.add( indexer.constructQuery( MAVEN.GROUP_ID, searchFields.isExactSearch()
+ ? new SourcedSearchExpression( searchFields.getGroupId() )
+ : new UserInputSearchExpression( searchFields.getGroupId() )
+ ), Occur.MUST
+ );
}
if ( StringUtils.isNotBlank( searchFields.getArtifactId() ) )
{
q.add( indexer.constructQuery( MAVEN.ARTIFACT_ID,
- new UserInputSearchExpression( searchFields.getArtifactId() ) ), Occur.MUST
+ searchFields.isExactSearch()
+ ? new SourcedSearchExpression( searchFields.getArtifactId() )
+ : new UserInputSearchExpression( searchFields.getArtifactId() )
+ ), Occur.MUST
);
}
if ( StringUtils.isNotBlank( searchFields.getVersion() ) )
{
- q.add( indexer.constructQuery( MAVEN.VERSION, new SourcedSearchExpression( searchFields.getVersion() ) ),
- Occur.MUST );
+ q.add( indexer.constructQuery( MAVEN.VERSION, searchFields.isExactSearch() ? new SourcedSearchExpression(
+ searchFields.getVersion() ) : new SourcedSearchExpression( searchFields.getVersion() ) ), Occur.MUST );
}
if ( StringUtils.isNotBlank( searchFields.getPackaging() ) )
{
- q.add(
- indexer.constructQuery( MAVEN.PACKAGING, new UserInputSearchExpression( searchFields.getPackaging() ) ),
- Occur.MUST );
+ q.add( indexer.constructQuery( MAVEN.PACKAGING, searchFields.isExactSearch() ? new SourcedSearchExpression(
+ searchFields.getPackaging() ) : new UserInputSearchExpression( searchFields.getPackaging() ) ),
+ Occur.MUST
+ );
}
if ( StringUtils.isNotBlank( searchFields.getClassName() ) )
@@ -247,10 +264,16 @@ public class MavenRepositorySearch
if ( StringUtils.isNotBlank( searchFields.getClassifier() ) )
{
- q.add( indexer.constructQuery( MAVEN.CLASSIFIER,
- new UserInputSearchExpression( searchFields.getClassifier() ) ), Occur.MUST
+ q.add( indexer.constructQuery( MAVEN.CLASSIFIER, searchFields.isExactSearch() ? new SourcedSearchExpression(
+ searchFields.getClassifier() ) : new UserInputSearchExpression( searchFields.getClassifier() ) ),
+ Occur.MUST
);
}
+ else if ( searchFields.isExactSearch() )
+ {
+ //TODO improvement in case of exact search and no classifier we must query for classifier with null value
+ // currently it's done in DefaultSearchService with some filtering
+ }
if ( q.getClauses() == null || q.getClauses().length <= 0 )
{
@@ -261,6 +284,23 @@ public class MavenRepositorySearch
searchFields.getRepositories(), searchFields.isIncludePomArtifacts() );
}
+ private static class NullSearch implements SearchTyped, SearchExpression
+ {
+ private static final NullSearch INSTANCE = new NullSearch();
+
+ @Override
+ public String getStringValue()
+ {
+ return "[[NULL_VALUE]]";
+ }
+
+ @Override
+ public SearchType getSearchType()
+ {
+ return SearchType.EXACT;
+ }
+ }
+
private SearchResults search( SearchResultLimits limits, BooleanQuery q, List<String> indexingContextIds,
List<? extends ArtifactInfoFilter> filters, List<String> selectedRepos,
boolean includePoms )
diff --git a/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/archiva/indexer/search/SearchFields.java b/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/archiva/indexer/search/SearchFields.java
index fd2353423..e5844a765 100644
--- a/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/archiva/indexer/search/SearchFields.java
+++ b/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/archiva/indexer/search/SearchFields.java
@@ -114,6 +114,13 @@ public class SearchFields
private String classifier;
+ /**
+ * we use exact String matching search
+ *
+ * @since 2.1.0
+ */
+ private boolean exactSearch = false;
+
public SearchFields()
{
// no op
@@ -281,6 +288,16 @@ public class SearchFields
this.bundleRequireBundle = bundleRequireBundle;
}
+ public boolean isExactSearch()
+ {
+ return exactSearch;
+ }
+
+ public void setExactSearch( boolean exactSearch )
+ {
+ this.exactSearch = exactSearch;
+ }
+
@Override
public String toString()
{
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/SearchService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/SearchService.java
index de884541c..319abdfeb 100644
--- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/SearchService.java
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/SearchService.java
@@ -21,10 +21,10 @@ package org.apache.archiva.rest.api.services;
import org.apache.archiva.maven2.model.Artifact;
+import org.apache.archiva.redback.authorization.RedbackAuthorization;
import org.apache.archiva.rest.api.model.GroupIdList;
import org.apache.archiva.rest.api.model.SearchRequest;
import org.apache.archiva.rest.api.model.StringList;
-import org.apache.archiva.redback.authorization.RedbackAuthorization;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
@@ -32,6 +32,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
import java.util.List;
@Path( "/searchService/" )
@@ -60,8 +61,7 @@ public interface SearchService
@POST
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
@RedbackAuthorization( noPermission = true, noRestriction = true )
-
- List<Artifact> quickSearchWithRepositories( SearchRequest searchRequest )
+ List<Artifact> quickSearchWithRepositories( SearchRequest searchRequest )
throws ArchivaRestServiceException;
/**
@@ -127,4 +127,13 @@ public interface SearchService
throws ArchivaRestServiceException;
*/
+ @GET
+ @Path( "/artifact" )
+ @Produces( "text/html" )
+ @RedbackAuthorization( noPermission = true, noRestriction = true )
+ Response redirectToArtifactFile( @QueryParam( "r" ) String repositoryId, @QueryParam( "g" ) String groupId,
+ @QueryParam( "a" ) String artifactId, @QueryParam( "v" ) String version,
+ @QueryParam( "p" ) String packaging, @QueryParam( "c" ) String classifier )
+ throws ArchivaRestServiceException;
+
}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/AbstractRestService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/AbstractRestService.java
index 6fb7d0bd0..3443625e5 100644
--- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/AbstractRestService.java
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/AbstractRestService.java
@@ -57,6 +57,7 @@ import org.springframework.context.ApplicationContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
@@ -87,7 +88,7 @@ public abstract class AbstractRestService
* FIXME: this could be multiple implementations and needs to be configured.
*/
@Inject
- @Named( value = "repositorySessionFactory" )
+ @Named(value = "repositorySessionFactory")
protected RepositorySessionFactory repositorySessionFactory;
@Inject
@@ -100,17 +101,20 @@ public abstract class AbstractRestService
protected RepositoryContentFactory repositoryContentFactory;
@Inject
- @Named( value = "archivaTaskScheduler#repository" )
+ @Named(value = "archivaTaskScheduler#repository")
protected DefaultRepositoryArchivaTaskScheduler repositoryTaskScheduler;
@Inject
- @Named( value = "userConfiguration#default" )
+ @Named(value = "userConfiguration#default")
protected UserConfiguration config;
@Context
protected HttpServletRequest httpServletRequest;
+ @Context
+ protected HttpServletResponse httpServletResponse;
+
protected AuditInformation getAuditInformation()
{
RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get();
@@ -213,6 +217,13 @@ public abstract class AbstractRestService
protected String getArtifactUrl( Artifact artifact )
throws ArchivaRestServiceException
{
+ return getArtifactUrl( artifact, null );
+ }
+
+
+ protected String getArtifactUrl( Artifact artifact, String repositoryId )
+ throws ArchivaRestServiceException
+ {
try
{
@@ -225,10 +236,16 @@ public abstract class AbstractRestService
sb.append( "/repository" );
- // FIXME when artifact come from a remote repository when have here the remote repo id
+ // when artifact come from a remote repository when have here the remote repo id
// we must replace it with a valid managed one available for the user.
-
- sb.append( '/' ).append( artifact.getContext() );
+ if ( StringUtils.isEmpty( repositoryId ) )
+ {
+ sb.append( '/' ).append( artifact.getContext() );
+ }
+ else
+ {
+ sb.append( '/' ).append( repositoryId );
+ }
sb.append( '/' ).append( StringUtils.replaceChars( artifact.getGroupId(), '.', '/' ) );
sb.append( '/' ).append( artifact.getArtifactId() );
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultSearchService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultSearchService.java
index d944893aa..9dae9491d 100644
--- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultSearchService.java
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultSearchService.java
@@ -37,14 +37,17 @@ import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import javax.inject.Inject;
+import javax.ws.rs.core.Response;
+import java.net.URI;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* @author Olivier Lamy
*/
-@Service( "searchService#rest" )
+@Service("searchService#rest")
public class DefaultSearchService
extends AbstractRestService
implements SearchService
@@ -205,6 +208,51 @@ public class DefaultSearchService
return new StringList( getObservableRepos() );
}
+ @Override
+ public Response redirectToArtifactFile( String repositoryId, String groupId, String artifactId, String version,
+ String packaging, String classifier )
+ throws ArchivaRestServiceException
+ {
+ try
+ {
+
+ SearchFields searchField = new SearchFields();
+ searchField.setGroupId( groupId );
+ searchField.setArtifactId( artifactId );
+ searchField.setPackaging( StringUtils.isBlank( packaging ) ? "jar" : packaging );
+ searchField.setVersion( version );
+ searchField.setClassifier( classifier );
+ searchField.setRepositories( Arrays.asList( repositoryId ) );
+ searchField.setExactSearch( true );
+ SearchResults searchResults = repositorySearch.search( getPrincipal(), searchField, null );
+ List<Artifact> artifacts = getArtifacts( searchResults );
+
+ // TODO improve that with querying lucene with null value for classifier
+ // so simple loop and retain only artifact with null classifier
+ if ( classifier == null )
+ {
+ List<Artifact> filteredArtifacts = new ArrayList<>( artifacts.size() );
+ for ( Artifact artifact : artifacts )
+ {
+ if ( artifact.getClassifier() == null )
+ {
+ filteredArtifacts.add( artifact );
+ }
+ }
+
+ artifacts = filteredArtifacts;
+ }
+
+ String artifactUrl = getArtifactUrl( artifacts.get( 0 ), repositoryId );
+
+ return Response.temporaryRedirect( new URI( artifactUrl ) ).build();
+ }
+ catch ( Exception e )
+ {
+ throw new ArchivaRestServiceException( e.getMessage(), e );
+ }
+ }
+
//-------------------------------------
// internal
//-------------------------------------