]> source.dussan.org Git - archiva.git/blob
f030a3b86ae6b5f7b4a99166b3851d4f9c213722
[archiva.git] /
1 package org.apache.archiva.rest.services;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *   http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
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.maven2.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.model.StringList;
33 import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
34 import org.apache.archiva.rest.api.services.SearchService;
35 import org.apache.commons.collections.ListUtils;
36 import org.apache.commons.lang.StringUtils;
37 import org.springframework.stereotype.Service;
38
39 import javax.inject.Inject;
40 import javax.ws.rs.core.Response;
41 import java.net.URI;
42 import java.util.ArrayList;
43 import java.util.Arrays;
44 import java.util.Collections;
45 import java.util.List;
46
47 /**
48  * @author Olivier Lamy
49  */
50 @Service("searchService#rest")
51 public class DefaultSearchService
52     extends AbstractRestService
53     implements SearchService
54 {
55
56     @Inject
57     private RepositorySearch repositorySearch;
58
59     @Override
60     public List<Artifact> quickSearch( String queryString )
61         throws ArchivaRestServiceException
62     {
63         if ( StringUtils.isBlank( queryString ) )
64         {
65             return Collections.emptyList();
66         }
67
68         SearchResultLimits limits = new SearchResultLimits( 0 );
69         try
70         {
71             SearchResults searchResults =
72                 repositorySearch.search( getPrincipal(), getObservableRepos(), queryString, limits,
73                                          Collections.<String>emptyList() );
74             return getArtifacts( searchResults );
75
76         }
77         catch ( RepositorySearchException e )
78         {
79             log.error( e.getMessage(), e );
80             throw new ArchivaRestServiceException( e.getMessage(), e );
81         }
82     }
83
84     @Override
85     public List<Artifact> quickSearchWithRepositories( SearchRequest searchRequest )
86         throws ArchivaRestServiceException
87     {
88         String queryString = searchRequest.getQueryTerms();
89         if ( StringUtils.isBlank( queryString ) )
90         {
91             return Collections.emptyList();
92         }
93         List<String> repositories = searchRequest.getRepositories();
94         if ( repositories == null || repositories.isEmpty() )
95         {
96             repositories = getObservableRepos();
97         }
98         SearchResultLimits limits =
99             new SearchResultLimits( searchRequest.getPageSize(), searchRequest.getSelectedPage() );
100         try
101         {
102             SearchResults searchResults = repositorySearch.search( getPrincipal(), repositories, queryString, limits,
103                                                                    Collections.<String>emptyList() );
104             return getArtifacts( searchResults );
105
106         }
107         catch ( RepositorySearchException e )
108         {
109             log.error( e.getMessage(), e );
110             throw new ArchivaRestServiceException( e.getMessage(), e );
111         }
112     }
113
114     @Override
115     public List<Artifact> getArtifactVersions( String groupId, String artifactId, String packaging )
116         throws ArchivaRestServiceException
117     {
118         if ( StringUtils.isBlank( groupId ) || StringUtils.isBlank( artifactId ) )
119         {
120             return Collections.emptyList();
121         }
122         SearchFields searchField = new SearchFields();
123         searchField.setGroupId( groupId );
124         searchField.setArtifactId( artifactId );
125         searchField.setPackaging( StringUtils.isBlank( packaging ) ? "jar" : packaging );
126         searchField.setRepositories( getObservableRepos() );
127
128         try
129         {
130             SearchResults searchResults = repositorySearch.search( getPrincipal(), searchField, null );
131             return getArtifacts( searchResults );
132         }
133         catch ( RepositorySearchException e )
134         {
135             log.error( e.getMessage(), e );
136             throw new ArchivaRestServiceException( e.getMessage(), e );
137         }
138     }
139
140     @Override
141     public List<Artifact> searchArtifacts( SearchRequest searchRequest )
142         throws ArchivaRestServiceException
143     {
144         if ( searchRequest == null )
145         {
146             return Collections.emptyList();
147         }
148         SearchFields searchField = getModelMapper().map( searchRequest, SearchFields.class );
149         SearchResultLimits limits = new SearchResultLimits( 0 );
150         limits.setPageSize( searchRequest.getPageSize() );
151
152         // if no repos set we use ones available for the user
153         if ( searchField.getRepositories() == null || searchField.getRepositories().isEmpty() )
154         {
155             searchField.setRepositories( getObservableRepos() );
156         }
157
158         try
159         {
160             SearchResults searchResults = repositorySearch.search( getPrincipal(), searchField, limits );
161             return getArtifacts( searchResults );
162         }
163         catch ( RepositorySearchException e )
164         {
165             log.error( e.getMessage(), e );
166             throw new ArchivaRestServiceException( e.getMessage(), e );
167         }
168     }
169
170     @Override
171     public GroupIdList getAllGroupIds( List<String> selectedRepos )
172         throws ArchivaRestServiceException
173     {
174         List<String> observableRepos = getObservableRepos();
175         List<String> repos = ListUtils.intersection( observableRepos, selectedRepos );
176         if ( repos == null || repos.isEmpty() )
177         {
178             return new GroupIdList( Collections.<String>emptyList() );
179         }
180         try
181         {
182             return new GroupIdList( new ArrayList<>( repositorySearch.getAllGroupIds( getPrincipal(), repos ) ) );
183         }
184         catch ( RepositorySearchException e )
185         {
186             log.error( e.getMessage(), e );
187             throw new ArchivaRestServiceException( e.getMessage(), e );
188         }
189
190     }
191
192     public List<Dependency> getDependencies( String groupId, String artifactId, String version )
193         throws ArchivaRestServiceException
194     {
195         return null;  //To change body of implemented methods use File | Settings | File Templates.
196     }
197
198     public List<Artifact> getArtifactByChecksum( String checksum )
199         throws ArchivaRestServiceException
200     {
201         return null;  //To change body of implemented methods use File | Settings | File Templates.
202     }
203
204     @Override
205     public StringList getObservablesRepoIds()
206         throws ArchivaRestServiceException
207     {
208         return new StringList( getObservableRepos() );
209     }
210
211     @Override
212     public Response redirectToArtifactFile( String repositoryId, String groupId, String artifactId, String version,
213                                             String packaging, String classifier )
214         throws ArchivaRestServiceException
215     {
216         try
217         {
218             // validate query
219
220             if ( StringUtils.isEmpty( groupId ) )
221             {
222                 return Response.status( new Response.StatusType()
223                 {
224                     @Override
225                     public int getStatusCode()
226                     {
227                         return Response.Status.BAD_REQUEST.getStatusCode();
228                     }
229
230                     @Override
231                     public Response.Status.Family getFamily()
232                     {
233                         return Response.Status.BAD_REQUEST.getFamily();
234                     }
235
236                     @Override
237                     public String getReasonPhrase()
238                     {
239                         return "groupId mandatory";
240                     }
241                 } ).build();
242             }
243
244             if ( StringUtils.isEmpty( artifactId ) )
245             {
246                 return Response.status( new Response.StatusType()
247                 {
248                     @Override
249                     public int getStatusCode()
250                     {
251                         return Response.Status.BAD_REQUEST.getStatusCode();
252                     }
253
254                     @Override
255                     public Response.Status.Family getFamily()
256                     {
257                         return Response.Status.BAD_REQUEST.getFamily();
258                     }
259
260                     @Override
261                     public String getReasonPhrase()
262                     {
263                         return "artifactId mandatory";
264                     }
265                 } ).build();
266             }
267
268             if ( StringUtils.isEmpty( version ) )
269             {
270                 return Response.status( new Response.StatusType()
271                 {
272                     @Override
273                     public int getStatusCode()
274                     {
275                         return Response.Status.BAD_REQUEST.getStatusCode();
276                     }
277
278                     @Override
279                     public Response.Status.Family getFamily()
280                     {
281                         return Response.Status.BAD_REQUEST.getFamily();
282                     }
283
284                     @Override
285                     public String getReasonPhrase()
286                     {
287                         return "version mandatory";
288                     }
289                 } ).build();
290             }
291
292             SearchFields searchField = new SearchFields();
293             searchField.setGroupId( groupId );
294             searchField.setArtifactId( artifactId );
295             searchField.setPackaging( StringUtils.isBlank( packaging ) ? "jar" : packaging );
296             searchField.setVersion( version );
297             searchField.setClassifier( classifier );
298             List<String> userRepos = getObservablesRepoIds().getStrings();
299             searchField.setRepositories(
300                 StringUtils.isEmpty( repositoryId ) ? userRepos : Arrays.asList( repositoryId ) );
301             searchField.setExactSearch( true );
302             SearchResults searchResults = repositorySearch.search( getPrincipal(), searchField, null );
303             List<Artifact> artifacts = getArtifacts( searchResults );
304
305             if ( artifacts.isEmpty() )
306             {
307                 return Response.status( new Response.StatusType()
308                 {
309                     @Override
310                     public int getStatusCode()
311                     {
312                         return Response.Status.NO_CONTENT.getStatusCode();
313                     }
314
315                     @Override
316                     public Response.Status.Family getFamily()
317                     {
318                         return Response.Status.NO_CONTENT.getFamily();
319                     }
320
321                     @Override
322                     public String getReasonPhrase()
323                     {
324                         return "your query doesn't return any artifact";
325                     }
326                 } ).build();
327             }
328
329             // TODO improve that with querying lucene with null value for classifier
330             // so simple loop and retain only artifact with null classifier
331             if ( classifier == null )
332             {
333                 List<Artifact> filteredArtifacts = new ArrayList<>( artifacts.size() );
334                 for ( Artifact artifact : artifacts )
335                 {
336                     if ( artifact.getClassifier() == null )
337                     {
338                         filteredArtifacts.add( artifact );
339                     }
340                 }
341
342                 artifacts = filteredArtifacts;
343             }
344
345             // TODO return json result of the query ?
346             if ( artifacts.size() > 1 )
347             {
348                 return Response.status( new Response.StatusType()
349                 {
350                     @Override
351                     public int getStatusCode()
352                     {
353                         return Response.Status.BAD_REQUEST.getStatusCode();
354                     }
355
356                     @Override
357                     public Response.Status.Family getFamily()
358                     {
359                         return Response.Status.BAD_REQUEST.getFamily();
360                     }
361
362                     @Override
363                     public String getReasonPhrase()
364                     {
365                         return "your query return more than one artifact";
366                     }
367                 } ).build();
368             }
369
370             Artifact artifact = artifacts.get( 0 );
371
372             return Response.temporaryRedirect( new URI( artifact.getUrl() ) ).build();
373         }
374         catch ( Exception e )
375         {
376             throw new ArchivaRestServiceException( e.getMessage(), e );
377         }
378     }
379
380     //-------------------------------------
381     // internal
382     //-------------------------------------
383     protected List<Artifact> getArtifacts( SearchResults searchResults )
384         throws ArchivaRestServiceException
385     {
386
387         if ( searchResults == null || searchResults.isEmpty() )
388         {
389             return Collections.emptyList();
390         }
391         List<Artifact> artifacts = new ArrayList<>( searchResults.getReturnedHitsCount() );
392         for ( SearchResultHit hit : searchResults.getHits() )
393         {
394             // duplicate Artifact one per available version
395             if ( hit.getVersions().size() > 0 )
396             {
397                 for ( String version : hit.getVersions() )
398                 {
399
400                     Artifact versionned = getModelMapper().map( hit, Artifact.class );
401
402                     if ( StringUtils.isNotBlank( version ) )
403                     {
404                         versionned.setVersion( version );
405                         versionned.setUrl( getArtifactUrl( versionned ) );
406
407                         artifacts.add( versionned );
408
409                     }
410                 }
411             }
412         }
413         return artifacts;
414     }
415
416
417 }