You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MavenRepositorySearch.java 27KB

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