]> source.dussan.org Git - archiva.git/commitdiff
[MRM-1043]
authorMaria Odea B. Ching <oching@apache.org>
Fri, 13 Feb 2009 11:25:47 +0000 (11:25 +0000)
committerMaria Odea B. Ching <oching@apache.org>
Fri, 13 Feb 2009 11:25:47 +0000 (11:25 +0000)
o moved the advanced search to the quick search page
o dynamically add search criteria
o added additional test in SearchAction

git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@744080 13f79535-47bb-0310-9956-ffa450edef68

archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/src/main/java/org/apache/archiva/consumers/lucene/NexusIndexerConsumer.java
archiva-modules/archiva-base/archiva-indexer/src/test/java/org/apache/archiva/indexer/search/NexusRepositorySearchTest.java
archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/SearchAction.java
archiva-modules/archiva-web/archiva-webapp/src/main/resources/struts.xml
archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/quickSearch.jsp
archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/results.jsp
archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/SearchActionTest.java

index 0455f7e97c29edf9ea5ea2d23ba367f5b8db53b9..ef826bd2cff9418a39c33dd97d8bd1facc570d60 100644 (file)
@@ -57,11 +57,11 @@ public class NexusIndexerConsumer
 {
     private static final Logger log = LoggerFactory.getLogger( NexusIndexerConsumer.class );
 
-    private final NexusIndexer indexer;
+    private NexusIndexer indexer;
 
-    private final ArtifactContextProducer artifactContextProducer;
+    private ArtifactContextProducer artifactContextProducer;
 
-    private final IndexPacker indexPacker;
+    private IndexPacker indexPacker;
 
     private ManagedDefaultRepositoryContent repositoryContent;
 
index 1b55c8e10eaace4290a90ae996c9dae5ad1ff19d..85f0c03047c349c0e2813a7cf8edfcdd28fed2e4 100644 (file)
@@ -425,4 +425,5 @@ public class NexusRepositorySearchTest
         assertFalse( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_2 + "/.indexer" ).exists() );
     }
 
+    // TODO: add test when an existing index already exists
 }
index 260703e206c8853dece661ac07578bd58ca7682f..c0d937e413c069e35b092678dda6829d9f06f850 100644 (file)
@@ -22,6 +22,7 @@ package org.apache.maven.archiva.web.action;
 import java.net.MalformedURLException;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -60,7 +61,7 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
  *
  * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="searchAction"
  */
-public class SearchAction
+public class SearchAction 
     extends PlexusActionSupport
     implements Preparable
 {
@@ -131,6 +132,8 @@ public class SearchAction
     private boolean fromResultsPage;
 
     private RepositorySearch nexusSearch;
+    
+    private Map<String, String> searchFields;
         
     public boolean isFromResultsPage()
     {
@@ -161,16 +164,49 @@ public class SearchAction
         {
             managedRepositoryList.add( "all" );
         }
+        
+        searchFields = new HashMap<String, String>();
+        searchFields.put( "groupId", "Group ID" );
+        searchFields.put( "artifactId", "Artifact ID" );
+        searchFields.put( "version", "Version" );
+        searchFields.put( "className", "Class/Package Name" ); 
+        searchFields.put( "repositoryId", "Repository" );
+        
+        super.clearErrorsAndMessages();       
+        clearSearchFields();
+    }
+    
+    private void clearSearchFields()
+    {
+        repositoryId = "";
+        artifactId = "";
+        groupId = "";
+        version = "";
+        className = "";     
+        currentPage = 0;
     }
 
     // advanced search MRM-90 -- filtered search
     public String filteredSearch()
         throws MalformedURLException, RepositoryIndexException, RepositoryIndexSearchException
-    {
+    {   
+        // TODO: 
+        // - repositories must be provided as a select box instead of as a textfield!
+        // - what about the row count?
+        // - remove advancedSearch.jsp
+        
+        if ( ( groupId == null || "".equals( groupId ) ) &&
+            ( artifactId == null || "".equals( artifactId ) ) && ( className == null || "".equals( className ) ) &&
+            ( version == null || "".equals( version ) ) )
+        {   
+            addActionError( "Advanced Search - At least one search criteria must be provided." );
+            return INPUT;
+        }
+        
         fromFilterSearch = true;
-
+        
         if ( CollectionUtils.isEmpty( managedRepositoryList ) )
-        {
+        {            
             return GlobalResults.ACCESS_TO_NO_REPOS;
         }
 
@@ -178,22 +214,24 @@ public class SearchAction
 
         limits.setPageSize( rowCount );
         List<String> selectedRepos = new ArrayList<String>();
-
-        if ( repositoryId.equals( "all" ) )
+        
+        if ( repositoryId == null || StringUtils.isBlank( repositoryId ) ||
+            "all".equals( StringUtils.stripToEmpty( repositoryId ) ) )
         {
             selectedRepos = getObservableRepos();
         }
         else
         {
             selectedRepos.add( repositoryId );
-        }
+        }        
 
         if ( CollectionUtils.isEmpty( selectedRepos ) )
-        {
+        {         
             return GlobalResults.ACCESS_TO_NO_REPOS;
         }
 
-        SearchFields searchFields = new SearchFields( groupId, artifactId, version, null, className, selectedRepos );
+        SearchFields searchFields =
+            new SearchFields( groupId, artifactId, version, null, className, selectedRepos );
                 
         // TODO: add packaging in the list of fields for advanced search (UI)?
         try
@@ -641,4 +679,14 @@ public class SearchAction
     {
         this.archivaXworkUser = archivaXworkUser;
     }
+
+    public Map<String, String> getSearchFields()
+    {
+        return searchFields;
+    }
+
+    public void setSearchFields( Map<String, String> searchFields )
+    {
+        this.searchFields = searchFields;
+    }
 }
index af05d4e0c47cc019ba6cfb95faf762d23d0ab016..e478e2cbf964536118b8847ea3af8337a6f485be 100644 (file)
     </action>
 
     <action name="filteredSearch" class="searchAction" method="filteredSearch">
-      <result name="input">/WEB-INF/jsp/advancedSearch.jsp</result>
+      <result name="input">/WEB-INF/jsp/quickSearch.jsp</result>
       <result>/WEB-INF/jsp/results.jsp</result>
       <result name="error">/WEB-INF/jsp/quickSearch.jsp</result>
     </action>
index f5e05d9db96de67345a797379c2f9774ecb6ba49..a63ec75c05e055b96995d15b8d5fabe865bff33e 100644 (file)
 <head>
   <title>Quick Search</title>
   <s:head/>
+  <script type="text/javascript">  
+    function addSearchField(fieldText, field, divName)
+    {     
+      var element = document.getElementById( field );
+      if( element != null )
+      {
+        alert( "Cannot add field! Field has already been added." );
+        return 0;
+      }
+
+      var table = document.getElementById( "dynamicTable" );
+      var row = document.createElement( "TR" );
+      var label = document.createElement("TD");
+      label.innerHTML = fieldText + ": ";      
+     
+      var textfield = document.createElement( "TD" );
+      var inp1 =  document.createElement( "INPUT" );
+      inp1.setAttribute( "type", "text" );
+      inp1.setAttribute( "size", "30" );
+      inp1.setAttribute( "id", field );
+      inp1.setAttribute( "name", field );
+      textfield.appendChild( inp1 );
+
+      row.appendChild( label ); 
+      row.appendChild( textfield );
+      table.appendChild( row );
+    }
+  </script>  
+
   <script type="text/javascript" src="<c:url value='/js/jquery/jquery-1.2.6.pack.js'/>"></script>
   <script type="text/javascript">
     $(document).ready(function(){
     });
   });
   </script>
+  
+  <%-- advanced search --%>
+  <script type="text/javascript">
+    $(document).ready(function(){
+    
+    $("table.settings-search").hide();
+    $("a.expand-search").click(function(event){
+      event.preventDefault();
+      $(this).next().toggle("slow");
+    });
+  });
+  </script>
 </head>
 
 <s:if test="%{infoMessage != null}">
 
 <div id="contentArea">
 <div id="searchBox">
-  <s:form method="get" action="quickSearch" validate="true">
-    <s:textfield label="Search for" size="50" name="q"/>
-    <s:hidden name="completeQueryString" value="%{completeQueryString}"/>        
-    <s:submit value="Search"/>
-  </s:form>
-
-  <s:url id="filteredSearchUrl" action="advancedSearch"/>
-  <s:a href="%{filteredSearchUrl}">
-    Advanced Search >>
-  </s:a>
 
+  <c:url var="iconCreateUrl" value="/images/icons/create.png" />
+  
+  <s:form method="get" id="quickSearch" action="quickSearch" validate="true">    
+    <s:textfield label="Search for" size="50" name="q"/> 
+    <s:hidden name="completeQueryString" value="%{completeQueryString}"/>  
+    <s:submit value="Search"/>         
+  </s:form>  
   <p>
     <s:actionerror/>
   </p>
 </div>
-<div id="searchHint">
-  
+
+<div id="searchHint">  
   Enter your search terms. A variety of data will be searched for your keywords. <a class="expand" href="#"><img src="<c:url value="/images/icon_info_sml.gif"/>" /></a>
+  
   <table class="settings">
-    <tr>
-      <td>
-        <b>*</b> To search for Java classes or packages, just type the class name or package name in the search box.<br/>  
-      </td>
-    </tr>
     <tr>
       <td>
         <b>*</b> To perform a boolean <code>NOT</code> search, use the keyword <code>NOT</code> after your search
          <code>myQueryTerm NOT dependency</code> 
       </td>
     </tr>
+    <tr>
+      <td>
+        <b>*</b> To do a filtered or advanced search, select the criteria from the list below and click the <img src="${iconCreateUrl}"/> icon. Specify the term you want to be matched in the created text field.
+      </td>
+    </tr>
+    <tr>
+      <td>    
+        <s:form id="filteredSearch" method="get" action="filteredSearch" validate="true">  
+          <label><strong>Advanced Search Fields: </strong></label><s:select name="searchField" list="searchFields" theme="simple"/> 
+          <s:a href="#" title="Add Search Field" onclick="addSearchField( document.filteredSearch.searchField.options[document.filteredSearch.searchField.selectedIndex].text, document.filteredSearch.searchField.value, 'dynamicFields' )" theme="simple">
+            <img src="${iconCreateUrl}" />
+          </s:a>
+          <table id="dynamicTable">          
+            <tr>
+              <td/>
+              <td/>  
+            </tr>
+          </table> 
+          <s:submit value="Search" theme="simple"/>  
+        </s:form>  
+      </td>
+    </tr>    
   </table>
   
 </div>
index 0ee7600129e7d8be86cfe60df975e0683780692c..119b4fdeebe23537eb4f7664e8ba477f9e2998b1 100644 (file)
 <head>
   <title>Search Results</title>
   <s:head/>
+  <script type="text/javascript">  
+    function addSearchField(fieldText, field, divName)
+    {     
+      var element = document.getElementById( field );
+      if( element != null )
+      {
+        alert( "Cannot add field! Field has already been added." );
+        return 0;
+      }
+
+      var table = document.getElementById( "dynamicTable" );
+      var row = document.createElement( "TR" );
+      var label = document.createElement("TD");
+      label.innerHTML = fieldText + ": ";      
+     
+      var textfield = document.createElement( "TD" );
+      var inp1 =  document.createElement( "INPUT" );
+      inp1.setAttribute( "type", "text" );
+      inp1.setAttribute( "size", "30" );
+      inp1.setAttribute( "id", field );
+      inp1.setAttribute( "name", field );
+      textfield.appendChild( inp1 );
+
+      row.appendChild( label ); 
+      row.appendChild( textfield );
+      table.appendChild( row );
+    }
+  </script>  
 </head>
 
 <body>
 
+<c:url var="iconCreateUrl" value="/images/icons/create.png" />
+
 <c:if test="${fromFilterSearch == true}">
   <h1>Advanced Search</h1>
 </c:if>
   <div id="searchBoxResults">
 
     <c:if test="${fromFilterSearch == true}">
+    <table>
+    <tr>
+      <td>
+        <b>*</b> To do a filtered or advanced search, select the criteria from the list below and click the <img src="${iconCreateUrl}"/> icon. Specify the term you want to be matched in the created text field.
+      </td>
+    </tr>
+    <tr>
+      <td>
+      <s:form id="filteredSearch" method="get" action="filteredSearch" validate="true">
+         <s:hidden name="fromFilterSearch" value="%{#attr.fromFilterSearch}" theme="simple"/>  
+         <label><strong>Advanced Search Fields: </strong></label><s:select name="searchField" list="searchFields" theme="simple"/> 
+         <s:a href="#" title="Add Search Field" onclick="addSearchField( document.filteredSearch.searchField.options[document.filteredSearch.searchField.selectedIndex].text, document.filteredSearch.searchField.value, 'dynamicFields' )" theme="simple">
+            <img src="${iconCreateUrl}" />
+         </s:a>
+         <table id="dynamicTable">          
+           <tr>
+             <td/>
+             <td/>  
+           </tr>
+         </table> 
+         <s:submit value="Search" theme="simple"/>  
+       </s:form>  
+       </td>
+     </tr>
+     </table>
+
+      <%--
       <s:form method="get" action="filteredSearch" validate="true">
         <s:textfield label="Row Count" size="50" name="rowCount"/>
         <s:textfield label="Group Id" size="50" name="groupId"/>
       <script type="text/javascript">
         document.getElementById("filteredSearch_groupId").focus();
       </script>
-      </c:if>
+      --%>
+    </c:if>
     <c:if test="${fromFilterSearch == false}">
       <s:form method="get" action="quickSearch" validate="true">
         <s:textfield label="Search for" size="50" name="q"/>
   <p>
     <s:actionerror/>
   </p>
-
   </div>
 
   <h1>Results</h1>
   </div>
 </div>
 </body>
-</html>
+</html>
\ No newline at end of file
index 323002fc799ec58a5ac828207a055d2d3983c7b7..b01a3d8b0d7bcd8acff5f67711b21c14e282798f 100644 (file)
@@ -451,6 +451,7 @@ public class SearchActionTest
     {
         List<String> managedRepos = new ArrayList<String>();
         
+        action.setGroupId( "org.apache.archiva" );
         action.setManagedRepositoryList( managedRepos );
         
         String result = action.filteredSearch();
@@ -458,6 +459,21 @@ public class SearchActionTest
         assertEquals( GlobalResults.ACCESS_TO_NO_REPOS, result );
     }
     
+    public void testAdvancedSearchNoSpecifiedCriteria()
+        throws Exception
+    {
+        List<String> managedRepos = new ArrayList<String>();
+        
+        action.setManagedRepositoryList( managedRepos );
+        
+        String result = action.filteredSearch();
+        
+        assertEquals( Action.INPUT, result );
+        assertFalse( action.getActionErrors().isEmpty() );
+        assertEquals( "Advanced Search - At least one search criteria must be provided.",
+                      (String) action.getActionErrors().iterator().next() );
+    }
+    
     // find artifact..
     
     public void testFindArtifactWithOneHit()