You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ep...@apache.org on 2006/01/05 08:20:42 UTC

svn commit: r366106 - in /maven/repository-manager/trunk/maven-repository-indexer: ./ src/main/java/org/apache/maven/repository/indexing/ src/test/java/org/apache/maven/repository/indexing/

Author: epunzalan
Date: Wed Jan  4 23:20:26 2006
New Revision: 366106

URL: http://svn.apache.org/viewcvs?rev=366106&view=rev
Log:
PR: MRM-44
Submitted by: Maria Odea Ching

Patch for searching by groupId, artifactId, version, name, package, class, and file.  Also allowed nested searching using AND and OR.

Refactored the Searcher for common code and placed them inside an Abstract class.

Added:
    maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/AbstractRepositoryIndexSearcher.java   (with props)
Modified:
    maven/repository-manager/trunk/maven-repository-indexer/pom.xml
    maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/ArtifactRepositoryIndexSearcher.java
    maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/RepositoryIndexSearcher.java
    maven/repository-manager/trunk/maven-repository-indexer/src/test/java/org/apache/maven/repository/indexing/ArtifactRepositoryIndexingTest.java

Modified: maven/repository-manager/trunk/maven-repository-indexer/pom.xml
URL: http://svn.apache.org/viewcvs/maven/repository-manager/trunk/maven-repository-indexer/pom.xml?rev=366106&r1=366105&r2=366106&view=diff
==============================================================================
--- maven/repository-manager/trunk/maven-repository-indexer/pom.xml (original)
+++ maven/repository-manager/trunk/maven-repository-indexer/pom.xml Wed Jan  4 23:20:26 2006
@@ -35,6 +35,10 @@
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-model</artifactId>
+    </dependency>
+    <dependency>
       <groupId>lucene</groupId>
       <artifactId>lucene</artifactId>
       <version>1.4.3</version>
@@ -42,7 +46,6 @@
     <dependency>
       <groupId>org.codehaus.plexus</groupId>
       <artifactId>plexus-utils</artifactId>
-      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.codehaus.plexus</groupId>

Added: maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/AbstractRepositoryIndexSearcher.java
URL: http://svn.apache.org/viewcvs/maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/AbstractRepositoryIndexSearcher.java?rev=366106&view=auto
==============================================================================
--- maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/AbstractRepositoryIndexSearcher.java (added)
+++ maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/AbstractRepositoryIndexSearcher.java Wed Jan  4 23:20:26 2006
@@ -0,0 +1,258 @@
+package org.apache.maven.repository.indexing;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Hits;
+import org.apache.lucene.document.Document;
+import org.apache.maven.repository.indexing.query.OptionalQuery;
+import org.apache.maven.repository.indexing.query.Query;
+import org.apache.maven.repository.indexing.query.RequiredQuery;
+import org.apache.maven.repository.indexing.query.SinglePhraseQuery;
+import org.apache.maven.repository.indexing.query.AbstractCompoundQuery;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+/**
+ *
+ */
+public abstract class AbstractRepositoryIndexSearcher
+    implements RepositoryIndexSearcher
+{
+    protected ArtifactRepositoryIndex index;
+
+    private BooleanQuery bQry;
+
+    private BooleanQuery mainQry;
+
+    private boolean isRequired = true;
+
+    /**
+     * Constructor
+     *
+     * @param index   the index object
+     */
+    public AbstractRepositoryIndexSearcher( ArtifactRepositoryIndex index )
+    {
+        this.index = index;
+    }
+
+    /**
+     * Search the artifact based on the search criteria specified in the query
+     * object. Returns a list of artifact objects
+     *
+     * @param query the query object that contains the search criteria
+     * @return List
+     * @throws RepositoryIndexSearchException
+     */
+    public List search( Query query )
+        throws RepositoryIndexSearchException
+    {
+        List artifactList = null;
+        IndexSearcher searcher = null;
+        Hits hits = null;
+
+        try
+        {
+            searcher = new IndexSearcher( index.getIndexPath() );
+        }
+        catch ( IOException e )
+        {
+            throw new RepositoryIndexSearchException( e.getMessage(), e );
+        }
+
+        if ( query instanceof SinglePhraseQuery )
+        {
+            SinglePhraseQuery singleQry = (SinglePhraseQuery) query;
+            createSubQuery();
+            try
+            {
+                addQuery( singleQry.getField(), singleQry.getValue(), true, false );
+                hits = searcher.search( bQry );
+            }
+            catch ( IOException ie )
+            {
+                throw new RepositoryIndexSearchException( ie.getMessage(), ie );
+            }
+            catch ( ParseException pe )
+            {
+                throw new RepositoryIndexSearchException( pe.getMessage(), pe );
+            }
+
+        }
+        else if ( query instanceof RequiredQuery || query instanceof OptionalQuery )
+        {
+            createMainQuery();
+            try
+            {
+                buildCompoundQuery( query );
+                hits = searcher.search( mainQry );
+            }
+            catch ( IOException ie )
+            {
+                throw new RepositoryIndexSearchException( ie.getMessage(), ie );
+            }
+            catch ( ParseException pe )
+            {
+                throw new RepositoryIndexSearchException( pe.getMessage(), pe );
+            }
+        }
+
+        try
+        {
+            artifactList = buildList( hits );
+            searcher.close();
+        }
+        catch ( IOException ie )
+        {
+            ie.printStackTrace();
+            throw new RepositoryIndexSearchException( ie.getMessage(), ie );
+        }
+
+        return artifactList;
+    }
+
+    /**
+     * Create a main BooleanQuery object that will contain the other
+     * BooleanQuery objects.
+     */
+    private void createMainQuery()
+    {
+        mainQry = new BooleanQuery();
+    }
+
+    /**
+     * Add the other BooleanQuery objects to the main BooleanQuery object
+     *
+     * @param required   specifies if the search is AND or OR
+     * @param prohibited specifies if NOT will be used in the search
+     */
+    private void addToMainQuery( boolean required, boolean prohibited )
+    {
+        mainQry.add( bQry, required, prohibited );
+    }
+
+    /**
+     * Create a new BooleanQuery object for nested search
+     */
+    private void createSubQuery()
+    {
+        bQry = new BooleanQuery();
+    }
+
+    /**
+     * Add query to the globally declared BooleanQuery object
+     *
+     * @param field      the name of the field in the index where the value is to be searched
+     * @param value      the value to be searched in the index
+     * @param required   specifies if the search is AND or OR
+     * @param prohibited specifies if NOT will be used in the search
+     * @throws ParseException
+     */
+    private void addQuery( String field, String value, boolean required, boolean prohibited )
+        throws ParseException
+    {
+        QueryParser parser = new QueryParser( field, index.getAnalyzer() );
+        org.apache.lucene.search.Query qry = parser.parse( value );
+        bQry.add( qry, required, prohibited );
+    }
+
+    /**
+     * Build or construct the query that will be used by the searcher
+     *
+     * @param query the query object that contains the search criteria
+     * @throws ParseException
+     */
+    private void buildCompoundQuery( Query query )
+        throws ParseException
+    {
+        AbstractCompoundQuery cQry = null;
+        boolean required = false;
+
+        if ( query instanceof RequiredQuery )
+        {
+            cQry = (RequiredQuery) query;
+            required = true;
+        }
+        else
+        {
+            cQry = (OptionalQuery) query;
+            required = false;
+        }
+
+        boolean reset = true;
+
+        // get the query list and iterate through each
+        List queries = cQry.getQueryList();
+        for ( Iterator iter = queries.iterator(); iter.hasNext(); )
+        {
+            Query query2 = (Query) iter.next();
+
+            if ( query2 instanceof SinglePhraseQuery )
+            {
+                SinglePhraseQuery sQry = (SinglePhraseQuery) query2;
+                if ( reset )
+                {
+                    createSubQuery();
+                }
+                addQuery( sQry.getField(), sQry.getValue(), required, false );
+                reset = false;
+
+                if ( !iter.hasNext() )
+                {
+                    addToMainQuery( isRequired, false );
+                }
+
+            }
+            else if ( query2 instanceof RequiredQuery || query2 instanceof OptionalQuery )
+            {
+                isRequired = required;
+                buildCompoundQuery( query2 );
+            }
+        }
+    }
+
+    /**
+     * Create a list of artifact objects from the result set.
+     *
+     * @param hits the search result set
+     * @return List
+     * @throws IOException
+     */
+    private List buildList( Hits hits )
+        throws IOException
+    {
+        List artifactList = new ArrayList();
+
+        for ( int i = 0; i < hits.length(); i++ )
+        {
+            Document doc = hits.doc( i );
+
+            artifactList.add( createSearchedObjectFromIndexDocument( doc ) );
+        }
+
+        return artifactList;
+    }
+
+    protected abstract Object createSearchedObjectFromIndexDocument( Document doc );
+}

Propchange: maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/AbstractRepositoryIndexSearcher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/AbstractRepositoryIndexSearcher.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/ArtifactRepositoryIndexSearcher.java
URL: http://svn.apache.org/viewcvs/maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/ArtifactRepositoryIndexSearcher.java?rev=366106&r1=366105&r2=366106&view=diff
==============================================================================
--- maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/ArtifactRepositoryIndexSearcher.java (original)
+++ maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/ArtifactRepositoryIndexSearcher.java Wed Jan  4 23:20:26 2006
@@ -17,25 +17,20 @@
  */
 
 import org.apache.lucene.document.Document;
-import org.apache.lucene.queryParser.ParseException;
-import org.apache.lucene.queryParser.QueryParser;
-import org.apache.lucene.search.Hits;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
+import org.apache.lucene.search.BooleanQuery;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.factory.ArtifactFactory;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
+import java.io.File;
 
 /**
  * This class searches the index for existing artifacts that contains the
  * specified query string.
+ *
+ * @author Maria Odea Ching
  */
 public class ArtifactRepositoryIndexSearcher
-    implements RepositoryIndexSearcher
+    extends AbstractRepositoryIndexSearcher
 {
     private static final String NAME = "name";
 
@@ -46,59 +41,37 @@
     private static final String VERSION = "version";
 
     private ArtifactFactory factory;
-    
-    private ArtifactRepositoryIndex index;
 
-    public ArtifactRepositoryIndexSearcher( ArtifactRepositoryIndex index, ArtifactFactory factory )
-    {
-        this.factory = factory;
-        this.index = index;
-    }
+    private BooleanQuery bQry;
+
+    private BooleanQuery mainQry;
+
+    private boolean isRequired = true;
 
     /**
-     * Search the artifact that contains the query string in the specified
-     * search field.
+     * Constructor
      *
-     * @param queryString
-     * @param searchField
+     * @param index   the index object
+     * @param factory ArtifactFactory object
      */
-    public List search( String queryString, String searchField )
-        throws RepositoryIndexSearchException
+    public ArtifactRepositoryIndexSearcher( ArtifactRepositoryIndex index, ArtifactFactory factory )
     {
-        List artifactList = new ArrayList();
+        super( index );
+        this.factory = factory;
+    }
 
-        try
-        {
-            IndexSearcher searcher = new IndexSearcher( index.getIndexPath() );
-            QueryParser parser = new QueryParser( searchField, index.getAnalyzer() );
-            Query qry = parser.parse( queryString );
-            Hits hits = searcher.search( qry );
-
-            for ( int i = 0; i < hits.length(); i++ )
-            {
-                Document doc = hits.doc( i );
-
-                String groupId = doc.get( GROUPID );
-                String artifactId = doc.get( ARTIFACTID );
-                String version = doc.get( VERSION );
-                String name = doc.get( NAME );
-                String packaging = name.substring( name.lastIndexOf( '.' ) + 1 );
-                Artifact artifact = factory.createBuildArtifact( groupId, artifactId, version, packaging );
-
-                artifactList.add( artifact );
-            }
-
-            searcher.close();
-        }
-        catch ( IOException e )
-        {
-            throw new RepositoryIndexSearchException( e.getMessage(), e );
-        }
-        catch ( ParseException e )
-        {
-            throw new RepositoryIndexSearchException( "Error parsing query: " + e.getMessage() );
-        }
+    protected Object createSearchedObjectFromIndexDocument( Document doc )
+    {
+        String groupId = doc.get( GROUPID );
+        String artifactId = doc.get( ARTIFACTID );
+        String version = doc.get( VERSION );
+        String name = doc.get( NAME );
+        String packaging = name.substring( name.lastIndexOf( '.' ) + 1 );
+        Artifact artifact = factory.createBuildArtifact( groupId, artifactId, version, packaging );
+        String groupIdTemp = groupId.replace( '.', '/' );
+        artifact.setFile( new File(
+            index.getRepository().getBasedir() + groupIdTemp + "/" + artifactId + "/" + version + "/" + name ) );
 
-        return artifactList;
+        return artifact;
     }
 }

Modified: maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/RepositoryIndexSearcher.java
URL: http://svn.apache.org/viewcvs/maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/RepositoryIndexSearcher.java?rev=366106&r1=366105&r2=366106&view=diff
==============================================================================
--- maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/RepositoryIndexSearcher.java (original)
+++ maven/repository-manager/trunk/maven-repository-indexer/src/main/java/org/apache/maven/repository/indexing/RepositoryIndexSearcher.java Wed Jan  4 23:20:26 2006
@@ -18,19 +18,21 @@
 
 import java.util.List;
 
+import org.apache.maven.repository.indexing.query.Query;
+import org.apache.maven.artifact.Artifact;
+import org.apache.lucene.document.Document;
+
 /**
- *
+ * @author Maria Odea Ching
  */
 public interface RepositoryIndexSearcher
 {
     /**
-     * Search the artifact that contains the query string in the specified
-     * search field.
-     *
-     * @param index
-     * @param queryString
-     * @param searchField
+     * Search the artifact based on the search criteria specified in the query object. Returns a list of
+     * artifact objects. 
+     * @param query The query object that contains the search criteria.
+     * @return List
+     * @exception RepositoryIndexSearchException
      */
-    List search( String queryString, String searchField )
-        throws RepositoryIndexSearchException;
+    List search(Query query) throws RepositoryIndexSearchException;
 }

Modified: maven/repository-manager/trunk/maven-repository-indexer/src/test/java/org/apache/maven/repository/indexing/ArtifactRepositoryIndexingTest.java
URL: http://svn.apache.org/viewcvs/maven/repository-manager/trunk/maven-repository-indexer/src/test/java/org/apache/maven/repository/indexing/ArtifactRepositoryIndexingTest.java?rev=366106&r1=366105&r2=366106&view=diff
==============================================================================
--- maven/repository-manager/trunk/maven-repository-indexer/src/test/java/org/apache/maven/repository/indexing/ArtifactRepositoryIndexingTest.java (original)
+++ maven/repository-manager/trunk/maven-repository-indexer/src/test/java/org/apache/maven/repository/indexing/ArtifactRepositoryIndexingTest.java Wed Jan  4 23:20:26 2006
@@ -21,14 +21,21 @@
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.repository.digest.DefaultDigester;
+import org.apache.maven.repository.digest.Digester;
+import org.apache.maven.repository.indexing.query.OptionalQuery;
+import org.apache.maven.repository.indexing.query.Query;
+import org.apache.maven.repository.indexing.query.RequiredQuery;
+import org.apache.maven.repository.indexing.query.SinglePhraseQuery;
 import org.codehaus.plexus.PlexusTestCase;
 import org.codehaus.plexus.util.FileUtils;
 
 import java.io.File;
+import java.util.Iterator;
 import java.util.List;
 
 /**
- *
+ * @author Edwin Punzalan/Maria Odea Ching
  */
 public class ArtifactRepositoryIndexingTest
     extends PlexusTestCase
@@ -51,6 +58,14 @@
 
     private String indexPath;
 
+    private Digester digester;
+
+    private static final String SHA1 = "sha1";
+
+    private static final String MD5 = "md5";
+
+    private static final String NAME = "name";
+
     protected void setUp()
         throws Exception
     {
@@ -61,8 +76,10 @@
         ArtifactRepositoryLayout layout = (ArtifactRepositoryLayout) lookup( ArtifactRepositoryLayout.ROLE, "default" );
         ArtifactRepositoryFactory repoFactory = (ArtifactRepositoryFactory) lookup( ArtifactRepositoryFactory.ROLE );
         repository = repoFactory.createArtifactRepository( "test", repoDir, layout, null, null );
+        digester = new DefaultDigester();
 
         indexPath = "target/index";
+        FileUtils.deleteDirectory( indexPath );
     }
 
     public void testIndexerExceptions()
@@ -79,7 +96,7 @@
         }
         catch ( RepositoryIndexException e )
         {
-            //expected
+            // expected
         }
 
         try
@@ -90,7 +107,7 @@
         }
         catch ( RepositoryIndexException e )
         {
-            //expected
+            // expected
         }
 
         Artifact artifact = getArtifact( "test", "test-artifactId", "1.0" );
@@ -98,7 +115,7 @@
 
         indexer = factory.createArtifactRepositoryIndex( indexPath, repository );
         indexer.close();
-        
+
         try
         {
             indexer.indexArtifact( artifact );
@@ -106,7 +123,7 @@
         }
         catch ( RepositoryIndexException e )
         {
-            //expected
+            // expected
         }
 
         try
@@ -116,7 +133,7 @@
         }
         catch ( RepositoryIndexException e )
         {
-            //expected
+            // expected
         }
 
         indexer = factory.createArtifactRepositoryIndex( indexPath, repository );
@@ -128,12 +145,17 @@
         }
         catch ( RepositoryIndexException e )
         {
-            //expected
+            // expected
         }
 
         indexer.close();
     }
 
+    /**
+     * Create an index that will be used for testing.
+     * 
+     * @throws Exception
+     */
     public void createTestIndex()
         throws Exception
     {
@@ -156,7 +178,12 @@
         indexer.close();
     }
 
-    public void testSearch()
+    /**
+     * Test the ArtifactRepositoryIndexSearcher using a single-phrase search.
+     * 
+     * @throws Exception
+     */
+    public void testSearchSingle()
         throws Exception
     {
         createTestIndex();
@@ -165,32 +192,228 @@
         ArtifactRepositoryIndex indexer = factory.createArtifactRepositoryIndex( indexPath, repository );
         RepositoryIndexSearcher repoSearcher = factory.createArtifactRepositoryIndexSearcher( indexer );
 
-        List artifacts = repoSearcher.search( "test", GROUPID );
-        assertEquals( 1, artifacts.size() );
-
-        artifacts = repoSearcher.search( "test", ARTIFACTID );
-        assertEquals( 1, artifacts.size() );
-
-        artifacts = repoSearcher.search( "1.0", VERSION );
+        // search version
+        Query qry = new SinglePhraseQuery( VERSION, "1.0" );
+        List artifacts = repoSearcher.search( qry );
         assertEquals( 1, artifacts.size() );
+        for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
+        {
+            Artifact artifact = (Artifact) iter.next();
+            assertEquals( "1.0", artifact.getVersion() );
+        }
 
-        artifacts = repoSearcher.search( "App", CLASSES );
+        // search classes
+        qry = new SinglePhraseQuery( CLASSES, "App" );
+        artifacts = repoSearcher.search( qry );
         assertEquals( 1, artifacts.size() );
+        for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
+        {
+            Artifact artifact = (Artifact) iter.next();
+            assertEquals( "test-artifactId", artifact.getArtifactId() );
+        }
 
-        artifacts = repoSearcher.search( "groupId", PACKAGES );
+        // search packages
+        qry = new SinglePhraseQuery( PACKAGES, "groupId" );
+        artifacts = repoSearcher.search( qry );
         assertEquals( 1, artifacts.size() );
+        for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
+        {
+            Artifact artifact = (Artifact) iter.next();
+            assertEquals( "test-artifactId", artifact.getArtifactId() );
+        }
 
-        artifacts = repoSearcher.search( "pom.xml", FILES );
+        // search files
+        qry = new SinglePhraseQuery( FILES, "pom.xml" );
+        artifacts = repoSearcher.search( qry );
         assertEquals( 3, artifacts.size() );
+        Iterator iter = artifacts.iterator();
+        if ( iter.hasNext() )
+        {
+            Artifact artifact = (Artifact) iter.next();
+            assertEquals( "test-artifactId", artifact.getArtifactId() );
+        }
 
-        artifacts = repoSearcher.search( "org.apache.maven", GROUPID );
+        // search group id
+        qry = new SinglePhraseQuery( GROUPID, "org.apache.maven" );
+        artifacts = repoSearcher.search( qry );
         assertEquals( 2, artifacts.size() );
+        iter = artifacts.iterator();
+        if ( iter.hasNext() )
+        {
+            Artifact artifact = (Artifact) iter.next();
+            assertEquals( "org.apache.maven", artifact.getGroupId() );
+        }
 
-        artifacts = repoSearcher.search( "maven-artifact", ARTIFACTID );
+        // search artifact id
+        qry = new SinglePhraseQuery( ARTIFACTID, "maven-artifact" );
+        artifacts = repoSearcher.search( qry );
         assertEquals( 1, artifacts.size() );
+        for ( iter = artifacts.iterator(); iter.hasNext(); )
+        {
+            Artifact artifact = (Artifact) iter.next();
+            assertEquals( "maven-artifact", artifact.getArtifactId() );
+        }
 
-        artifacts = repoSearcher.search( "2", VERSION );
+        // search version
+        qry = new SinglePhraseQuery( VERSION, "2" );
+        artifacts = repoSearcher.search( qry );
         assertEquals( 2, artifacts.size() );
+        for ( iter = artifacts.iterator(); iter.hasNext(); )
+        {
+            Artifact artifact = (Artifact) iter.next();
+            assertTrue( artifact.getVersion().indexOf( "2" ) != -1 );
+        }
+
+        // search sha1 checksum
+        Artifact artifact = getArtifact( "org.apache.maven", "maven-model", "2.0" );
+        artifact.setFile( new File( repository.getBasedir(), repository.pathOf( artifact ) ) );
+
+        String sha1 = digester.createChecksum( artifact.getFile(), Digester.SHA1 );
+
+        qry = new SinglePhraseQuery( SHA1, sha1.trim() );
+        artifacts = repoSearcher.search( qry );
+        assertEquals( 1, artifacts.size() );
+        for ( iter = artifacts.iterator(); iter.hasNext(); )
+        {
+            Artifact artifact2 = (Artifact) iter.next();
+            String sha1Tmp = digester.createChecksum( artifact2.getFile(), Digester.SHA1 );
+            assertEquals( sha1, sha1Tmp );
+        }
+
+        // search md5 checksum
+        String md5 = digester.createChecksum( artifact.getFile(), Digester.MD5 );
+        qry = new SinglePhraseQuery( MD5, md5.trim() );
+        artifacts = repoSearcher.search( qry );
+        assertEquals( 1, artifacts.size() );
+        for ( iter = artifacts.iterator(); iter.hasNext(); )
+        {
+            Artifact artifact2 = (Artifact) iter.next();
+            String md5Tmp = digester.createChecksum( artifact2.getFile(), Digester.MD5 );
+            assertEquals( md5, md5Tmp );
+        }
+
+        indexer.close();
+    }
+
+    /**
+     * Test the ArtifactRepositoryIndexSearcher using compound search (AND, OR).
+     * 
+     * @throws Exception
+     */
+    public void testSearchCompound()
+        throws Exception
+    {
+
+        createTestIndex();
+
+        RepositoryIndexingFactory factory = (RepositoryIndexingFactory) lookup( RepositoryIndexingFactory.ROLE );
+        ArtifactRepositoryIndex indexer = factory.createArtifactRepositoryIndex( indexPath, repository );
+        RepositoryIndexSearcher repoSearcher = factory.createArtifactRepositoryIndexSearcher( indexer );
+
+        // Criteria 1: required query
+        // ex. artifactId=maven-artifact AND groupId=org.apache.maven
+        Query qry1 = new SinglePhraseQuery( ARTIFACTID, "maven-artifact" );
+        Query qry2 = new SinglePhraseQuery( GROUPID, "org.apache.maven" );
+        RequiredQuery rQry = new RequiredQuery();
+        rQry.add( qry1 );
+        rQry.add( qry2 );
+
+        List artifacts = repoSearcher.search( rQry );
+        for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
+        {
+            Artifact artifact = (Artifact) iter.next();
+            assertEquals( "maven-artifact", artifact.getArtifactId() );
+            assertEquals( "org.apache.maven", artifact.getGroupId() );
+        }
+
+        // Criteria 2: nested required query
+        // ex. (artifactId=maven-artifact AND groupId=org.apache.maven) OR
+        // version=2.0.3
+        Query qry3 = new SinglePhraseQuery( VERSION, "2.0.3" );
+        OptionalQuery oQry = new OptionalQuery();
+        oQry.add( rQry );
+        oQry.add( qry3 );
+
+        artifacts = repoSearcher.search( oQry );
+        for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
+        {
+            Artifact artifact = (Artifact) iter.next();
+            assertEquals( "maven-artifact", artifact.getArtifactId() );
+            assertEquals( "org.apache.maven", artifact.getGroupId() );
+        }
+
+        // Criteria 3: nested required query
+        // ex. (artifactId=maven-artifact AND groupId=org.apache.maven) AND
+        // (version=2.0.3 OR version=2.0.1)
+        // AND (name=maven-artifact-2.0.1.jar OR name=maven-artifact)
+        Query qry4 = new SinglePhraseQuery( VERSION, "2.0.1" );
+        oQry = new OptionalQuery();
+        oQry.add( qry3 );
+        oQry.add( qry4 );
+
+        OptionalQuery oQry5 = new OptionalQuery();
+        Query qry9 = new SinglePhraseQuery( NAME, "maven-artifact-2.0.1.jar" );
+        Query qry10 = new SinglePhraseQuery( NAME, "maven-artifact" );
+        oQry5.add( qry9 );
+        oQry5.add( qry10 );
+
+        RequiredQuery rQry2 = new RequiredQuery();
+        rQry2.add( oQry );
+        rQry2.add( rQry );
+        rQry2.add( oQry5 );
+
+        artifacts = repoSearcher.search( rQry2 );
+        for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
+        {
+            Artifact artifact = (Artifact) iter.next();
+            assertEquals( "maven-artifact", artifact.getArtifactId() );
+            assertEquals( "org.apache.maven", artifact.getGroupId() );
+            assertEquals( "2.0.1", artifact.getVersion() );
+        }
+
+        // Criteria 4: nested required query
+        // ex. [(artifactId=maven-artifact AND groupId=org.apache.maven) AND
+        // (version=2.0.3 OR version=2.0.1)
+        // AND (name=maven-artifact-2.0.1.jar OR name=maven-artifact)]
+        // OR [(artifactId=sample AND groupId=test)]
+        RequiredQuery rQry3 = new RequiredQuery();
+        Query qry5 = new SinglePhraseQuery( ARTIFACTID, "sample" );
+        Query qry6 = new SinglePhraseQuery( GROUPID, "test" );
+        rQry3.add( qry5 );
+        rQry3.add( qry6 );
+        OptionalQuery oQry2 = new OptionalQuery();
+        oQry2.add( rQry2 );
+        oQry2.add( rQry3 );
+
+        artifacts = repoSearcher.search( oQry2 );
+        for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
+        {
+            Artifact artifact = (Artifact) iter.next();
+            assertEquals( "maven-artifact", artifact.getArtifactId() );
+            assertEquals( "org.apache.maven", artifact.getGroupId() );
+            assertEquals( "2.0.1", artifact.getVersion() );
+        }
+
+        // Criteria 4: nested required query
+        // ex. [(artifactId=maven-artifact AND groupId=org.apache.maven) AND
+        // (version=2.0.3 OR version=2.0.1)
+        // AND (name=maven-artifact-2.0.1.jar OR name=maven-artifact)] OR
+        // [(artifactId=sample AND groupId=test)] OR
+        // [(artifactId=sample2 AND groupId=test)]
+        RequiredQuery rQry4 = new RequiredQuery();
+        Query qry7 = new SinglePhraseQuery( ARTIFACTID, "sample2" );
+        Query qry8 = new SinglePhraseQuery( GROUPID, "test" );
+        rQry4.add( qry7 );
+        rQry4.add( qry8 );
+        oQry2.add( rQry4 );
+
+        artifacts = repoSearcher.search( oQry2 );
+        for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
+        {
+            Artifact artifact = (Artifact) iter.next();
+            assertEquals( "maven-artifact", artifact.getArtifactId() );
+            assertEquals( "org.apache.maven", artifact.getGroupId() );
+        }
 
         indexer.close();
     }
@@ -210,7 +433,6 @@
         throws Exception
     {
         repository = null;
-        FileUtils.deleteDirectory( indexPath );
 
         super.tearDown();
     }