This project has retired. For details please refer to its
Attic page.
DefaultSearchService xref
1 package org.apache.archiva.rest.services;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.archiva.common.utils.VersionComparator;
23 import org.apache.archiva.indexer.search.RepositorySearch;
24 import org.apache.archiva.indexer.search.RepositorySearchException;
25 import org.apache.archiva.indexer.search.SearchFields;
26 import org.apache.archiva.indexer.search.SearchResultHit;
27 import org.apache.archiva.indexer.search.SearchResultLimits;
28 import org.apache.archiva.indexer.search.SearchResults;
29 import org.apache.archiva.maven2.model.Artifact;
30 import org.apache.archiva.metadata.model.ArtifactMetadata;
31 import org.apache.archiva.metadata.repository.MetadataRepository;
32 import org.apache.archiva.metadata.repository.MetadataRepositoryException;
33 import org.apache.archiva.metadata.repository.RepositorySession;
34 import org.apache.archiva.metadata.repository.RepositorySessionFactory;
35 import org.apache.archiva.rest.api.model.ChecksumSearch;
36 import org.apache.archiva.rest.api.model.GroupIdList;
37 import org.apache.archiva.rest.api.model.SearchRequest;
38 import org.apache.archiva.rest.api.model.StringList;
39 import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
40 import org.apache.archiva.rest.api.services.SearchService;
41 import org.apache.commons.collections.ListUtils;
42 import org.apache.commons.lang.StringUtils;
43 import org.springframework.stereotype.Service;
44
45 import javax.inject.Inject;
46 import javax.ws.rs.core.Response;
47 import java.net.URI;
48 import java.util.ArrayList;
49 import java.util.Arrays;
50 import java.util.Collection;
51 import java.util.Collections;
52 import java.util.HashSet;
53 import java.util.List;
54 import java.util.Set;
55 import java.util.TreeMap;
56
57
58
59
60 @Service( "searchService#rest" )
61 public class DefaultSearchService
62 extends AbstractRestService
63 implements SearchService
64 {
65
66 private static final String LATEST_KEYWORD = "LATEST";
67
68 @Inject
69 private RepositorySearch repositorySearch;
70
71 @Inject
72 private RepositorySessionFactory repositorySessionFactory;
73
74 @Override
75 public List<Artifact> quickSearch( String queryString )
76 throws ArchivaRestServiceException
77 {
78 if ( StringUtils.isBlank( queryString ) )
79 {
80 return Collections.emptyList( );
81 }
82
83 SearchResultLimits limits = new SearchResultLimits( 0 );
84 try
85 {
86 SearchResults searchResults =
87 repositorySearch.search( getPrincipal( ), getObservableRepos( ), queryString, limits,
88 Collections.<String>emptyList( ) );
89 return getArtifacts( searchResults );
90
91 }
92 catch ( RepositorySearchException e )
93 {
94 log.error( e.getMessage( ), e );
95 throw new ArchivaRestServiceException( e.getMessage( ), e );
96 }
97 }
98
99 @Override
100 public List<Artifact> quickSearchWithRepositories( SearchRequest searchRequest )
101 throws ArchivaRestServiceException
102 {
103 String queryString = searchRequest.getQueryTerms( );
104 if ( StringUtils.isBlank( queryString ) )
105 {
106 return Collections.emptyList( );
107 }
108 List<String> repositories = searchRequest.getRepositories( );
109 if ( repositories == null || repositories.isEmpty( ) )
110 {
111 repositories = getObservableRepos( );
112 }
113 SearchResultLimits limits =
114 new SearchResultLimits( searchRequest.getPageSize( ), searchRequest.getSelectedPage( ) );
115 try
116 {
117 SearchResults searchResults = repositorySearch.search( getPrincipal( ), repositories, queryString, limits,
118 Collections.<String>emptyList( ) );
119 return getArtifacts( searchResults );
120
121 }
122 catch ( RepositorySearchException e )
123 {
124 log.error( e.getMessage( ), e );
125 throw new ArchivaRestServiceException( e.getMessage( ), e );
126 }
127 }
128
129 @Override
130 public List<Artifact> getArtifactVersions( String groupId, String artifactId, String packaging )
131 throws ArchivaRestServiceException
132 {
133 if ( StringUtils.isBlank( groupId ) || StringUtils.isBlank( artifactId ) )
134 {
135 return Collections.emptyList( );
136 }
137 SearchFields searchField = new SearchFields( );
138 searchField.setGroupId( groupId );
139 searchField.setArtifactId( artifactId );
140 searchField.setPackaging( StringUtils.isBlank( packaging ) ? "jar" : packaging );
141 searchField.setRepositories( getObservableRepos( ) );
142
143 try
144 {
145 SearchResults searchResults = repositorySearch.search( getPrincipal( ), searchField, null );
146 return getArtifacts( searchResults );
147 }
148 catch ( RepositorySearchException e )
149 {
150 log.error( e.getMessage( ), e );
151 throw new ArchivaRestServiceException( e.getMessage( ), e );
152 }
153 }
154
155 @Override
156 public List<Artifact> searchArtifacts( SearchRequest searchRequest )
157 throws ArchivaRestServiceException
158 {
159 if ( searchRequest == null )
160 {
161 return Collections.emptyList( );
162 }
163 SearchFields searchField = getModelMapper( ).map( searchRequest, SearchFields.class );
164 SearchResultLimits limits = new SearchResultLimits( 0 );
165 limits.setPageSize( searchRequest.getPageSize( ) );
166
167
168 if ( searchField.getRepositories( ) == null || searchField.getRepositories( ).isEmpty( ) )
169 {
170 searchField.setRepositories( getObservableRepos( ) );
171 }
172
173 try
174 {
175 SearchResults searchResults = repositorySearch.search( getPrincipal( ), searchField, limits );
176 return getArtifacts( searchResults );
177 }
178 catch ( RepositorySearchException e )
179 {
180 log.error( e.getMessage( ), e );
181 throw new ArchivaRestServiceException( e.getMessage( ), e );
182 }
183 }
184
185 @Override
186 public GroupIdList getAllGroupIds( List<String> selectedRepos )
187 throws ArchivaRestServiceException
188 {
189 List<String> observableRepos = getObservableRepos( );
190 List<String> repos = ListUtils.intersection( observableRepos, selectedRepos );
191 if ( repos == null || repos.isEmpty( ) )
192 {
193 return new GroupIdList( Collections.<String>emptyList( ) );
194 }
195 try
196 {
197 return new GroupIdList( new ArrayList<>( repositorySearch.getAllGroupIds( getPrincipal( ), repos ) ) );
198 }
199 catch ( RepositorySearchException e )
200 {
201 log.error( e.getMessage( ), e );
202 throw new ArchivaRestServiceException( e.getMessage( ), e );
203 }
204
205 }
206
207
208 public List<Artifact> getArtifactByChecksum( ChecksumSearch checksumSearch )
209 throws ArchivaRestServiceException
210 {
211
212
213 if ( checksumSearch.getRepositories( ) == null || checksumSearch.getRepositories( ).isEmpty( ) )
214 {
215 checksumSearch.setRepositories( getObservableRepos( ) );
216 }
217
218 RepositorySession repositorySession = repositorySessionFactory.createSession( );
219
220 MetadataRepository metadataRepository = repositorySession.getRepository( );
221
222 Set<Artifact> artifactSet = new HashSet<>( );
223
224 try
225 {
226 for ( String repoId : checksumSearch.getRepositories( ) )
227 {
228 Collection<ArtifactMetadata> artifactMetadatas =
229 metadataRepository.getArtifactsByChecksum( repoId, checksumSearch.getChecksum( ) );
230 artifactSet.addAll( buildArtifacts( artifactMetadatas, repoId ) );
231 }
232
233 return new ArrayList<>( artifactSet );
234
235 }
236 catch ( MetadataRepositoryException e )
237 {
238 log.error( e.getMessage( ), e );
239 throw new ArchivaRestServiceException( e.getMessage( ), e );
240 }
241 finally
242 {
243 repositorySession.closeQuietly( );
244 }
245
246
247 }
248
249 @Override
250 public StringList getObservablesRepoIds( )
251 throws ArchivaRestServiceException
252 {
253 return new StringList( getObservableRepos( ) );
254 }
255
256 @Override
257 public Response redirectToArtifactFile( String repositoryId, String groupId, String artifactId, String version,
258 String packaging, String classifier, Boolean literalVersion )
259 throws ArchivaRestServiceException
260 {
261 try
262 {
263
264
265 if ( StringUtils.isEmpty( groupId ) )
266 {
267 return Response.status( new Response.StatusType( )
268 {
269 @Override
270 public int getStatusCode( )
271 {
272 return Response.Status.BAD_REQUEST.getStatusCode( );
273 }
274
275 @Override
276 public Response.Status.Family getFamily( )
277 {
278 return Response.Status.BAD_REQUEST.getFamily( );
279 }
280
281 @Override
282 public String getReasonPhrase( )
283 {
284 return "groupId mandatory";
285 }
286 } ).build( );
287 }
288
289 if ( StringUtils.isEmpty( version ) )
290 {
291 return Response.status( new Response.StatusType( )
292 {
293 @Override
294 public int getStatusCode( )
295 {
296 return Response.Status.BAD_REQUEST.getStatusCode( );
297 }
298
299 @Override
300 public Response.Status.Family getFamily( )
301 {
302 return Response.Status.BAD_REQUEST.getFamily( );
303 }
304
305 @Override
306 public String getReasonPhrase( )
307 {
308 return "version mandatory";
309 }
310 } ).build( );
311 }
312
313 if ( StringUtils.isEmpty( artifactId ) )
314 {
315 return Response.status( new Response.StatusType( )
316 {
317 @Override
318 public int getStatusCode( )
319 {
320 return Response.Status.BAD_REQUEST.getStatusCode( );
321 }
322
323 @Override
324 public Response.Status.Family getFamily( )
325 {
326 return Response.Status.BAD_REQUEST.getFamily( );
327 }
328
329 @Override
330 public String getReasonPhrase( )
331 {
332 return "artifactId mandatory";
333 }
334 } ).build( );
335 }
336
337 SearchFields searchField = new SearchFields( );
338 searchField.setGroupId( groupId );
339 searchField.setArtifactId( artifactId );
340 searchField.setPackaging( StringUtils.isBlank( packaging ) ? "jar" : packaging );
341 if ( literalVersion.booleanValue( ) || !StringUtils.equals( version, LATEST_KEYWORD ) )
342 {
343 searchField.setVersion( version );
344 }
345 searchField.setClassifier( classifier );
346 List<String> userRepos = getObservablesRepoIds( ).getStrings( );
347 searchField.setRepositories(
348 StringUtils.isEmpty( repositoryId ) ? userRepos : Arrays.asList( repositoryId ) );
349 log.debug( "Searching repository {}", repositoryId );
350 searchField.setExactSearch( true );
351 SearchResults searchResults = repositorySearch.search( getPrincipal( ), searchField, null );
352 List<Artifact> artifacts = getArtifacts( searchResults, repositoryId );
353
354 if ( artifacts.isEmpty( ) )
355 {
356 return Response.status( new Response.StatusType( )
357 {
358 @Override
359 public int getStatusCode( )
360 {
361 return Response.Status.NO_CONTENT.getStatusCode( );
362 }
363
364 @Override
365 public Response.Status.Family getFamily( )
366 {
367 return Response.Status.NO_CONTENT.getFamily( );
368 }
369
370 @Override
371 public String getReasonPhrase( )
372 {
373 return "your query doesn't return any artifact";
374 }
375 } ).build( );
376 }
377
378
379
380 if ( classifier == null )
381 {
382 List<Artifact> filteredArtifacts = new ArrayList<>( artifacts.size( ) );
383 for ( Artifact artifact : artifacts )
384 {
385 if ( artifact.getClassifier( ) == null )
386 {
387 filteredArtifacts.add( artifact );
388 }
389 }
390
391 artifacts = filteredArtifacts;
392 }
393
394
395 if ( artifacts.size( ) > 1 && ( literalVersion || !StringUtils.equals( version, LATEST_KEYWORD ) ) )
396 {
397 return Response.status( new Response.StatusType( )
398 {
399 @Override
400 public int getStatusCode( )
401 {
402 return Response.Status.BAD_REQUEST.getStatusCode( );
403 }
404
405 @Override
406 public Response.Status.Family getFamily( )
407 {
408 return Response.Status.BAD_REQUEST.getFamily( );
409 }
410
411 @Override
412 public String getReasonPhrase( )
413 {
414 return "your query return more than one artifact";
415 }
416 } ).build( );
417 }
418
419
420 if ( !literalVersion && ( artifacts.size( ) > 1 && StringUtils.equals( version, LATEST_KEYWORD ) ) )
421 {
422 TreeMap<String, Artifact> artifactPerVersion = new TreeMap<>( VersionComparator.getInstance( ) );
423
424 for ( Artifact artifact : artifacts )
425 {
426 artifactPerVersion.put( artifact.getVersion( ), artifact );
427 }
428
429 return Response.temporaryRedirect(
430 new URI( artifactPerVersion.lastEntry( ).getValue( ).getUrl( ) ) ).build( );
431
432 }
433
434 Artifact artifact = artifacts.get( 0 );
435 log.debug( "Returning artifact {}, {}", artifact.getUrl( ), artifact.getRepositoryId( ) );
436 return Response.temporaryRedirect( new URI( artifact.getUrl( ) ) ).build( );
437 }
438 catch ( Exception e )
439 {
440 throw new ArchivaRestServiceException( e.getMessage( ), e );
441 }
442 }
443
444 protected List<Artifact> getArtifacts( SearchResults searchResults )
445 throws ArchivaRestServiceException
446 {
447 return getArtifacts( searchResults, null );
448 }
449
450
451
452
453 protected List<Artifact> getArtifacts( SearchResults searchResults, String repositoryId )
454 throws ArchivaRestServiceException
455 {
456
457 if ( searchResults == null || searchResults.isEmpty() )
458 {
459 return Collections.emptyList();
460 }
461 List<Artifact> artifacts = new ArrayList<>( searchResults.getReturnedHitsCount() );
462 for ( SearchResultHit hit : searchResults.getHits() )
463 {
464
465 if ( hit.getVersions().size() > 0 )
466 {
467 for ( String version : hit.getVersions() )
468 {
469
470 Artifact versionned = getModelMapper().map( hit, Artifact.class );
471
472 if ( StringUtils.isNotBlank( version ) )
473 {
474 versionned.setVersion( version );
475 versionned.setUrl( getArtifactUrl( versionned, repositoryId ) );
476
477 artifacts.add( versionned );
478
479 }
480 }
481 }
482 }
483 return artifacts;
484 }
485
486
487 }