rest search service must provide the real url artifact

git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1177069 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Olivier Lamy 2011-09-28 21:34:34 +00:00
parent 18b92bde16
commit bcf81e82ac
8 changed files with 268 additions and 7 deletions

View File

@ -450,8 +450,6 @@ public class NexusRepositorySearch
hit.setArtifactId( artifactInfo.artifactId );
hit.setGroupId( artifactInfo.groupId );
hit.setRepositoryId( artifactInfo.repository );
// FIXME archiva url ??
hit.setUrl( artifactInfo.repository + "/" + artifactInfo.fname );
hit.addVersion( artifactInfo.version );
hit.setBundleExportPackage( artifactInfo.bundleExportPackage );
hit.setBundleExportService( artifactInfo.bundleExportService );
@ -459,7 +457,6 @@ public class NexusRepositorySearch
hit.setBundleVersion( artifactInfo.bundleVersion );
hit.setBundleDescription( artifactInfo.bundleDescription );
hit.setBundleDocUrl( artifactInfo.bundleDocUrl );
hit.setBundleRequireBundle( artifactInfo.bundleRequireBundle );
hit.setBundleImportPackage( artifactInfo.bundleImportPackage );
hit.setBundleLicense( artifactInfo.bundleLicense );
@ -469,7 +466,6 @@ public class NexusRepositorySearch
hit.setPrefix( artifactInfo.prefix );
hit.setPackaging( artifactInfo.packaging );
hit.setClassifier( artifactInfo.classifier );
// sure ??
hit.setUrl( artifactInfo.remoteUrl );
}

View File

@ -30,6 +30,8 @@ import org.apache.archiva.rest.api.model.Dependency;
import org.apache.archiva.rest.api.model.SearchRequest;
import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
import org.apache.archiva.rest.api.services.SearchService;
import org.apache.archiva.rest.services.interceptors.HttpContext;
import org.apache.archiva.rest.services.interceptors.HttpContextThreadLocal;
import org.apache.archiva.security.AccessDeniedException;
import org.apache.archiva.security.ArchivaSecurityException;
import org.apache.archiva.security.PrincipalNotFoundException;
@ -43,6 +45,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -78,7 +81,7 @@ public class DefaultSearchService
SearchResults searchResults =
repositorySearch.search( getPrincipal(), getObservableRepos(), queryString, limits,
Collections.<String>emptyList() );
return getArtifacts( searchResults);
return getArtifacts( searchResults );
}
catch ( RepositorySearchException e )
@ -182,6 +185,8 @@ public class DefaultSearchService
protected List<Artifact> getArtifacts( SearchResults searchResults )
{
HttpContext httpContext = HttpContextThreadLocal.get();
if ( searchResults == null || searchResults.isEmpty() )
{
return Collections.emptyList();
@ -221,11 +226,13 @@ public class DefaultSearchService
// FIXME archiva url ??
Artifact versionned = new BeanReplicator().replicateBean( hit, Artifact.class );
if ( StringUtils.isNotBlank( version ) )
{
versionned.setVersion( version );
versionned.setUrl( getArtifactUrl( httpContext, versionned ) );
artifacts.add( versionned );
artifacts.add( versionned );
}
}
@ -233,4 +240,47 @@ public class DefaultSearchService
}
return artifacts;
}
private String getArtifactUrl( HttpContext httpContext, Artifact artifact )
{
if ( httpContext == null )
{
return null;
}
if ( httpContext.getHttpServletRequest() == null )
{
return null;
}
StringBuilder sb = new StringBuilder( getBaseUrl( httpContext.getHttpServletRequest() ) );
sb.append( "/repository" );
if ( StringUtils.startsWith( artifact.getContext(), "remote-" ) )
{
// if context is 'remote-*' we have to set a repo which the current user can use
}
else
{
sb.append( '/' ).append( artifact.getContext() );
}
sb.append( '/' ).append( StringUtils.replaceChars( artifact.getGroupId(), '.', '/' ) );
sb.append( '/' ).append( artifact.getArtifactId() );
sb.append( '/' ).append( artifact.getVersion() );
sb.append( '/' ).append( artifact.getArtifactId() );
if ( StringUtils.isNotBlank( artifact.getClassifier() ) )
{
sb.append( '-' ).append( artifact.getClassifier() );
}
sb.append( '-' ).append( artifact.getVersion() );
sb.append( '.' ).append( artifact.getPackaging() );
return sb.toString();
}
protected String getBaseUrl( HttpServletRequest req )
{
return req.getScheme() + "://" + req.getServerName()
+ ( req.getServerPort() == 80 ? "" : ":" + req.getServerPort() ) + req.getContextPath();
}
}

View File

@ -0,0 +1,48 @@
package org.apache.archiva.rest.services.interceptors;
/*
* 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 javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
/**
* @author Olivier Lamy
* @since 1.4
*/
public class HttpContext
implements Serializable
{
private HttpServletRequest httpServletRequest;
public HttpContext()
{
// no op
}
public HttpServletRequest getHttpServletRequest()
{
return httpServletRequest;
}
public HttpContext setHttpServletRequest( HttpServletRequest httpServletRequest )
{
this.httpServletRequest = httpServletRequest;
return this;
}
}

View File

@ -0,0 +1,41 @@
package org.apache.archiva.rest.services.interceptors;
/*
* 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.codehaus.redback.rest.services.RedbackRequestInformation;
/**
* @author Olivier Lamy
* @since 1.4
*/
public class HttpContextThreadLocal
{
private static final ThreadLocal<HttpContext> userThreadLocal =
new ThreadLocal<HttpContext>();
public static void set( HttpContext httpContext )
{
userThreadLocal.set( httpContext );
}
public static HttpContext get()
{
return userThreadLocal.get();
}
}

View File

@ -0,0 +1,77 @@
package org.apache.archiva.rest.services.interceptors;
/*
* 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.cxf.interceptor.Fault;
import org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor;
import org.apache.cxf.jaxrs.model.OperationResourceInfo;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.phase.PhaseInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.ws.rs.core.Response;
/**
* @author Olivier Lamy
* @since 1.4
*/
@Service( "httpContextThreadLocalCleaner#rest" )
public class HttpContextThreadLocalCleaner
extends AbstractPhaseInterceptor<Message>
implements PhaseInterceptor<Message>
{
private Logger log = LoggerFactory.getLogger( getClass() );
public HttpContextThreadLocalCleaner( String phase )
{
super( phase );
addAfter( JAXRSInInterceptor.class.getName() );
}
public HttpContextThreadLocalCleaner()
{
super( Phase.PRE_STREAM );
addAfter( JAXRSInInterceptor.class.getName() );
}
public Response handleResponse( Message message, OperationResourceInfo operationResourceInfo, Response response )
{
log.debug( "handleResponse" );
cleanup();
return null;
}
private void cleanup()
{
HttpContextThreadLocal.set( null );
}
public void handleMessage( Message message )
throws Fault
{
log.debug( "handleMessage" );
cleanup();
}
}

View File

@ -0,0 +1,47 @@
package org.apache.archiva.rest.services.interceptors;
/*
* 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.cxf.jaxrs.ext.RequestHandler;
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
import org.apache.cxf.message.Message;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Response;
/**
* @author Olivier Lamy
*/
@Service( "httpContextThreadLocalInterceptor#rest" )
public class HttpContextThreadLocalInterceptor
implements RequestHandler
{
public Response handleRequest( Message m, ClassResourceInfo resourceClass )
{
HttpContextThreadLocal.set( new HttpContext().setHttpServletRequest( getHttpServletRequest( m ) ) );
return null;
}
public HttpServletRequest getHttpServletRequest( Message message )
{
// FIXME use a constant from cxf
return (HttpServletRequest) message.get( "HTTP.REQUEST" );
}
}

View File

@ -44,7 +44,7 @@
<jaxrs:providers>
<ref bean="authenticationInterceptor#rest"/>
<ref bean="permissionInterceptor#rest"/>
<ref bean="repositoriesService#rest"/>
<ref bean="httpContextThreadLocalInterceptor#rest"/>
</jaxrs:providers>
<jaxrs:serviceBeans>
@ -61,6 +61,7 @@
<jaxrs:outInterceptors>
<ref bean="threadLocalUserCleaner#rest"/>
<ref bean="httpContextThreadLocalCleaner#rest"/>
</jaxrs:outInterceptors>
</jaxrs:server>

View File

@ -214,6 +214,7 @@ public class SearchServiceTest
assertTrue( " not 1 results for Bundle ExportPackage org.apache.karaf.features.command.completers but "
+ artifacts.size() + ":" + artifacts, artifacts.size() == 1 );
log.info( "artifcat url " + artifacts.get( 0 ).getUrl() );
deleteTestRepo( testRepoId, targetRepo );
}