This project has retired. For details please refer to its Attic page.
MavenRepositorySearch xref
View Javadoc
1   package org.apache.archiva.indexer.maven.search;
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.admin.model.RepositoryAdminException;
23  import org.apache.archiva.admin.model.beans.ProxyConnector;
24  import org.apache.archiva.admin.model.proxyconnector.ProxyConnectorAdmin;
25  import org.apache.archiva.indexer.UnsupportedBaseContextException;
26  import org.apache.archiva.indexer.search.ArtifactInfoFilter;
27  import org.apache.archiva.indexer.search.NoClassifierArtifactInfoFilter;
28  import org.apache.archiva.indexer.search.RepositorySearch;
29  import org.apache.archiva.indexer.search.RepositorySearchException;
30  import org.apache.archiva.indexer.search.SearchFields;
31  import org.apache.archiva.indexer.search.SearchResultHit;
32  import org.apache.archiva.indexer.search.SearchResultLimits;
33  import org.apache.archiva.indexer.search.SearchResults;
34  import org.apache.archiva.indexer.util.SearchUtil;
35  import org.apache.archiva.model.ArchivaArtifactModel;
36  import org.apache.archiva.repository.RemoteRepository;
37  import org.apache.archiva.repository.Repository;
38  import org.apache.archiva.repository.RepositoryRegistry;
39  import org.apache.archiva.repository.RepositoryType;
40  import org.apache.commons.lang3.StringUtils;
41  import org.apache.maven.index.ArtifactInfo;
42  import org.apache.maven.index.FlatSearchRequest;
43  import org.apache.maven.index.FlatSearchResponse;
44  import org.apache.maven.index.Indexer;
45  import org.apache.maven.index.MAVEN;
46  import org.apache.maven.index.OSGI;
47  import org.apache.maven.index.QueryCreator;
48  import org.apache.maven.index.SearchType;
49  import org.apache.maven.index.context.IndexingContext;
50  import org.apache.maven.index.expr.SearchExpression;
51  import org.apache.maven.index.expr.SearchTyped;
52  import org.apache.maven.index.expr.SourcedSearchExpression;
53  import org.apache.maven.index.expr.UserInputSearchExpression;
54  import org.apache.maven.index_shaded.lucene.search.BooleanClause;
55  import org.apache.maven.index_shaded.lucene.search.BooleanClause.Occur;
56  import org.apache.maven.index_shaded.lucene.search.BooleanQuery;
57  import org.slf4j.Logger;
58  import org.slf4j.LoggerFactory;
59  import org.springframework.stereotype.Service;
60  
61  import javax.inject.Inject;
62  import java.io.IOException;
63  import java.util.ArrayList;
64  import java.util.Collection;
65  import java.util.Collections;
66  import java.util.HashSet;
67  import java.util.List;
68  import java.util.Map;
69  import java.util.Set;
70  
71  /**
72   * RepositorySearch implementation which uses the Maven Indexer for searching.
73   */
74  @Service( "repositorySearch#maven" )
75  public class MavenRepositorySearch
76      implements RepositorySearch
77  {
78      private Logger log = LoggerFactory.getLogger( getClass() );
79  
80      private Indexer indexer;
81  
82      private QueryCreator queryCreator;
83  
84  
85      RepositoryRegistry repositoryRegistry;
86  
87      private ProxyConnectorAdmin proxyConnectorAdmin;
88  
89      protected MavenRepositorySearch()
90      {
91          // for test purpose
92      }
93  
94      @Inject
95      public MavenRepositorySearch( Indexer nexusIndexer, RepositoryRegistry repositoryRegistry,
96  
97                                    ProxyConnectorAdmin proxyConnectorAdmin, QueryCreator queryCreator )
98      {
99          this.indexer = nexusIndexer;
100         this.queryCreator = queryCreator;
101         this.repositoryRegistry = repositoryRegistry;
102         this.proxyConnectorAdmin = proxyConnectorAdmin;
103     }
104 
105     /**
106      * @see RepositorySearch#search(String, List, String, SearchResultLimits, List)
107      */
108     @Override
109     public SearchResults search(String principal, List<String> selectedRepos, String term, SearchResultLimits limits,
110                                 List<String> previousSearchTerms )
111         throws RepositorySearchException
112     {
113         List<String> indexingContextIds = addIndexingContexts( selectedRepos );
114 
115         // since upgrade to nexus 2.0.0, query has changed from g:[QUERIED TERM]* to g:*[QUERIED TERM]*
116         //      resulting to more wildcard searches so we need to increase max clause count
117         BooleanQuery.setMaxClauseCount( Integer.MAX_VALUE );
118         BooleanQuery.Builder qb = new BooleanQuery.Builder();
119 
120         if ( previousSearchTerms == null || previousSearchTerms.isEmpty() )
121         {
122             constructQuery( term, qb );
123         }
124         else
125         {
126             for ( String previousTerm : previousSearchTerms )
127             {
128                 BooleanQuery.Builder iQuery = new BooleanQuery.Builder();
129                 constructQuery( previousTerm, iQuery );
130 
131                 qb.add( iQuery.build(), BooleanClause.Occur.MUST );
132             }
133 
134             BooleanQuery.Builder iQuery = new BooleanQuery.Builder();
135             constructQuery( term, iQuery );
136             qb.add( iQuery.build(), BooleanClause.Occur.MUST );
137         }
138 
139         // we retun only artifacts without classifier in quick search, olamy cannot find a way to say with this field empty
140         // FIXME  cannot find a way currently to setup this in constructQuery !!!
141         return search( limits, qb.build(), indexingContextIds, NoClassifierArtifactInfoFilter.LIST, selectedRepos, true );
142 
143     }
144 
145     /**
146      * @see RepositorySearch#search(String, SearchFields, SearchResultLimits)
147      */
148     @SuppressWarnings( "deprecation" )
149     @Override
150     public SearchResults search( String principal, SearchFields searchFields, SearchResultLimits limits )
151         throws RepositorySearchException
152     {
153         if ( searchFields.getRepositories() == null )
154         {
155             throw new RepositorySearchException( "Repositories cannot be null." );
156         }
157 
158         List<String> indexingContextIds = addIndexingContexts( searchFields.getRepositories() );
159 
160         // if no index found in the specified ones return an empty search result instead of doing a search on all index
161         // olamy: IMHO doesn't make sense
162         if ( !searchFields.getRepositories().isEmpty() && ( indexingContextIds == null
163             || indexingContextIds.isEmpty() ) )
164         {
165             return new SearchResults();
166         }
167 
168         BooleanQuery.Builder qb = new BooleanQuery.Builder();
169         if ( StringUtils.isNotBlank( searchFields.getGroupId() ) )
170         {
171             qb.add( indexer.constructQuery( MAVEN.GROUP_ID, searchFields.isExactSearch() ? new SourcedSearchExpression(
172                        searchFields.getGroupId() ) : new UserInputSearchExpression( searchFields.getGroupId() ) ),
173                    BooleanClause.Occur.MUST );
174         }
175 
176         if ( StringUtils.isNotBlank( searchFields.getArtifactId() ) )
177         {
178             qb.add( indexer.constructQuery( MAVEN.ARTIFACT_ID,
179                                            searchFields.isExactSearch()
180                                                ? new SourcedSearchExpression( searchFields.getArtifactId() )
181                                                : new UserInputSearchExpression( searchFields.getArtifactId() ) ),
182                    BooleanClause.Occur.MUST );
183         }
184 
185         if ( StringUtils.isNotBlank( searchFields.getVersion() ) )
186         {
187             qb.add( indexer.constructQuery( MAVEN.VERSION, searchFields.isExactSearch() ? new SourcedSearchExpression(
188                        searchFields.getVersion() ) : new SourcedSearchExpression( searchFields.getVersion() ) ),
189                    BooleanClause.Occur.MUST );
190         }
191 
192         if ( StringUtils.isNotBlank( searchFields.getPackaging() ) )
193         {
194             qb.add( indexer.constructQuery( MAVEN.PACKAGING, searchFields.isExactSearch() ? new SourcedSearchExpression(
195                        searchFields.getPackaging() ) : new UserInputSearchExpression( searchFields.getPackaging() ) ),
196                    BooleanClause.Occur.MUST );
197         }
198 
199         if ( StringUtils.isNotBlank( searchFields.getClassName() ) )
200         {
201             qb.add( indexer.constructQuery( MAVEN.CLASSNAMES,
202                                            new UserInputSearchExpression( searchFields.getClassName() ) ),
203                    BooleanClause.Occur.MUST );
204         }
205 
206         if ( StringUtils.isNotBlank( searchFields.getBundleSymbolicName() ) )
207         {
208             qb.add( indexer.constructQuery( OSGI.SYMBOLIC_NAME,
209                                            new UserInputSearchExpression( searchFields.getBundleSymbolicName() ) ),
210                    BooleanClause.Occur.MUST );
211         }
212 
213         if ( StringUtils.isNotBlank( searchFields.getBundleVersion() ) )
214         {
215             qb.add( indexer.constructQuery( OSGI.VERSION,
216                                            new UserInputSearchExpression( searchFields.getBundleVersion() ) ),
217                    BooleanClause.Occur.MUST );
218         }
219 
220         if ( StringUtils.isNotBlank( searchFields.getBundleExportPackage() ) )
221         {
222             qb.add( indexer.constructQuery( OSGI.EXPORT_PACKAGE,
223                                            new UserInputSearchExpression( searchFields.getBundleExportPackage() ) ),
224                    Occur.MUST );
225         }
226 
227         if ( StringUtils.isNotBlank( searchFields.getBundleExportService() ) )
228         {
229             qb.add( indexer.constructQuery( OSGI.EXPORT_SERVICE,
230                                            new UserInputSearchExpression( searchFields.getBundleExportService() ) ),
231                    Occur.MUST );
232         }
233 
234         if ( StringUtils.isNotBlank( searchFields.getBundleImportPackage() ) )
235         {
236             qb.add( indexer.constructQuery( OSGI.IMPORT_PACKAGE,
237                                            new UserInputSearchExpression( searchFields.getBundleImportPackage() ) ),
238                    Occur.MUST );
239         }
240 
241         if ( StringUtils.isNotBlank( searchFields.getBundleName() ) )
242         {
243             qb.add( indexer.constructQuery( OSGI.NAME, new UserInputSearchExpression( searchFields.getBundleName() ) ),
244                    Occur.MUST );
245         }
246 
247         if ( StringUtils.isNotBlank( searchFields.getBundleImportPackage() ) )
248         {
249             qb.add( indexer.constructQuery( OSGI.IMPORT_PACKAGE,
250                                            new UserInputSearchExpression( searchFields.getBundleImportPackage() ) ),
251                    Occur.MUST );
252         }
253 
254         if ( StringUtils.isNotBlank( searchFields.getBundleRequireBundle() ) )
255         {
256             qb.add( indexer.constructQuery( OSGI.REQUIRE_BUNDLE,
257                                            new UserInputSearchExpression( searchFields.getBundleRequireBundle() ) ),
258                    Occur.MUST );
259         }
260 
261         if ( StringUtils.isNotBlank( searchFields.getClassifier() ) )
262         {
263             qb.add( indexer.constructQuery( MAVEN.CLASSIFIER, searchFields.isExactSearch() ? new SourcedSearchExpression(
264                        searchFields.getClassifier() ) : new UserInputSearchExpression( searchFields.getClassifier() ) ),
265                    Occur.MUST );
266         }
267         else if ( searchFields.isExactSearch() )
268         {
269             //TODO improvement in case of exact search and no classifier we must query for classifier with null value
270             // currently it's done in DefaultSearchService with some filtering
271         }
272 
273         BooleanQuery qu = qb.build();
274         if ( qu.clauses() == null || qu.clauses().size() <= 0 )
275         {
276             throw new RepositorySearchException( "No search fields set." );
277         }
278         if (qu.clauses()!=null) {
279             log.debug("CLAUSES ", qu.clauses());
280             for (BooleanClause cl : qu.clauses()) {
281                 log.debug("Clause ",cl);
282             }
283         }
284 
285         return search( limits, qu, indexingContextIds, Collections.<ArtifactInfoFilter>emptyList(),
286                        searchFields.getRepositories(), searchFields.isIncludePomArtifacts() );
287     }
288 
289     private static class NullSearch
290         implements SearchTyped, SearchExpression
291     {
292         private static final NullSearch INSTANCE = new NullSearch();
293 
294         @Override
295         public String getStringValue()
296         {
297             return "[[NULL_VALUE]]";
298         }
299 
300         @Override
301         public SearchType getSearchType()
302         {
303             return SearchType.EXACT;
304         }
305     }
306 
307     private SearchResults search( SearchResultLimits limits, BooleanQuery q, List<String> indexingContextIds,
308                                   List<? extends ArtifactInfoFilter> filters, List<String> selectedRepos,
309                                   boolean includePoms )
310         throws RepositorySearchException
311     {
312 
313         try
314         {
315             FlatSearchRequest request = new FlatSearchRequest( q );
316 
317             request.setContexts( getIndexingContexts( indexingContextIds ) );
318             if ( limits != null )
319             {
320                 // we apply limits only when first page asked
321                 if ( limits.getSelectedPage() == 0 )
322                 {
323                     request.setCount( limits.getPageSize() * ( Math.max( 1, limits.getSelectedPage() ) ) );
324                 }
325             }
326 
327             FlatSearchResponse response = indexer.searchFlat( request );
328 
329             if ( response == null || response.getTotalHitsCount() == 0 )
330             {
331                 SearchResultsrch/SearchResults.html#SearchResults">SearchResults results = new SearchResults();
332                 results.setLimits( limits );
333                 return results;
334             }
335 
336             return convertToSearchResults( response, limits, filters, selectedRepos, includePoms );
337         }
338         catch ( IOException e )
339         {
340             throw new RepositorySearchException( e.getMessage(), e );
341         }
342         catch ( RepositoryAdminException e )
343         {
344             throw new RepositorySearchException( e.getMessage(), e );
345         }
346 
347     }
348 
349     private IndexingContext getIndexingContext(String id) {
350         String repoId;
351         if (StringUtils.startsWith(id, "remote-")) {
352             repoId = StringUtils.substringAfter(id, "remote-");
353         } else {
354             repoId = id;
355         }
356         Repository repo = repositoryRegistry.getRepository(repoId);
357         if (repo==null) {
358             return null;
359         } else {
360             if (repo.getIndexingContext()!=null) {
361                 try {
362                     return repo.getIndexingContext().getBaseContext(IndexingContext.class);
363                 } catch (UnsupportedBaseContextException e) {
364                     return null;
365                 }
366             } else {
367                 return null;
368             }
369         }
370     }
371 
372     private List<IndexingContext> getIndexingContexts( List<String> ids )
373     {
374         List<IndexingContext> contexts = new ArrayList<>( ids.size() );
375 
376         for ( String id : ids )
377         {
378             IndexingContext context = getIndexingContext(id);
379             if ( context != null )
380             {
381                 contexts.add( context );
382             }
383             else
384             {
385                 log.warn( "context with id {} not exists", id );
386             }
387         }
388 
389         return contexts;
390     }
391 
392     private void constructQuery( String term, BooleanQuery.Builder q )
393     {
394         q.add( indexer.constructQuery( MAVEN.GROUP_ID, new UserInputSearchExpression( term ) ), Occur.SHOULD );
395         q.add( indexer.constructQuery( MAVEN.ARTIFACT_ID, new UserInputSearchExpression( term ) ), Occur.SHOULD );
396         q.add( indexer.constructQuery( MAVEN.VERSION, new UserInputSearchExpression( term ) ), Occur.SHOULD );
397         q.add( indexer.constructQuery( MAVEN.PACKAGING, new UserInputSearchExpression( term ) ), Occur.SHOULD );
398         q.add( indexer.constructQuery( MAVEN.CLASSNAMES, new UserInputSearchExpression( term ) ), Occur.SHOULD );
399 
400         //Query query =
401         //    new WildcardQuery( new Term( MAVEN.CLASSNAMES.getFieldName(), "*" ) );
402         //q.add( query, Occur.MUST_NOT );
403         // olamy IMHO we could set this option as at least one must match
404         //q.setMinimumNumberShouldMatch( 1 );
405     }
406 
407 
408     /**
409      * @param selectedRepos
410      * @return indexing contextId used
411      */
412     private List<String> addIndexingContexts( List<String> selectedRepos )
413     {
414         Set<String> indexingContextIds = new HashSet<>();
415         for ( String repo : selectedRepos )
416         {
417             try
418             {
419                 Repository rRepo = repositoryRegistry.getRepository(repo);
420 
421                 if ( rRepo != null )
422                 {
423 
424                     if (rRepo.getType().equals(RepositoryType.MAVEN)) {
425                         assert rRepo.getIndexingContext() != null;
426                         IndexingContext context = rRepo.getIndexingContext().getBaseContext(IndexingContext.class);
427                         if (context.isSearchable()) {
428                             indexingContextIds.addAll(getRemoteIndexingContextIds(repo));
429                             indexingContextIds.add(context.getId());
430                         } else {
431                             log.warn("indexingContext with id {} not searchable", rRepo.getId());
432                         }
433                     }
434 
435                 }
436                 else
437                 {
438                     log.warn( "Repository '{}' not found in configuration.", repo );
439                 }
440             }
441             catch ( RepositorySearchException e )
442             {
443                 log.warn( "RepositorySearchException occured while accessing index of repository '{}' : {}", repo,
444                     e.getMessage() );
445                 continue;
446             } catch (UnsupportedBaseContextException e) {
447                 log.error("Fatal situation: Maven repository without IndexingContext found.");
448                 continue;
449             }
450         }
451 
452         return new ArrayList<>( indexingContextIds );
453     }
454 
455 
456     @Override
457     public Set<String> getRemoteIndexingContextIds( String managedRepoId )
458         throws RepositorySearchException
459     {
460         Set<String> ids = new HashSet<>();
461 
462         List<ProxyConnector> proxyConnectors = null;
463         try
464         {
465             proxyConnectors = proxyConnectorAdmin.getProxyConnectorAsMap().get( managedRepoId );
466         }
467         catch ( RepositoryAdminException e )
468         {
469             throw new RepositorySearchException( e.getMessage(), e );
470         }
471 
472         if ( proxyConnectors == null || proxyConnectors.isEmpty() )
473         {
474             return ids;
475         }
476 
477         for ( ProxyConnector proxyConnector : proxyConnectors )
478         {
479             String remoteId = "remote-" + proxyConnector.getTargetRepoId();
480             RemoteRepository repo = repositoryRegistry.getRemoteRepository(proxyConnector.getTargetRepoId());
481             if (repo.getType()==RepositoryType.MAVEN) {
482                 try {
483                     IndexingContext context = repo.getIndexingContext() != null ? repo.getIndexingContext().getBaseContext(IndexingContext.class) : null;
484                     if (context!=null && context.isSearchable()) {
485                         ids.add(remoteId);
486                     }
487                 } catch (UnsupportedBaseContextException e) {
488                     // Ignore this one
489                 }
490             }
491         }
492 
493         return ids;
494     }
495 
496     @Override
497     public Collection<String> getAllGroupIds( String principal, List<String> selectedRepos )
498         throws RepositorySearchException
499     {
500         List<IndexingContext> indexContexts = getIndexingContexts( selectedRepos );
501 
502         if ( indexContexts == null || indexContexts.isEmpty() )
503         {
504             return Collections.emptyList();
505         }
506 
507         try
508         {
509             Set<String> allGroupIds = new HashSet<>();
510             for ( IndexingContext indexingContext : indexContexts )
511             {
512                 allGroupIds.addAll( indexingContext.getAllGroups() );
513             }
514             return allGroupIds;
515         }
516         catch ( IOException e )
517         {
518             throw new RepositorySearchException( e.getMessage(), e );
519         }
520 
521     }
522 
523     private SearchResults convertToSearchResults( FlatSearchResponse response, SearchResultLimits limits,
524                                                   List<? extends ArtifactInfoFilter> artifactInfoFilters,
525                                                   List<String> selectedRepos, boolean includePoms )
526         throws RepositoryAdminException
527     {
528         SearchResultsrch/SearchResults.html#SearchResults">SearchResults results = new SearchResults();
529         Set<ArtifactInfo> artifactInfos = response.getResults();
530 
531         for ( ArtifactInfo artifactInfo : artifactInfos )
532         {
533             if ( StringUtils.equalsIgnoreCase( "pom", artifactInfo.getFileExtension() ) && !includePoms )
534             {
535                 continue;
536             }
537             String id = SearchUtil.getHitId( artifactInfo.getGroupId(), //
538                                              artifactInfo.getArtifactId(), //
539                                              artifactInfo.getClassifier(), //
540                                              artifactInfo.getPackaging() );
541             Map<String, SearchResultHit> hitsMap = results.getHitsMap();
542 
543 
544             if ( !applyArtifactInfoFilters( artifactInfo, artifactInfoFilters, hitsMap ) )
545             {
546                 continue;
547             }
548 
549             SearchResultHit hit = hitsMap.get( id );
550             if ( hit != null )
551             {
552                 if ( !hit.getVersions().contains( artifactInfo.getVersion() ) )
553                 {
554                     hit.addVersion( artifactInfo.getVersion() );
555                 }
556             }
557             else
558             {
559                 hit = new SearchResultHit();
560                 hit.setArtifactId( artifactInfo.getArtifactId() );
561                 hit.setGroupId( artifactInfo.getGroupId() );
562                 hit.setRepositoryId( artifactInfo.getRepository() );
563                 hit.addVersion( artifactInfo.getVersion() );
564                 hit.setBundleExportPackage( artifactInfo.getBundleExportPackage() );
565                 hit.setBundleExportService( artifactInfo.getBundleExportService() );
566                 hit.setBundleSymbolicName( artifactInfo.getBundleSymbolicName() );
567                 hit.setBundleVersion( artifactInfo.getBundleVersion() );
568                 hit.setBundleDescription( artifactInfo.getBundleDescription() );
569                 hit.setBundleDocUrl( artifactInfo.getBundleDocUrl() );
570                 hit.setBundleRequireBundle( artifactInfo.getBundleRequireBundle() );
571                 hit.setBundleImportPackage( artifactInfo.getBundleImportPackage() );
572                 hit.setBundleLicense( artifactInfo.getBundleLicense() );
573                 hit.setBundleName( artifactInfo.getBundleName() );
574                 hit.setContext( artifactInfo.getContext() );
575                 hit.setGoals( artifactInfo.getGoals() );
576                 hit.setPrefix( artifactInfo.getPrefix() );
577                 hit.setPackaging( artifactInfo.getPackaging() );
578                 hit.setClassifier( artifactInfo.getClassifier() );
579                 hit.setFileExtension( artifactInfo.getFileExtension() );
580                 hit.setUrl( getBaseUrl( artifactInfo, selectedRepos ) );
581             }
582 
583             results.addHit( id, hit );
584         }
585 
586         results.setTotalHits( response.getTotalHitsCount() );
587         results.setTotalHitsMapSize( results.getHitsMap().values().size() );
588         results.setReturnedHitsCount( response.getReturnedHitsCount() );
589         results.setLimits( limits );
590 
591         if ( limits == null || limits.getSelectedPage() == SearchResultLimits.ALL_PAGES )
592         {
593             return results;
594         }
595         else
596         {
597             return paginate( results );
598         }
599     }
600 
601     /**
602      * calculate baseUrl without the context and base Archiva Url
603      *
604      * @param artifactInfo
605      * @return
606      */
607     protected String getBaseUrl( ArtifactInfo artifactInfo, List<String> selectedRepos )
608         throws RepositoryAdminException
609     {
610         StringBuilder sb = new StringBuilder();
611         if ( StringUtils.startsWith( artifactInfo.getContext(), "remote-" ) )
612         {
613             // it's a remote index result we search a managed which proxying this remote and on which
614             // current user has read karma
615             String managedRepoId =
616                 getManagedRepoId( StringUtils.substringAfter( artifactInfo.getContext(), "remote-" ), selectedRepos );
617             if ( managedRepoId != null )
618             {
619                 sb.append( '/' ).append( managedRepoId );
620                 artifactInfo.setContext( managedRepoId );
621             }
622         }
623         else
624         {
625             sb.append( '/' ).append( artifactInfo.getContext() );
626         }
627 
628         sb.append( '/' ).append( StringUtils.replaceChars( artifactInfo.getGroupId(), '.', '/' ) );
629         sb.append( '/' ).append( artifactInfo.getArtifactId() );
630         sb.append( '/' ).append( artifactInfo.getVersion() );
631         sb.append( '/' ).append( artifactInfo.getArtifactId() );
632         sb.append( '-' ).append( artifactInfo.getVersion() );
633         if ( StringUtils.isNotBlank( artifactInfo.getClassifier() ) )
634         {
635             sb.append( '-' ).append( artifactInfo.getClassifier() );
636         }
637         // maven-plugin packaging is a jar
638         if ( StringUtils.equals( "maven-plugin", artifactInfo.getPackaging() ) )
639         {
640             sb.append( "jar" );
641         }
642         else
643         {
644             sb.append( '.' ).append( artifactInfo.getPackaging() );
645         }
646 
647         return sb.toString();
648     }
649 
650     /**
651      * return a managed repo for a remote result
652      *
653      * @param remoteRepo
654      * @param selectedRepos
655      * @return
656      * @throws RepositoryAdminException
657      */
658     private String getManagedRepoId( String remoteRepo, List<String> selectedRepos )
659         throws RepositoryAdminException
660     {
661         Map<String, List<ProxyConnector>> proxyConnectorMap = proxyConnectorAdmin.getProxyConnectorAsMap();
662         if ( proxyConnectorMap == null || proxyConnectorMap.isEmpty() )
663         {
664             return null;
665         }
666         if ( selectedRepos != null && !selectedRepos.isEmpty() )
667         {
668             for ( Map.Entry<String, List<ProxyConnector>> entry : proxyConnectorMap.entrySet() )
669             {
670                 if ( selectedRepos.contains( entry.getKey() ) )
671                 {
672                     for ( ProxyConnector proxyConnector : entry.getValue() )
673                     {
674                         if ( StringUtils.equals( remoteRepo, proxyConnector.getTargetRepoId() ) )
675                         {
676                             return proxyConnector.getSourceRepoId();
677                         }
678                     }
679                 }
680             }
681         }
682 
683         // we don't find in search selected repos so return the first one
684         for ( Map.Entry<String, List<ProxyConnector>> entry : proxyConnectorMap.entrySet() )
685         {
686 
687             for ( ProxyConnector proxyConnector : entry.getValue() )
688             {
689                 if ( StringUtils.equals( remoteRepo, proxyConnector.getTargetRepoId() ) )
690                 {
691                     return proxyConnector.getSourceRepoId();
692                 }
693             }
694 
695         }
696         return null;
697     }
698 
699     private boolean applyArtifactInfoFilters( ArtifactInfo artifactInfo,
700                                               List<? extends ArtifactInfoFilter> artifactInfoFilters,
701                                               Map<String, SearchResultHit> currentResult )
702     {
703         if ( artifactInfoFilters == null || artifactInfoFilters.isEmpty() )
704         {
705             return true;
706         }
707 
708         ArchivaArtifactModelctModel.html#ArchivaArtifactModel">ArchivaArtifactModel artifact = new ArchivaArtifactModel();
709         artifact.setArtifactId( artifactInfo.getArtifactId() );
710         artifact.setClassifier( artifactInfo.getClassifier() );
711         artifact.setGroupId( artifactInfo.getGroupId() );
712         artifact.setRepositoryId( artifactInfo.getRepository() );
713         artifact.setVersion( artifactInfo.getVersion() );
714         artifact.setChecksumMD5( artifactInfo.getMd5() );
715         artifact.setChecksumSHA1( artifactInfo.getSha1() );
716         for ( ArtifactInfoFilter filter : artifactInfoFilters )
717         {
718             if ( !filter.addArtifactInResult( artifact, currentResult ) )
719             {
720                 return false;
721             }
722         }
723         return true;
724     }
725 
726     protected SearchResults./../../../org/apache/archiva/indexer/search/SearchResults.html#SearchResults">SearchResults paginate( SearchResults results )
727     {
728         SearchResultLimits limits = results.getLimits();
729         SearchResultsh/SearchResults.html#SearchResults">SearchResults paginated = new SearchResults();
730 
731         // ( limits.getPageSize() * ( Math.max( 1, limits.getSelectedPage() ) ) );
732 
733         int fetchCount = limits.getPageSize();
734         int offset = ( limits.getSelectedPage() * limits.getPageSize() );
735 
736         if ( fetchCount > results.getTotalHits() )
737         {
738             fetchCount = results.getTotalHits();
739         }
740 
741         // Goto offset.
742         if ( offset < results.getTotalHits() )
743         {
744             // only process if the offset is within the hit count.
745             for ( int i = 0; i < fetchCount; i++ )
746             {
747                 // Stop fetching if we are past the total # of available hits.
748                 if ( offset + i >= results.getHits().size() )
749                 {
750                     break;
751                 }
752 
753                 SearchResultHit hit = results.getHits().get( ( offset + i ) );
754                 if ( hit != null )
755                 {
756                     String id = SearchUtil.getHitId( hit.getGroupId(), hit.getArtifactId(), hit.getClassifier(),
757                                                      hit.getPackaging() );
758                     paginated.addHit( id, hit );
759                 }
760                 else
761                 {
762                     break;
763                 }
764             }
765         }
766         paginated.setTotalHits( results.getTotalHits() );
767         paginated.setReturnedHitsCount( paginated.getHits().size() );
768         paginated.setTotalHitsMapSize( results.getTotalHitsMapSize() );
769         paginated.setLimits( limits );
770 
771         return paginated;
772     }
773 
774 
775 }