protected NexusNGArtifactLink createNexusNGArtifactLink( final Request request, final String repositoryId, final String groupId, final String artifactId, final String version, final String extension, final String classifier) { NexusNGArtifactLink link = new NexusNGArtifactLink(); link.setExtension(extension); link.setClassifier(classifier); return link; }
protected void repackIteratorSearchResponse( Request request, Map<String, String> terms, SearchNGResponse response, boolean collapsed, Integer from, int count, IteratorSearchResponse iterator, SystemWideLatestVersionCollector systemWideCollector, RepositoryWideLatestVersionCollector repositoryWideCollector) throws NoSuchRepositoryException, IOException { response.setCollapsed(collapsed); response.setTotalCount(iterator.getTotalHitsCount()); response.setFrom(from == null ? -1 : from.intValue()); response.setCount(count == LUCENE_HIT_LIMIT ? -1 : count); // System.out.println( "** Query is \"" + iterator.getQuery().toString() + "\"." ); try { if (!response.isTooManyResults()) { // 1st pass, collect results LinkedHashMap<String, NexusNGArtifact> hits = new LinkedHashMap<String, NexusNGArtifact>(); NexusNGArtifact artifact; float firstDocumentScore = -1f; float lastDocumentScore = -1f; final long startedAtMillis = System.currentTimeMillis(); // 1sd pass, build first two level (no links), and actually consume the iterator and // collectors will be // set for (ArtifactInfo ai : iterator) { final String key = ai.groupId + ":" + ai.artifactId + ":" + ai.version; artifact = hits.get(key); // System.out.println( "* " + ai.context + " : " + ai.toString() + " -- " + // ai.getLuceneScore() + // " -- " // + ( artifact != null ? "F" : "N" ) ); if (artifact == null) { if (System.currentTimeMillis() - startedAtMillis > FIRST_LOOP_EXECUTION_TIME_LIMIT) { getSearchDiagnosticLogger() .debug( "Stopping delivering search results since we spent more than " + FIRST_LOOP_EXECUTION_TIME_LIMIT + " millis in 1st loop processing results."); break; } // we stop if we delivered "most important" hits (change of relevance from 1st document // we got) if (hits.size() > 10 && (firstDocumentScore - ai.getLuceneScore()) > DOCUMENT_TOP_RELEVANCE_HIT_CHANGE_THRESHOLD) { getSearchDiagnosticLogger() .debug( "Stopping delivering search results since we span " + DOCUMENT_TOP_RELEVANCE_HIT_CHANGE_THRESHOLD + " of score change (firstDocScore=" + firstDocumentScore + ", currentDocScore=" + ai.getLuceneScore() + ")."); break; } // we stop if we detect a "big drop" in relevance in relation to previous document's // score if (hits.size() > 10 && lastDocumentScore > 0) { if ((lastDocumentScore - ai.getLuceneScore()) > DOCUMENT_RELEVANCE_HIT_CHANGE_THRESHOLD) { getSearchDiagnosticLogger() .debug( "Stopping delivering search results since we hit a relevance drop bigger than " + DOCUMENT_RELEVANCE_HIT_CHANGE_THRESHOLD + " (lastDocScore=" + lastDocumentScore + ", currentDocScore=" + ai.getLuceneScore() + ")."); // the relevance change was big, so we stepped over "trash" results that are // probably not relevant at all, just stop here then break; } } // we stop if we hit the GA limit if ((hits.size() + 1) > GA_HIT_LIMIT) { getSearchDiagnosticLogger() .debug( "Stopping delivering search results since we hit a GA hit limit of " + GA_HIT_LIMIT + "."); // check for HIT_LIMIT: if we are stepping it over, stop here break; } else { artifact = new NexusNGArtifact(); artifact.setGroupId(ai.groupId); artifact.setArtifactId(ai.artifactId); artifact.setVersion(ai.version); artifact.setHighlightedFragment(getMatchHighlightHtmlSnippet(ai)); hits.put(key, artifact); } } Repository repository = getUnprotectedRepositoryRegistry().getRepository(ai.repository); addRepositoryDetails(request, response, repository); NexusNGArtifactHit hit = null; for (NexusNGArtifactHit artifactHit : artifact.getArtifactHits()) { if (repository.getId().equals(artifactHit.getRepositoryId())) { hit = artifactHit; break; } } if (hit == null) { hit = new NexusNGArtifactHit(); hit.setRepositoryId(repository.getId()); // if collapsed, we add links in 2nd pass, otherwise here if (!collapsed) { // we are adding the POM link "blindly", unless packaging is POM, // since the it will be added below the "usual" way if (!"pom".equals(ai.packaging)) { NexusNGArtifactLink link = createNexusNGArtifactLink( request, ai.repository, ai.groupId, ai.artifactId, ai.version, "pom", null); // add the POM link hit.addArtifactLink(link); } } // we just created it, add it artifact.addArtifactHit(hit); } if (!collapsed) { boolean needsToBeAdded = true; for (NexusNGArtifactLink link : hit.getArtifactLinks()) { if (StringUtils.equals(link.getClassifier(), ai.classifier) && StringUtils.equals(link.getExtension(), ai.fextension)) { needsToBeAdded = false; break; } } if (needsToBeAdded) { NexusNGArtifactLink link = createNexusNGArtifactLink( request, ai.repository, ai.groupId, ai.artifactId, ai.version, ai.fextension, ai.classifier); hit.addArtifactLink(link); } } if (firstDocumentScore < 0) { firstDocumentScore = ai.getLuceneScore(); } lastDocumentScore = ai.getLuceneScore(); } // summary: getSearchDiagnosticLogger() .debug( "Query terms \"" + terms + "\" (LQL \"" + iterator.getQuery() + "\") matched total of " + iterator.getTotalHitsCount() + " records, " + iterator.getTotalProcessedArtifactInfoCount() + " records were processed out of those, resulting in " + hits.size() + " unique GA records. Lucene scored documents first=" + firstDocumentScore + ", last=" + lastDocumentScore + ". Main processing loop took " + (System.currentTimeMillis() - startedAtMillis) + " ms."); // 2nd pass, set versions for (NexusNGArtifact artifactNg : hits.values()) { final String systemWideCollectorKey = systemWideCollector.getKey(artifactNg.getGroupId(), artifactNg.getArtifactId()); LatestVersionHolder systemWideHolder = systemWideCollector.getLVHForKey(systemWideCollectorKey); if (systemWideHolder != null) { if (systemWideHolder.getLatestSnapshot() != null) { artifactNg.setLatestSnapshot(systemWideHolder.getLatestSnapshot().toString()); artifactNg.setLatestSnapshotRepositoryId( systemWideHolder.getLatestSnapshotRepositoryId()); } if (systemWideHolder.getLatestRelease() != null) { artifactNg.setLatestRelease(systemWideHolder.getLatestRelease().toString()); artifactNg.setLatestReleaseRepositoryId( systemWideHolder.getLatestReleaseRepositoryId()); } } // add some "touche" on 1st level if (collapsed) { // set the top level version to one of the latest ones if (artifactNg.getLatestRelease() != null) { artifactNg.setVersion(artifactNg.getLatestRelease()); } else { artifactNg.setVersion(artifactNg.getLatestSnapshot()); } // "create" the links now for (NexusNGArtifactHit hit : artifactNg.getArtifactHits()) { final String repositoryWideCollectorKey = repositoryWideCollector.getKey( hit.getRepositoryId(), artifactNg.getGroupId(), artifactNg.getArtifactId()); LatestECVersionHolder repositoryWideHolder = repositoryWideCollector.getLVHForKey(repositoryWideCollectorKey); if (repositoryWideHolder != null) { String versionToSet = null; // do we have a "latest release" version? if (repositoryWideHolder.getLatestRelease() != null) { versionToSet = repositoryWideHolder.getLatestRelease().toString(); } else { versionToSet = repositoryWideHolder.getLatestSnapshot().toString(); } // add POM link NexusNGArtifactLink pomLink = createNexusNGArtifactLink( request, hit.getRepositoryId(), artifactNg.getGroupId(), artifactNg.getArtifactId(), versionToSet, "pom", null); hit.addArtifactLink(pomLink); // TODO: order! // add main artifact link // add everything else // make the list by joining two collections // rationale: in case of reposes, only one of these will be populated, other will be // empty // but in case of mixed policy (like group), probably both will exist // TODO: this will not work like it in groups, since then the versions will // mismatch! ArrayList<ECHolder> ecHolders = new ArrayList<ECHolder>(repositoryWideHolder.getReleaseECHolders()); ecHolders.addAll(repositoryWideHolder.getSnapshotECHolders()); for (ECHolder holder : ecHolders) { // add non-poms only, since we added POMs above if (!"pom".equals(holder.getExtension())) { NexusNGArtifactLink link = createNexusNGArtifactLink( request, hit.getRepositoryId(), artifactNg.getGroupId(), artifactNg.getArtifactId(), versionToSet, holder.getExtension(), holder.getClassifier()); hit.addArtifactLink(link); } } } } } } response.setData(new ArrayList<NexusNGArtifact>(hits.values())); } } finally { iterator.close(); } response.setTooManyResults(iterator.getTotalHitsCount() > count); }