Author: oching
Date: Wed Jul 16 01:46:38 2008
New Revision: 677197

URL: http://svn.apache.org/viewvc?rev=677197&view=rev
Log:
[MRM-864]
-use a lucene Filter with BooleanQuery and the LuceneQuery for searching within 
the search results
-added a checkbox in the general search page to search from the results only
-maintain a list of previous query strings if searchResultsOnly option is 
enabled in general search

Modified:
    
archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/CrossRepositorySearch.java
    
archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearch.java
    
archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearchTest.java
    
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/SearchAction.java
    
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/include/quickSearchForm.jspf
    
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/results.jsp

Modified: 
archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/CrossRepositorySearch.java
URL: 
http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/CrossRepositorySearch.java?rev=677197&r1=677196&r2=677197&view=diff
==============================================================================
--- 
archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/CrossRepositorySearch.java
 (original)
+++ 
archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/CrossRepositorySearch.java
 Wed Jul 16 01:46:38 2008
@@ -40,6 +40,19 @@
     public SearchResults searchForTerm( String principal, List<String> 
selectedRepos, String term, SearchResultLimits limits );
     
     /**
+     * Search for a specific term from the previous search results.
+     * 
+     * @param principal the user doing the search.
+     * @param selectedRepos the repositories to search from.
+     * @param term the term to search for.
+     * @param limits the limits to apply to the search results.
+     * @param previousSearchTerms the list of the previous search terms.
+     * @return the results
+     */
+    public SearchResults searchForTerm( String principal, List<String> 
selectedRepos, String term,
+                                        SearchResultLimits limits, 
List<String> previousSearchTerms );
+    
+    /**
      * Search for the specific bytecode across all repositories.
      * 
      * @param term the term to search for.

Modified: 
archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearch.java
URL: 
http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearch.java?rev=677197&r1=677196&r2=677197&view=diff
==============================================================================
--- 
archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearch.java
 (original)
+++ 
archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearch.java
 Wed Jul 16 01:46:38 2008
@@ -27,8 +27,12 @@
 import org.apache.lucene.queryParser.MultiFieldQueryParser;
 import org.apache.lucene.queryParser.ParseException;
 import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.search.BooleanClause;
+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.QueryWrapperFilter;
 import org.apache.lucene.search.Searchable;
 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
 import org.apache.maven.archiva.configuration.ConfigurationNames;
@@ -84,7 +88,7 @@
             QueryParser parser = new MultiFieldQueryParser( new 
String[]{HashcodesKeys.MD5, HashcodesKeys.SHA1},
                                                             new 
HashcodesHandlers().getAnalyzer() );
             LuceneQuery query = new LuceneQuery( parser.parse( checksum ) );
-            SearchResults results = searchAll( query, limits, indexes );
+            SearchResults results = searchAll( query, limits, indexes, null );
             results.getRepositories().addAll( this.localIndexedRepositories );
 
             return results;
@@ -106,7 +110,7 @@
         {
             QueryParser parser = new BytecodeHandlers().getQueryParser();
             LuceneQuery query = new LuceneQuery( parser.parse( term ) );
-            SearchResults results = searchAll( query, limits, indexes );
+            SearchResults results = searchAll( query, limits, indexes, null );
             results.getRepositories().addAll( this.localIndexedRepositories );
 
             return results;
@@ -120,8 +124,15 @@
         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 );
         List<RepositoryContentIndex> bytecodeIndices = getBytecodeIndexes( 
principal, selectedRepos );        
         indexes.addAll( bytecodeIndices );
@@ -129,8 +140,26 @@
         try
         {
             QueryParser parser = new FileContentHandlers().getQueryParser();
-            LuceneQuery query = new LuceneQuery( parser.parse( term ) );
-            SearchResults results = searchAll( query, limits, indexes );
+            LuceneQuery query = null;
+            SearchResults results = null;
+            if( previousSearchTerms == null || previousSearchTerms.isEmpty() )
+            {
+                query = new LuceneQuery( parser.parse( term ) );
+                results = searchAll( query, limits, indexes, null );
+            }
+            else
+            {
+                // AND the previous search terms
+                BooleanQuery booleanQuery = new BooleanQuery();
+                for( String previousSearchTerm : previousSearchTerms )
+                {
+                    booleanQuery.add( parser.parse( previousSearchTerm ), 
BooleanClause.Occur.MUST );
+                }
+                
+                query = new LuceneQuery( booleanQuery );                
+                Filter filter = new QueryWrapperFilter( parser.parse( term ) );
+                results = searchAll( query, limits, indexes, filter );
+            }            
             results.getRepositories().addAll( this.localIndexedRepositories );
             
             return results;
@@ -141,10 +170,10 @@
         }
 
         // empty results.
-        return new SearchResults();
+        return new SearchResults(); 
     }
-
-    private SearchResults searchAll( LuceneQuery luceneQuery, 
SearchResultLimits limits, List<RepositoryContentIndex> indexes )
+    
+    private SearchResults searchAll( LuceneQuery luceneQuery, 
SearchResultLimits limits, List<RepositoryContentIndex> indexes, Filter filter )
     {
         org.apache.lucene.search.Query specificQuery = 
luceneQuery.getLuceneQuery();
 
@@ -175,7 +204,15 @@
             searcher = new MultiSearcher( searchables );
 
             // Perform the search.
-            Hits hits = searcher.search( specificQuery );
+            Hits hits = null;
+            if( filter != null )
+            {
+                hits = searcher.search( specificQuery, filter );
+            }
+            else
+            {
+                hits = searcher.search( specificQuery );
+            }
 
             int hitCount = hits.length();
 

Modified: 
archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearchTest.java
URL: 
http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearchTest.java?rev=677197&r1=677196&r2=677197&view=diff
==============================================================================
--- 
archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearchTest.java
 (original)
+++ 
archiva/trunk/archiva-modules/archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearchTest.java
 Wed Jul 16 01:46:38 2008
@@ -140,7 +140,7 @@
             "org","org2","org3","org4","org5","org6","org7"
         };
         
-        assertSearchResults( expectedRepos, expectedResults, search, "org" );
+        assertSearchResults( expectedRepos, expectedResults, search, "org", 
null );
     }
 
     public void testSearchTerm_Junit()
@@ -156,7 +156,7 @@
             "junit","junit2","junit3"
         };
         
-        assertSearchResults( expectedRepos, expectedResults, search, "junit" );
+        assertSearchResults( expectedRepos, expectedResults, search, "junit", 
null );
     }
 
     public void testSearchInvalidTerm()
@@ -172,10 +172,49 @@
             // Nothing.
         };
         
-        assertSearchResults( expectedRepos, expectedResults, search, 
"monosodium" );
+        assertSearchResults( expectedRepos, expectedResults, search, 
"monosodium", null );
     }
     
-    private void assertSearchResults( String expectedRepos[], String 
expectedResults[], CrossRepositorySearch search, String term )
+    public void testSearchWithinSearchResults()
+        throws Exception
+    {
+        CrossRepositorySearch search = lookupCrossRepositorySearch();
+
+        String expectedRepos[] = new String[] {
+            TEST_DEFAULT_REPO_ID
+        };
+        
+        String expectedResults[] = new String[] { 
+            "org","org2","org3","org4","org5","org6","org7"
+        };
+        
+        // first search
+        assertSearchResults( expectedRepos, expectedResults, search, "org", 
null );
+        
+        List<String> previousSearchTerms = new ArrayList<String>();
+        previousSearchTerms.add( "org" );        
+        String secondSearchExpectedResults[] = new String[] { 
+            "org.apache.maven.archiva.record", 
"org.apache.maven.archiva.record2",
+                "org.apache.maven.archiva.record3", 
"org.apache.maven.archiva.record4",
+                "org.apache.maven.archiva.record5", 
"org.apache.maven.archiva.record6",
+                "org.apache.maven.archiva.record7"
+        };
+        
+        //second search
+        assertSearchResults( expectedRepos, secondSearchExpectedResults, 
search, "org.apache.maven.archiva.record",
+                             previousSearchTerms );
+        
+        previousSearchTerms.add( "org.apache.maven.archiva.record" );
+        String thirdSearchExpectedResults[] = new String[] { 
+            "junit", "junit2", "junit3"
+        };
+        
+        //third search
+        assertSearchResults( expectedRepos, thirdSearchExpectedResults, 
search, "junit", previousSearchTerms );        
+    }
+    
+    private void assertSearchResults( String expectedRepos[], String 
expectedResults[], CrossRepositorySearch search,
+                                      String term, List<String> 
previousSearchTerms )
         throws Exception
     {
         SearchResultLimits limits = new SearchResultLimits( 0 );
@@ -184,7 +223,15 @@
         List<String> selectedRepos = new ArrayList<String>();
         selectedRepos.addAll( Arrays.asList( expectedRepos ) );
         
-        SearchResults results = search.searchForTerm( "guest", selectedRepos, 
term, limits );
+        SearchResults results = null;
+        if( previousSearchTerms == null )
+        {
+            results = search.searchForTerm( "guest", selectedRepos, term, 
limits );
+        }
+        else
+        {
+            results = search.searchForTerm( "guest", selectedRepos, term, 
limits, previousSearchTerms );
+        }
         
         assertNotNull( "Search Results should not be null.", results );
         assertEquals( "Repository Hits", expectedRepos.length, 
results.getRepositories().size() );

Modified: 
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/SearchAction.java
URL: 
http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/SearchAction.java?rev=677197&r1=677196&r2=677197&view=diff
==============================================================================
--- 
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/SearchAction.java
 (original)
+++ 
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/SearchAction.java
 Wed Jul 16 01:46:38 2008
@@ -20,6 +20,7 @@
  */
 
 import java.net.MalformedURLException;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
@@ -83,6 +84,12 @@
     private int currentPage = 0;
     
     private int totalPages;
+    
+    private boolean searchResultsOnly; 
+    
+    private String completeQueryString;
+    
+    private static final String COMPLETE_QUERY_STRING_SEPARATOR = ";";
 
     public String quickSearch()
         throws MalformedURLException, RepositoryIndexException, 
RepositoryIndexSearchException
@@ -103,7 +110,15 @@
             return GlobalResults.ACCESS_TO_NO_REPOS;
         }
 
-        results = crossRepoSearch.searchForTerm( getPrincipal(), 
selectedRepos, q, limits );
+        if( searchResultsOnly && !completeQueryString.equals( "" ) )
+        { 
+            results = crossRepoSearch.searchForTerm( getPrincipal(), 
selectedRepos, q, limits, parseCompleteQueryString() );
+        }
+        else
+        {
+            completeQueryString = "";
+            results = crossRepoSearch.searchForTerm( getPrincipal(), 
selectedRepos, q, limits );
+        }
         
         if ( results.isEmpty() )
         {
@@ -125,7 +140,12 @@
          * to result in a higher score. 
          *   - Joakim
          */
-
+        
+        if( !isEqualToPreviousSearchTerm( q ) )
+        {
+            buildCompleteQueryString( q );
+        }
+        
         return SUCCESS;
     }
 
@@ -191,6 +211,46 @@
         return Collections.emptyList();
     }
 
+    private void buildCompleteQueryString( String searchTerm )
+    {
+        if( searchTerm.indexOf( COMPLETE_QUERY_STRING_SEPARATOR ) != -1 )
+        {
+            searchTerm = StringUtils.remove( searchTerm, 
COMPLETE_QUERY_STRING_SEPARATOR );
+        }
+        
+        if( completeQueryString == null || "".equals( completeQueryString ) )
+        {
+            completeQueryString = searchTerm;
+        }
+        else
+        {            
+            completeQueryString = completeQueryString + 
COMPLETE_QUERY_STRING_SEPARATOR + searchTerm;
+        }
+    }
+    
+    private List<String> parseCompleteQueryString()
+    {
+        List<String> parsedCompleteQueryString = new ArrayList<String>();      
  
+        String[] parsed = StringUtils.split( completeQueryString, 
COMPLETE_QUERY_STRING_SEPARATOR );
+        CollectionUtils.addAll( parsedCompleteQueryString, parsed );
+        
+        return parsedCompleteQueryString;
+    }
+    
+    private boolean isEqualToPreviousSearchTerm( String searchTerm )
+    {
+        if( !"".equals( completeQueryString ) )
+        {
+            String[] parsed = StringUtils.split( completeQueryString, 
COMPLETE_QUERY_STRING_SEPARATOR );
+            if( StringUtils.equalsIgnoreCase( searchTerm, parsed[ 
parsed.length - 1 ] ) )
+            {
+                return true;
+            }
+        }
+        
+        return false;
+    }
+    
     public String getQ()
     {
         return q;
@@ -230,4 +290,24 @@
     {
         this.totalPages = totalPages;
     }
+
+    public boolean isSearchResultsOnly()
+    {
+        return searchResultsOnly;
+    }
+
+    public void setSearchResultsOnly( boolean searchResultsOnly )
+    {
+        this.searchResultsOnly = searchResultsOnly;
+    }
+
+    public String getCompleteQueryString()
+    {
+        return completeQueryString;
+    }
+
+    public void setCompleteQueryString( String completeQueryString )
+    {
+        this.completeQueryString = completeQueryString;
+    }    
 }

Modified: 
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/include/quickSearchForm.jspf
URL: 
http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/include/quickSearchForm.jspf?rev=677197&r1=677196&r2=677197&view=diff
==============================================================================
--- 
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/include/quickSearchForm.jspf
 (original)
+++ 
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/include/quickSearchForm.jspf
 Wed Jul 16 01:46:38 2008
@@ -22,6 +22,8 @@
 <div id="searchBox">
   <ww:form method="get" action="quickSearch" validate="true">
     <ww:textfield label="Search for" size="50" name="q"/>
+    <ww:checkbox label="Search Results Only" name="searchResultsOnly"/>        
+    <ww:hidden name="completeQueryString" value="${completeQueryString}"/>     
   
     <ww:submit label="Go!"/>
   </ww:form>
 

Modified: 
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/results.jsp
URL: 
http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/results.jsp?rev=677197&r1=677196&r2=677197&view=diff
==============================================================================
--- 
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/results.jsp
 (original)
+++ 
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/results.jsp
 Wed Jul 16 01:46:38 2008
@@ -122,6 +122,8 @@
                              <ww:url action="quickSearch" namespace="/">
                                <ww:param name="q" value="%{'${q}'}"/>
                                <ww:param name="currentPage" value="%{'${i}'}"/>
+                               <ww:param name="searchResultsOnly" 
value="%{'${searchResultsOnly}'}"/>
+                               <ww:param name="completeQueryString" 
value="%{'${completeQueryString}'}"/>
                              </ww:url>
                          </c:set>
                                  <a href="${specificPageUrl}">${i + 1}</a>


Reply via email to