diff options
author | Maria Odea B. Ching <oching@apache.org> | 2008-09-17 02:51:40 +0000 |
---|---|---|
committer | Maria Odea B. Ching <oching@apache.org> | 2008-09-17 02:51:40 +0000 |
commit | d0771be5634063d8e5634465e15a6f91c92089a5 (patch) | |
tree | 47dedf35063497826b6417526a5125bd03a1ee02 /archiva-modules/archiva-base | |
parent | dbc8a0f7d93a236636112bc167a24c50684c3a77 (diff) | |
download | archiva-d0771be5634063d8e5634465e15a6f91c92089a5.tar.gz archiva-d0771be5634063d8e5634465e15a6f91c92089a5.zip |
[MRM-90]
submitted by Gwen Harold Autencio
-filtered/advanced search
additional changes to patch:
-applied formatting
-removed unused methods and imports
git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@696137 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'archiva-modules/archiva-base')
3 files changed, 158 insertions, 22 deletions
diff --git a/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/CrossRepositorySearch.java b/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/CrossRepositorySearch.java index 63e21151c..52596ff9f 100644 --- a/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/CrossRepositorySearch.java +++ b/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/CrossRepositorySearch.java @@ -69,4 +69,21 @@ public interface CrossRepositorySearch * @return the results. */ public SearchResults searchForChecksum( String principal, List<String> selectedRepos, String checksum, SearchResultLimits limits ); + + /** + * Search for a specific artifact matching the given field values. The search is performed on the bytecode + * index/indices. + * + * @param principal + * @param selectedRepos repository to be searched + * @param groupId groupId to be matched + * @param artifactId artifactId to be matched + * @param version version to be matched + * @param className Java class or package name to be matched + * @param limits the limits to apply to the search results + * @return + */ + public SearchResults executeFilteredSearch( String principal, List<String> selectedRepos, String groupId, + String artifactId, String version, String className, + SearchResultLimits limits ); } diff --git a/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearch.java b/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearch.java index ede311346..a21c4fa6b 100644 --- a/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearch.java +++ b/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearch.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.List; import org.apache.lucene.document.Document; +import org.apache.lucene.index.Term; import org.apache.lucene.queryParser.MultiFieldQueryParser; import org.apache.lucene.queryParser.ParseException; import org.apache.lucene.queryParser.QueryParser; @@ -32,16 +33,20 @@ import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.Filter; import org.apache.lucene.search.Hits; import org.apache.lucene.search.MultiSearcher; +import org.apache.lucene.search.Query; import org.apache.lucene.search.QueryWrapperFilter; import org.apache.lucene.search.Searchable; +import org.apache.lucene.search.TermQuery; import org.apache.maven.archiva.configuration.ArchivaConfiguration; import org.apache.maven.archiva.configuration.ConfigurationNames; import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration; +import org.apache.maven.archiva.indexer.ArtifactKeys; import org.apache.maven.archiva.indexer.RepositoryContentIndex; import org.apache.maven.archiva.indexer.RepositoryContentIndexFactory; import org.apache.maven.archiva.indexer.RepositoryIndexException; import org.apache.maven.archiva.indexer.RepositoryIndexSearchException; import org.apache.maven.archiva.indexer.bytecode.BytecodeHandlers; +import org.apache.maven.archiva.indexer.bytecode.BytecodeKeys; import org.apache.maven.archiva.indexer.filecontent.FileContentHandlers; import org.apache.maven.archiva.indexer.hashcodes.HashcodesHandlers; import org.apache.maven.archiva.indexer.hashcodes.HashcodesKeys; @@ -57,7 +62,7 @@ import org.slf4j.LoggerFactory; /** * DefaultCrossRepositorySearch - * + * * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a> * @version $Id$ * @plexus.component role="org.apache.maven.archiva.indexer.search.CrossRepositorySearch" role-hint="default" @@ -66,12 +71,12 @@ public class DefaultCrossRepositorySearch implements CrossRepositorySearch, RegistryListener, Initializable { private Logger log = LoggerFactory.getLogger( DefaultCrossRepositorySearch.class ); - + /** * @plexus.requirement role-hint="lucene" */ private RepositoryContentIndexFactory indexFactory; - + /** * @plexus.requirement */ @@ -79,14 +84,61 @@ public class DefaultCrossRepositorySearch private List<ManagedRepositoryConfiguration> localIndexedRepositories = new ArrayList<ManagedRepositoryConfiguration>(); - public SearchResults searchForChecksum( String principal, List<String> selectedRepos, String checksum, SearchResultLimits limits ) + public SearchResults executeFilteredSearch( String principal, List<String> selectedRepos, String groupId, + String artifactId, String version, String className, + SearchResultLimits limits ) + { + List<RepositoryContentIndex> indexes = getBytecodeIndexes( principal, selectedRepos ); + SearchResults results = new SearchResults(); + BooleanQuery booleanQuery = new BooleanQuery(); + + if ( groupId != null && groupId.length() > 0 ) + { + parseAndAdd( booleanQuery, ArtifactKeys.GROUPID, groupId, "\\.|-" ); + } + + if ( artifactId != null && artifactId.length() > 0 ) + { + parseAndAdd( booleanQuery, ArtifactKeys.ARTIFACTID, artifactId, "\\.|-" ); + } + + if ( version != null && version.length() > 0 ) + { + parseAndAdd( booleanQuery, ArtifactKeys.VERSION, version, "\\.|-" ); + } + + if ( className != null && className.length() > 0 ) + { + + try + { + QueryParser parser = + new MultiFieldQueryParser( new String[] { BytecodeKeys.CLASSES, BytecodeKeys.FILES, + BytecodeKeys.METHODS }, new BytecodeHandlers().getAnalyzer() ); + booleanQuery.add( parser.parse( className ), BooleanClause.Occur.MUST ); + } + catch ( ParseException e ) + { + + } + } + + LuceneQuery query = new LuceneQuery( booleanQuery ); + results = searchAll( query, limits, indexes, null ); + results.getRepositories().add( this.localIndexedRepositories ); + + return results; + } + + public SearchResults searchForChecksum( String principal, List<String> selectedRepos, String checksum, + SearchResultLimits limits ) { List<RepositoryContentIndex> indexes = getHashcodeIndexes( principal, selectedRepos ); try { QueryParser parser = new MultiFieldQueryParser( new String[]{HashcodesKeys.MD5, HashcodesKeys.SHA1}, - new HashcodesHandlers().getAnalyzer() ); + new HashcodesHandlers().getAnalyzer() ); LuceneQuery query = new LuceneQuery( parser.parse( checksum ) ); SearchResults results = searchAll( query, limits, indexes, null ); results.getRepositories().addAll( this.localIndexedRepositories ); @@ -124,23 +176,22 @@ public class DefaultCrossRepositorySearch return new SearchResults(); } - public SearchResults searchForTerm( String principal, List<String> selectedRepos, String term, SearchResultLimits limits ) { return searchForTerm( principal, selectedRepos, term, limits, null ); } - + public SearchResults searchForTerm( String principal, List<String> selectedRepos, String term, SearchResultLimits limits, List<String> previousSearchTerms ) { List<RepositoryContentIndex> indexes = getFileContentIndexes( principal, selectedRepos ); - + try { QueryParser parser = new FileContentHandlers().getQueryParser(); LuceneQuery query = null; SearchResults results = null; - if( previousSearchTerms == null || previousSearchTerms.isEmpty() ) + if ( previousSearchTerms == null || previousSearchTerms.isEmpty() ) { query = new LuceneQuery( parser.parse( term ) ); results = searchAll( query, limits, indexes, null ); @@ -149,17 +200,17 @@ public class DefaultCrossRepositorySearch { // AND the previous search terms BooleanQuery booleanQuery = new BooleanQuery(); - for( String previousSearchTerm : previousSearchTerms ) + for ( String previousSearchTerm : previousSearchTerms ) { booleanQuery.add( parser.parse( previousSearchTerm ), BooleanClause.Occur.MUST ); } - - query = new LuceneQuery( booleanQuery ); + + query = new LuceneQuery( booleanQuery ); Filter filter = new QueryWrapperFilter( parser.parse( term ) ); results = searchAll( query, limits, indexes, filter ); - } + } results.getRepositories().addAll( this.localIndexedRepositories ); - + return results; } catch ( ParseException e ) @@ -168,9 +219,9 @@ public class DefaultCrossRepositorySearch } // empty results. - return new SearchResults(); + return new SearchResults(); } - + private SearchResults searchAll( LuceneQuery luceneQuery, SearchResultLimits limits, List<RepositoryContentIndex> indexes, Filter filter ) { org.apache.lucene.search.Query specificQuery = luceneQuery.getLuceneQuery(); @@ -203,7 +254,7 @@ public class DefaultCrossRepositorySearch // Perform the search. Hits hits = null; - if( filter != null ) + if ( filter != null ) { hits = searcher.search( specificQuery, filter ); } @@ -355,7 +406,7 @@ public class DefaultCrossRepositorySearch return ret; } - + private boolean indexExists( RepositoryContentIndex index ) { try @@ -402,6 +453,26 @@ public class DefaultCrossRepositorySearch } } + private void parseAndAdd( BooleanQuery query, String key, String value, String delimiter ) + { + if ( value != null && value.length() > 0 ) + { + String[] terms = value.split( delimiter ); + for ( int i = 0; i < terms.length; i++ ) + { + Term valueTerm = new Term( key, terms[i] ); + Query valueQuery = new TermQuery( valueTerm ); + query.add( valueQuery, BooleanClause.Occur.MUST ); + } + } + else + { + Term valueTerm = new Term( key, value ); + Query valueQuery = new TermQuery( valueTerm ); + query.add( valueQuery, BooleanClause.Occur.MUST ); + } + } + public void initialize() throws InitializationException { diff --git a/archiva-modules/archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearchTest.java b/archiva-modules/archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearchTest.java index 71c872d67..005e3e719 100644 --- a/archiva-modules/archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearchTest.java +++ b/archiva-modules/archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearchTest.java @@ -242,6 +242,51 @@ public class DefaultCrossRepositorySearchTest "org.apache.maven.continuum.web.action.BuildDefinitionAction.isBuildFresh", null, true ); } + public void testExecuteFilteredSearch() + throws Exception + { + CrossRepositorySearch search = lookupCrossRepositorySearch(); + + String expectedRepos[] = new String[] { TEST_DEFAULT_REPO_ID }; + + String expectedResults[] = new String[] { "org1", "org2", "org3", "org4", "org5", "org6", "org7", "org8" }; + + String secondExpectedResults[] = new String[] { "continuum-webapp" }; + + String thirdExpectedResults[] = new String[] { "archiva-common" }; + + // search for groupId + assertFilteredSearchResults( expectedRepos, expectedResults, search, "org", null, null, null, 30 ); + + // search for groupId and artifactId + assertFilteredSearchResults( expectedRepos, secondExpectedResults, search, "org.apache.maven", + "continuum-webapp", null, null, 30 ); + + // search for groupId , artifactId and version + assertFilteredSearchResults( expectedRepos, thirdExpectedResults, search, "org.apache.maven.archiva", + "archiva-common", "1.0", null, 30 ); + } + + private void assertFilteredSearchResults ( String expectedRepos[], String expectedResults[], CrossRepositorySearch search, + String groupId, String artifactId, String version, String className , int rowCount ) + { + SearchResultLimits limits = new SearchResultLimits( 0 ); + limits.setPageSize( rowCount ); + + List<String> selectedRepos = new ArrayList<String>(); + selectedRepos.addAll( Arrays.asList( expectedRepos ) ); + + SearchResults results = null; + + results = search.executeFilteredSearch( "guest" , selectedRepos, groupId, artifactId, version, className, limits ); + + assertNotNull( "Search Results should not be null.", results ); + assertEquals( "Repository Hits", expectedRepos.length, results.getRepositories().size() ); + assertEquals( expectedRepos.length, 1); + assertEquals( TEST_DEFAULT_REPO_ID , selectedRepos.get( 0 ) ); + assertEquals( "Search Result Hits", expectedResults.length, results.getHits().size() ); + } + private void assertSearchResults( String expectedRepos[], String expectedResults[], CrossRepositorySearch search, String term, List<String> previousSearchTerms, boolean bytecode ) throws Exception @@ -251,11 +296,12 @@ public class DefaultCrossRepositorySearchTest List<String> selectedRepos = new ArrayList<String>(); selectedRepos.addAll( Arrays.asList( expectedRepos ) ); - + SearchResults results = null; + if( previousSearchTerms == null ) - { - if( bytecode ) + { + if( bytecode ) { results = search.searchForBytecode( "guest", selectedRepos, term, limits ); } @@ -268,16 +314,18 @@ public class DefaultCrossRepositorySearchTest { results = search.searchForTerm( "guest", selectedRepos, term, limits, previousSearchTerms ); } + assertNotNull( "Search Results should not be null.", results ); assertEquals( "Repository Hits", expectedRepos.length, results.getRepositories().size() ); + // TODO: test the repository ids returned. assertEquals( "Search Result Hits", expectedResults.length, results.getHits().size() ); // TODO: test the order of hits. // TODO: test the value of the hits. } - + protected ManagedRepositoryConfiguration createRepository( String id, String name, File location ) { ManagedRepositoryConfiguration repo = new ManagedRepositoryConfiguration(); |