1 package org.apache.archiva.rest.services;
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
21 import net.sf.beanlib.provider.replicator.BeanReplicator;
22 import org.apache.archiva.indexer.search.RepositorySearch;
23 import org.apache.archiva.indexer.search.RepositorySearchException;
24 import org.apache.archiva.indexer.search.SearchFields;
25 import org.apache.archiva.indexer.search.SearchResultHit;
26 import org.apache.archiva.indexer.search.SearchResultLimits;
27 import org.apache.archiva.indexer.search.SearchResults;
28 import org.apache.archiva.rest.api.model.Artifact;
29 import org.apache.archiva.rest.api.model.Dependency;
30 import org.apache.archiva.rest.api.model.GroupIdList;
31 import org.apache.archiva.rest.api.model.SearchRequest;
32 import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
33 import org.apache.archiva.rest.api.services.SearchService;
34 import org.apache.archiva.security.AccessDeniedException;
35 import org.apache.archiva.security.ArchivaSecurityException;
36 import org.apache.archiva.security.PrincipalNotFoundException;
37 import org.apache.archiva.security.UserRepositories;
38 import org.apache.commons.collections.ListUtils;
39 import org.apache.commons.lang.StringUtils;
40 import org.codehaus.plexus.redback.users.UserManager;
41 import org.codehaus.redback.rest.services.RedbackAuthenticationThreadLocal;
42 import org.codehaus.redback.rest.services.RedbackRequestInformation;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45 import org.springframework.stereotype.Service;
47 import javax.inject.Inject;
48 import javax.servlet.http.HttpServletRequest;
49 import javax.ws.rs.core.Context;
50 import java.util.ArrayList;
51 import java.util.Collections;
52 import java.util.List;
55 * @author Olivier Lamy
57 @Service( "searchService#rest" )
58 public class DefaultSearchService
59 implements SearchService
62 private Logger log = LoggerFactory.getLogger( getClass() );
65 private RepositorySearch repositorySearch;
68 private UserRepositories userRepositories;
71 private HttpServletRequest httpServletRequest;
73 public List<Artifact> quickSearch( String queryString )
74 throws ArchivaRestServiceException
76 if ( StringUtils.isBlank( queryString ) )
78 return Collections.emptyList();
81 SearchResultLimits limits = new SearchResultLimits( 0 );
82 List<String> observableRepoIds = getObservableRepos();
85 SearchResults searchResults =
86 repositorySearch.search( getPrincipal(), getObservableRepos(), queryString, limits,
87 Collections.<String>emptyList() );
88 return getArtifacts( searchResults );
91 catch ( RepositorySearchException e )
93 log.error( e.getMessage(), e );
94 throw new ArchivaRestServiceException( e.getMessage() );
98 public List<Artifact> getArtifactVersions( String groupId, String artifactId, String packaging )
99 throws ArchivaRestServiceException
101 if ( StringUtils.isBlank( groupId ) || StringUtils.isBlank( artifactId ) )
103 return Collections.emptyList();
105 SearchFields searchField = new SearchFields();
106 searchField.setGroupId( groupId );
107 searchField.setArtifactId( artifactId );
108 searchField.setPackaging( StringUtils.isBlank( packaging ) ? "jar" : packaging );
109 searchField.setRepositories( getObservableRepos() );
113 SearchResults searchResults = repositorySearch.search( getPrincipal(), searchField, null );
114 return getArtifacts( searchResults );
116 catch ( RepositorySearchException e )
118 log.error( e.getMessage(), e );
119 throw new ArchivaRestServiceException( e.getMessage() );
123 public List<Artifact> searchArtifacts( SearchRequest searchRequest )
124 throws ArchivaRestServiceException
126 if ( searchRequest == null )
128 return Collections.emptyList();
130 SearchFields searchField = new BeanReplicator().replicateBean( searchRequest, SearchFields.class );
131 SearchResultLimits limits = new SearchResultLimits( 0 );
133 // if no repos set we use ones available for the user
134 if ( searchField.getRepositories() == null || searchField.getRepositories().isEmpty() )
136 searchField.setRepositories( getObservableRepos() );
141 SearchResults searchResults = repositorySearch.search( getPrincipal(), searchField, limits );
142 return getArtifacts( searchResults );
144 catch ( RepositorySearchException e )
146 log.error( e.getMessage(), e );
147 throw new ArchivaRestServiceException( e.getMessage() );
151 public GroupIdList getAllGroupIds( List<String> selectedRepos )
152 throws ArchivaRestServiceException
154 List<String> observableRepos = getObservableRepos();
155 List<String> repos = ListUtils.intersection( observableRepos, selectedRepos );
156 if ( repos == null || repos.isEmpty() )
158 return new GroupIdList( Collections.<String>emptyList() );
162 return new GroupIdList( new ArrayList<String>( repositorySearch.getAllGroupIds( getPrincipal(), repos ) ) );
164 catch ( RepositorySearchException e )
166 log.error( e.getMessage(), e );
167 throw new ArchivaRestServiceException( e.getMessage() );
172 public List<Dependency> getDependencies( String groupId, String artifactId, String version )
173 throws ArchivaRestServiceException
175 return null; //To change body of implemented methods use File | Settings | File Templates.
178 public List<Artifact> getArtifactByChecksum( String checksum )
179 throws ArchivaRestServiceException
181 return null; //To change body of implemented methods use File | Settings | File Templates.
185 protected List<String> getObservableRepos()
189 List<String> ids = userRepositories.getObservableRepositoryIds( getPrincipal() );
190 return ids == null ? Collections.<String>emptyList() : ids;
192 catch ( PrincipalNotFoundException e )
194 log.warn( e.getMessage(), e );
196 catch ( AccessDeniedException e )
198 log.warn( e.getMessage(), e );
200 catch ( ArchivaSecurityException e )
202 log.warn( e.getMessage(), e );
204 return Collections.emptyList();
207 protected String getPrincipal()
209 RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get();
211 return redbackRequestInformation == null
212 ? UserManager.GUEST_USERNAME
213 : ( redbackRequestInformation.getUser() == null
214 ? UserManager.GUEST_USERNAME
215 : redbackRequestInformation.getUser().getUsername() );
218 protected List<Artifact> getArtifacts( SearchResults searchResults )
221 if ( searchResults == null || searchResults.isEmpty() )
223 return Collections.emptyList();
225 List<Artifact> artifacts = new ArrayList<Artifact>( searchResults.getReturnedHitsCount() );
226 for ( SearchResultHit hit : searchResults.getHits() )
228 // duplicate Artifact one per available version
229 if ( hit.getVersions().size() > 0 )
231 for ( String version : hit.getVersions() )
234 Artifact versionned = new BeanReplicator().replicateBean( hit, Artifact.class );
236 if ( StringUtils.isNotBlank( version ) )
238 versionned.setVersion( version );
239 versionned.setUrl( getArtifactUrl( versionned ) );
241 artifacts.add( versionned );
251 * TODO add a configuration mechanism to have configured the base archiva url
255 private String getArtifactUrl( Artifact artifact )
258 if ( httpServletRequest == null )
262 if ( StringUtils.isEmpty( artifact.getUrl() ) )
266 StringBuilder sb = new StringBuilder( getBaseUrl( httpServletRequest ) );
268 sb.append( "/repository" );
269 if ( !StringUtils.startsWith( artifact.getUrl(), "/" ) )
273 sb.append( artifact.getUrl() );
274 return sb.toString();
277 protected String getBaseUrl( HttpServletRequest req )
279 return req.getScheme() + "://" + req.getServerName() + ( req.getServerPort() == 80
281 : ":" + req.getServerPort() ) + req.getContextPath();