You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by br...@apache.org on 2010/12/21 08:21:44 UTC

svn commit: r1051396 - in /archiva/trunk/archiva-modules: metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/ plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/ plugins/metadata-store...

Author: brett
Date: Tue Dec 21 07:21:44 2010
New Revision: 1051396

URL: http://svn.apache.org/viewvc?rev=1051396&view=rev
Log:
[MRM-1327] re-arrange utility methods, and use search for retrieving artifacts by date

Modified:
    archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java
    archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java
    archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/test/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepositoryTest.java
    archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/test/repository.xml

Modified: archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java?rev=1051396&r1=1051395&r2=1051396&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java (original)
+++ archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java Tue Dec 21 07:21:44 2010
@@ -47,6 +47,8 @@ import java.util.Map;
 public abstract class AbstractMetadataRepositoryTest
     extends PlexusInSpringTestCase
 {
+    protected static final String OTHER_REPO_ID = "other-repo";
+
     protected MetadataRepository repository;
 
     protected static final String TEST_REPO_ID = "test";
@@ -162,9 +164,8 @@ public abstract class AbstractMetadataRe
     public void testGetArtifactOnly()
         throws MetadataResolutionException
     {
-        assertEquals( Collections.<ArtifactMetadata>emptyList(),
-                      new ArrayList<ArtifactMetadata>(
-                          repository.getArtifacts( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION ) ) );
+        assertEquals( Collections.<ArtifactMetadata>emptyList(), new ArrayList<ArtifactMetadata>(
+            repository.getArtifacts( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION ) ) );
         assertNull( repository.getProjectVersion( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION ) );
         assertNull( repository.getProject( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT ) );
         assertEquals( Collections.<String>emptyList(), repository.getRootNamespaces( TEST_REPO_ID ) );
@@ -184,7 +185,9 @@ public abstract class AbstractMetadataRe
         assertEquals( TEST_PROJECT, projectMetadata.getId() );
         assertEquals( TEST_NAMESPACE, projectMetadata.getNamespace() );
 
-        ProjectVersionMetadata projectVersionMetadata = repository.getProjectVersion( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION );
+        ProjectVersionMetadata projectVersionMetadata = repository.getProjectVersion( TEST_REPO_ID, TEST_NAMESPACE,
+                                                                                      TEST_PROJECT,
+                                                                                      TEST_PROJECT_VERSION );
         assertEquals( TEST_PROJECT_VERSION, projectVersionMetadata.getId() );
     }
 
@@ -307,9 +310,12 @@ public abstract class AbstractMetadataRe
         reference.setProjectVersion( "1.1" );
         reference.setReferenceType( ProjectVersionReference.ReferenceType.DEPENDENCY );
 
-        repository.updateProjectReference( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION, reference );
+        repository.updateProjectReference( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION,
+                                           reference );
 
-        Collection<ProjectVersionReference> references = repository.getProjectReferences( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION );
+        Collection<ProjectVersionReference> references = repository.getProjectReferences( TEST_REPO_ID, TEST_NAMESPACE,
+                                                                                          TEST_PROJECT,
+                                                                                          TEST_PROJECT_VERSION );
         assertEquals( 1, references.size() );
         reference = references.iterator().next();
         assertEquals( "another.namespace", reference.getNamespace() );
@@ -323,9 +329,10 @@ public abstract class AbstractMetadataRe
         // currently set up this way so the behaviour of both the test and the mock config return the same repository
         // set as the File implementation just uses the config rather than the content
         repository.updateNamespace( TEST_REPO_ID, "namespace" );
-        repository.updateNamespace( "other-repo", "namespace" );
+        repository.updateNamespace( OTHER_REPO_ID, "namespace" );
 
-        assertEquals( Arrays.asList( TEST_REPO_ID, "other-repo" ), new ArrayList<String>( repository.getRepositories() ) );
+        assertEquals( Arrays.asList( TEST_REPO_ID, OTHER_REPO_ID ), new ArrayList<String>(
+            repository.getRepositories() ) );
     }
 
     public void testUpdateProjectVersionMetadataIncomplete()
@@ -390,7 +397,7 @@ public abstract class AbstractMetadataRe
         metadata = repository.getProjectVersion( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION );
         assertEquals( Collections.<String>emptyList(), new ArrayList<String>( metadata.getFacetIds() ) );
     }
-    
+
     public void testUpdateProjectVersionMetadataWithExistingFacetsFacetPropertyWasRemoved()
         throws MetadataResolutionException
     {
@@ -424,7 +431,7 @@ public abstract class AbstractMetadataRe
         testFacet = (TestMetadataFacet) metadata.getFacet( TEST_FACET_ID );
         assertFalse( testFacet.toProperties().containsKey( "deleteKey" ) );
     }
-    
+
     public void testUpdateArtifactMetadataWithExistingFacets()
     {
         ArtifactMetadata metadata = createArtifact();
@@ -700,7 +707,7 @@ public abstract class AbstractMetadataRe
         assertTrue( repository.getArtifactsByDateRange( TEST_REPO_ID, null, upper ).isEmpty() );
     }
 
-     public void testGetArtifactsByRepoId()
+    public void testGetArtifactsByRepoId()
     {
         ArtifactMetadata artifact = createArtifact();
         repository.updateArtifact( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION, artifact );
@@ -767,7 +774,8 @@ public abstract class AbstractMetadataRe
         ArtifactMetadata artifact = createArtifact();
         repository.updateArtifact( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION, artifact );
 
-        assertEquals( Collections.<ArtifactMetadata>emptyList(), repository.getArtifactsByChecksum( TEST_REPO_ID, "not a checksum" ) );
+        assertEquals( Collections.<ArtifactMetadata>emptyList(), repository.getArtifactsByChecksum( TEST_REPO_ID,
+                                                                                                    "not a checksum" ) );
     }
 
     public void testDeleteArtifact()
@@ -868,8 +876,8 @@ public abstract class AbstractMetadataRe
         implements MetadataFacet
     {
         private String testFacetId;
-        
-        private Map<String, String> additionalProps;        
+
+        private Map<String, String> additionalProps;
 
         private String value;
 
@@ -884,11 +892,11 @@ public abstract class AbstractMetadataRe
             this.value = value;
             testFacetId = facetId;
         }
-        
+
         private TestMetadataFacet( String facetId, String value, Map<String, String> additionalProps )
         {
             this( facetId, value );
-            this.additionalProps = additionalProps;            
+            this.additionalProps = additionalProps;
         }
 
         public String getFacetId()
@@ -902,10 +910,10 @@ public abstract class AbstractMetadataRe
         }
 
         public Map<String, String> toProperties()
-        {            
+        {
             if ( value != null )
             {
-                if( additionalProps == null )
+                if ( additionalProps == null )
                 {
                     return Collections.singletonMap( "foo", value );
                 }
@@ -913,8 +921,8 @@ public abstract class AbstractMetadataRe
                 {
                     Map<String, String> props = new HashMap<String, String>();
                     props.put( "foo", value );
-                    
-                    for( String key : additionalProps.keySet() )
+
+                    for ( String key : additionalProps.keySet() )
                     {
                         props.put( key, additionalProps.get( key ) );
                     }
@@ -934,15 +942,15 @@ public abstract class AbstractMetadataRe
             {
                 this.value = value;
             }
-               
+
             properties.remove( "foo" );
-            
-            if( additionalProps == null )
+
+            if ( additionalProps == null )
             {
                 additionalProps = new HashMap<String, String>();
             }
-            
-            for( String key: properties.keySet() )
+
+            for ( String key : properties.keySet() )
             {
                 additionalProps.put( key, properties.get( key ) );
             }
@@ -952,7 +960,7 @@ public abstract class AbstractMetadataRe
         {
             return value;
         }
-        
+
         @Override
         public String toString()
         {

Modified: archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java?rev=1051396&r1=1051395&r2=1051396&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java (original)
+++ archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java Tue Dec 21 07:21:44 2010
@@ -34,6 +34,7 @@ import org.apache.archiva.metadata.model
 import org.apache.archiva.metadata.model.Scm;
 import org.apache.archiva.metadata.repository.MetadataRepository;
 import org.apache.archiva.metadata.repository.MetadataResolutionException;
+import org.apache.jackrabbit.commons.JcrUtils;
 import org.apache.jackrabbit.core.TransientRepository;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -44,7 +45,6 @@ import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
@@ -61,6 +61,12 @@ import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.SimpleCredentials;
+import javax.jcr.ValueFactory;
+import javax.jcr.Workspace;
+import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.nodetype.NodeTypeTemplate;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryResult;
 
 /**
  * @plexus.component role="org.apache.archiva.metadata.repository.MetadataRepository"
@@ -96,6 +102,15 @@ public class JcrMetadataRepository
             }
             // TODO: shouldn't do this in constructor since it's a singleton
             session = repository.login( new SimpleCredentials( "username", "password".toCharArray() ) );
+
+            Workspace workspace = session.getWorkspace();
+            workspace.getNamespaceRegistry().registerNamespace( "archiva", "http://archiva.apache.org/jcr" );
+
+            NodeTypeManager nodeTypeManager = workspace.getNodeTypeManager();
+            NodeTypeTemplate nodeType = nodeTypeManager.createNodeTypeTemplate();
+            nodeType.setMixin( true );
+            nodeType.setName( "archiva:artifact" );
+            nodeTypeManager.registerNodeType( nodeType, false );
         }
         catch ( LoginException e )
         {
@@ -111,9 +126,7 @@ public class JcrMetadataRepository
 
     public void updateProject( String repositoryId, ProjectMetadata project )
     {
-        String namespace = project.getNamespace();
-        String projectId = project.getId();
-        updateProject( repositoryId, namespace, projectId );
+        updateProject( repositoryId, project.getNamespace(), project.getId() );
     }
 
     private void updateProject( String repositoryId, String namespace, String projectId )
@@ -122,8 +135,7 @@ public class JcrMetadataRepository
 
         try
         {
-            Node namespaceNode = getOrCreateNamespaceNode( repositoryId, namespace );
-            getOrCreateNode( namespaceNode, projectId );
+            getOrAddProjectNode( repositoryId, namespace, projectId );
         }
         catch ( RepositoryException e )
         {
@@ -135,14 +147,16 @@ public class JcrMetadataRepository
     public void updateArtifact( String repositoryId, String namespace, String projectId, String projectVersion,
                                 ArtifactMetadata artifactMeta )
     {
+        updateNamespace( repositoryId, namespace );
+
         try
         {
-            Node node = getOrCreateArtifactNode( repositoryId, namespace, projectId, projectVersion,
-                                                 artifactMeta.getId() );
+            Node node = getOrAddArtifactNode( repositoryId, namespace, projectId, projectVersion,
+                                              artifactMeta.getId() );
 
             Calendar cal = Calendar.getInstance();
             cal.setTime( artifactMeta.getFileLastModified() );
-            node.setProperty( "updated", cal );
+            node.setProperty( "jcr:lastModified", cal );
 
             cal = Calendar.getInstance();
             cal.setTime( artifactMeta.getWhenGathered() );
@@ -155,17 +169,18 @@ public class JcrMetadataRepository
             node.setProperty( "version", artifactMeta.getVersion() );
 
             // TODO: namespaced properties instead?
-            Node facetNode = getOrCreateNode( node, "facets" );
+            Node facetNode = JcrUtils.getOrAddNode( node, "facets" );
             for ( MetadataFacet facet : artifactMeta.getFacetList() )
             {
                 // TODO: need to clear it?
-                Node n = getOrCreateNode( facetNode, facet.getFacetId() );
+                Node n = JcrUtils.getOrAddNode( facetNode, facet.getFacetId() );
 
                 for ( Map.Entry<String, String> entry : facet.toProperties().entrySet() )
                 {
                     n.setProperty( entry.getKey(), entry.getValue() );
                 }
             }
+            session.save();
         }
         catch ( RepositoryException e )
         {
@@ -174,14 +189,6 @@ public class JcrMetadataRepository
         }
     }
 
-    private Node getOrCreateArtifactNode( String repositoryId, String namespace, String projectId,
-                                          String projectVersion, String id )
-        throws RepositoryException
-    {
-        Node versionNode = getOrCreateProjectVersionNode( repositoryId, namespace, projectId, projectVersion );
-        return getOrCreateNode( versionNode, id );
-    }
-
     public void updateProjectVersion( String repositoryId, String namespace, String projectId,
                                       ProjectVersionMetadata versionMetadata )
     {
@@ -189,8 +196,8 @@ public class JcrMetadataRepository
 
         try
         {
-            Node versionNode = getOrCreateProjectVersionNode( repositoryId, namespace, projectId,
-                                                              versionMetadata.getId() );
+            Node versionNode = getOrAddProjectVersionNode( repositoryId, namespace, projectId,
+                                                           versionMetadata.getId() );
 
             versionNode.setProperty( "name", versionMetadata.getName() );
             versionNode.setProperty( "description", versionMetadata.getDescription() );
@@ -252,7 +259,7 @@ public class JcrMetadataRepository
             }
 
             // TODO: namespaced properties instead?
-            Node facetNode = getOrCreateNode( versionNode, "facets" );
+            Node facetNode = JcrUtils.getOrAddNode( versionNode, "facets" );
             for ( MetadataFacet facet : versionMetadata.getFacetList() )
             {
                 // TODO: shouldn't need to recreate, just update
@@ -261,7 +268,7 @@ public class JcrMetadataRepository
                     facetNode.getNode( facet.getFacetId() ).remove();
                 }
                 Node n = facetNode.addNode( facet.getFacetId() );
-                
+
                 for ( Map.Entry<String, String> entry : facet.toProperties().entrySet() )
                 {
                     n.setProperty( entry.getKey(), entry.getValue() );
@@ -275,44 +282,6 @@ public class JcrMetadataRepository
         }
     }
 
-    private Node getOrCreateProjectVersionNode( String repositoryId, String namespace, String projectId,
-                                                String projectVersion )
-        throws RepositoryException
-    {
-        Node namespaceNode = getOrCreateNamespaceNode( repositoryId, namespace );
-        Node projectNode = getOrCreateNode( namespaceNode, projectId );
-        return getOrCreateNode( projectNode, projectVersion );
-    }
-
-    private Node getOrCreateNode( Node baseNode, String name )
-        throws RepositoryException
-    {
-        return baseNode.hasNode( name ) ? baseNode.getNode( name ) : baseNode.addNode( name );
-    }
-
-    private Node getOrCreateNamespaceNode( String repositoryId, String namespace )
-        throws RepositoryException
-    {
-        Node repo = getOrCreateRepositoryContentNode( repositoryId );
-        return getOrCreateNode( repo, namespace );
-    }
-
-    private Node getOrCreateRepositoryContentNode( String repositoryId )
-        throws RepositoryException
-    {
-        Node node = getOrCreateRepositoryNode( repositoryId );
-        return getOrCreateNode( node, "content" );
-    }
-
-    private Node getOrCreateRepositoryNode( String repositoryId )
-        throws RepositoryException
-    {
-        Node root = session.getRootNode();
-        Node node = getOrCreateNode( root, "repositories" );
-        node = getOrCreateNode( node, repositoryId );
-        return node;
-    }
-
     public void updateProjectReference( String repositoryId, String namespace, String projectId, String projectVersion,
                                         ProjectVersionReference reference )
     {
@@ -320,14 +289,14 @@ public class JcrMetadataRepository
         // TODO: is this tree the right way up? It differs from the content model
         try
         {
-            Node node = getOrCreateRepositoryContentNode( repositoryId );
-            node = getOrCreateNode( node, namespace );
-            node = getOrCreateNode( node, projectId );
-            node = getOrCreateNode( node, projectVersion );
-            node = getOrCreateNode( node, "references" );
-            node = getOrCreateNode( node, reference.getNamespace() );
-            node = getOrCreateNode( node, reference.getProjectId() );
-            node = getOrCreateNode( node, reference.getProjectVersion() );
+            Node node = getOrAddRepositoryContentNode( repositoryId );
+            node = JcrUtils.getOrAddNode( node, namespace );
+            node = JcrUtils.getOrAddNode( node, projectId );
+            node = JcrUtils.getOrAddNode( node, projectVersion );
+            node = JcrUtils.getOrAddNode( node, "references" );
+            node = JcrUtils.getOrAddNode( node, reference.getNamespace() );
+            node = JcrUtils.getOrAddNode( node, reference.getProjectId() );
+            node = JcrUtils.getOrAddNode( node, reference.getProjectVersion() );
             node.setProperty( "type", reference.getReferenceType().toString() );
         }
         catch ( RepositoryException e )
@@ -341,7 +310,8 @@ public class JcrMetadataRepository
     {
         try
         {
-            Node node = getOrCreateNamespaceNode( repositoryId, namespace );
+            // TODO: currently flat
+            Node node = getOrAddNamespaceNode( repositoryId, namespace );
             node.setProperty( "namespace", namespace );
         }
         catch ( RepositoryException e )
@@ -357,16 +327,17 @@ public class JcrMetadataRepository
 
         try
         {
-            Node root = session.getRootNode();
-            Node node = root.getNode( "repositories/" + repositoryId + "/facets/" + facetId );
+            // no need to construct node-by-node here, as we'll find in the next instance, the facet names have / and
+            // are paths themselves
+            Node node = session.getRootNode().getNode( getFacetPath( repositoryId, facetId ) );
 
-            // TODO: could we simply query all nodes with no children?
+            // TODO: could we simply query all nodes with no children? Or perhaps a specific nodetype?
+            //   Might be better to review the purpose of this function - why is the list of paths helpful?
             recurse( facets, "", node );
         }
         catch ( PathNotFoundException e )
         {
-            // TODO: handle this case differently?
-            // currently ignored
+            // ignored - the facet doesn't exist, so return the empty list
         }
         catch ( RepositoryException e )
         {
@@ -379,10 +350,8 @@ public class JcrMetadataRepository
     private void recurse( List<String> facets, String prefix, Node node )
         throws RepositoryException
     {
-        NodeIterator iterator = node.getNodes();
-        while ( iterator.hasNext() )
+        for ( Node n : JcrUtils.getChildNodes( node ) )
         {
-            Node n = iterator.nextNode();
             String name = prefix + "/" + n.getName();
             if ( n.hasNodes() )
             {
@@ -396,24 +365,21 @@ public class JcrMetadataRepository
         }
     }
 
-
     public MetadataFacet getMetadataFacet( String repositoryId, String facetId, String name )
     {
         MetadataFacet metadataFacet = null;
         try
         {
             Node root = session.getRootNode();
-            Node node = root.getNode( "repositories/" + repositoryId + "/facets/" + facetId + "/" + name );
+            Node node = root.getNode( getFacetPath( repositoryId, facetId, name ) );
 
             MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( facetId );
             if ( metadataFacetFactory != null )
             {
                 metadataFacet = metadataFacetFactory.createMetadataFacet( repositoryId, name );
                 Map<String, String> map = new HashMap<String, String>();
-                PropertyIterator iterator = node.getProperties();
-                while ( iterator.hasNext() )
+                for ( Property property : JcrUtils.getProperties( node ) )
                 {
-                    Property property = iterator.nextProperty();
                     String p = property.getName();
                     if ( !p.startsWith( "jcr:" ) )
                     {
@@ -425,8 +391,7 @@ public class JcrMetadataRepository
         }
         catch ( PathNotFoundException e )
         {
-            // TODO: handle this case differently?
-            // currently ignored
+            // ignored - the facet doesn't exist, so return null
         }
         catch ( RepositoryException e )
         {
@@ -440,11 +405,11 @@ public class JcrMetadataRepository
     {
         try
         {
-            Node repo = getOrCreateRepositoryNode( repositoryId );
-            Node facets = getOrCreateNode( repo, "facets" );
+            Node repo = getOrAddRepositoryNode( repositoryId );
+            Node facets = JcrUtils.getOrAddNode( repo, "facets" );
 
             String id = metadataFacet.getFacetId();
-            Node facetNode = getOrCreateNode( facets, id );
+            Node facetNode = JcrUtils.getOrAddNode( facets, id );
 
             Node node = getOrCreatePath( facetNode, metadataFacet.getName() );
 
@@ -466,7 +431,7 @@ public class JcrMetadataRepository
         Node node = baseNode;
         for ( String n : name.split( "/" ) )
         {
-            node = getOrCreateNode( node, n );
+            node = JcrUtils.getOrAddNode( node, n );
         }
         return node;
     }
@@ -476,7 +441,7 @@ public class JcrMetadataRepository
         try
         {
             Node root = session.getRootNode();
-            String path = "repositories/" + repositoryId + "/facets/" + facetId;
+            String path = getFacetPath( repositoryId, facetId );
             // TODO: exception if missing?
             if ( root.hasNode( path ) )
             {
@@ -495,7 +460,7 @@ public class JcrMetadataRepository
         try
         {
             Node root = session.getRootNode();
-            String path = "repositories/" + repositoryId + "/facets/" + facetId + "/" + name;
+            String path = getFacetPath( repositoryId, facetId, name );
             // TODO: exception if missing?
             if ( root.hasNode( path ) )
             {
@@ -518,42 +483,47 @@ public class JcrMetadataRepository
 
     public List<ArtifactMetadata> getArtifactsByDateRange( String repoId, Date startTime, Date endTime )
     {
-        // TODO: this is quite slow - if we are to persist with this repository implementation we should build an index
-        //  of this information (eg. in Lucene, as before)
+        List<ArtifactMetadata> artifacts;
 
-        List<ArtifactMetadata> artifacts = new ArrayList<ArtifactMetadata>();
-        for ( String ns : getRootNamespaces( repoId ) )
+        String q = "SELECT * FROM [archiva:artifact]";
+
+        String clause = " WHERE";
+        if ( startTime != null )
         {
-            getArtifactsByDateRange( artifacts, repoId, ns, startTime, endTime );
+            q += clause + " [whenGathered] >= $start";
+            clause = " AND";
         }
-        Collections.sort( artifacts, new ArtifactComparator() );
-        return artifacts;
-    }
-
-    private void getArtifactsByDateRange( List<ArtifactMetadata> artifacts, String repoId, String ns, Date startTime,
-                                          Date endTime )
-    {
-        for ( String namespace : getNamespaces( repoId, ns ) )
+        if ( endTime != null )
         {
-            getArtifactsByDateRange( artifacts, repoId, ns + "." + namespace, startTime, endTime );
+            q += clause + " [whenGathered] <= $end";
         }
 
-        for ( String project : getProjects( repoId, ns ) )
+        try
         {
-            for ( String version : getProjectVersions( repoId, ns, project ) )
+            Query query = session.getWorkspace().getQueryManager().createQuery( q, Query.JCR_SQL2 );
+            ValueFactory valueFactory = session.getValueFactory();
+            if ( startTime != null )
             {
-                for ( ArtifactMetadata artifact : getArtifacts( repoId, ns, project, version ) )
-                {
-                    if ( startTime == null || startTime.before( artifact.getWhenGathered() ) )
-                    {
-                        if ( endTime == null || endTime.after( artifact.getWhenGathered() ) )
-                        {
-                            artifacts.add( artifact );
-                        }
-                    }
-                }
+                query.bindValue( "start", valueFactory.createValue( createCalendar( startTime ) ) );
+            }
+            if ( endTime != null )
+            {
+                query.bindValue( "end", valueFactory.createValue( createCalendar( endTime ) ) );
+            }
+            QueryResult result = query.execute();
+
+            artifacts = new ArrayList<ArtifactMetadata>();
+            for ( Node n : JcrUtils.getNodes( result ) )
+            {
+                artifacts.add( getArtifactFromNode( repoId, n ) );
             }
         }
+        catch ( RepositoryException e )
+        {
+            // TODO
+            throw new RuntimeException( e );
+        }
+        return artifacts;
     }
 
     public Collection<String> getRepositories()
@@ -1100,83 +1070,95 @@ public class JcrMetadataRepository
                 {
                     Node artifactNode = iterator.nextNode();
 
-                    String id = artifactNode.getName();
+                    ArtifactMetadata artifact = getArtifactFromNode( repositoryId, artifactNode );
+                    artifacts.add( artifact );
+                }
+            }
+        }
+        catch ( RepositoryException e )
+        {
+            // TODO
+            throw new RuntimeException( e );
+        }
 
-                    ArtifactMetadata artifact = new ArtifactMetadata();
-                    artifact.setId( id );
-                    artifact.setRepositoryId( repositoryId );
-                    artifact.setNamespace( namespace );
-                    artifact.setProject( projectId );
-                    artifact.setProjectVersion( projectVersion );
-                    artifact.setVersion( artifactNode.hasProperty( "version" ) ? artifactNode.getProperty(
-                        "version" ).getString() : projectVersion );
+        return artifacts;
+    }
 
-                    if ( artifactNode.hasProperty( "updated" ) )
-                    {
-                        artifact.setFileLastModified( artifactNode.getProperty(
-                            "updated" ).getDate().getTimeInMillis() );
-                    }
+    private ArtifactMetadata getArtifactFromNode( String repositoryId, Node artifactNode )
+        throws RepositoryException
+    {
+        String id = artifactNode.getName();
 
-                    if ( artifactNode.hasProperty( "whenGathered" ) )
-                    {
-                        artifact.setWhenGathered( artifactNode.getProperty( "whenGathered" ).getDate().getTime() );
-                    }
+        ArtifactMetadata artifact = new ArtifactMetadata();
+        artifact.setId( id );
+        artifact.setRepositoryId( repositoryId );
 
-                    if ( artifactNode.hasProperty( "size" ) )
-                    {
-                        artifact.setSize( artifactNode.getProperty( "size" ).getLong() );
-                    }
+        Node projectVersionNode = artifactNode.getParent();
+        Node projectNode = projectVersionNode.getParent();
+        Node namespaceNode = projectNode.getParent();
 
-                    if ( artifactNode.hasProperty( "md5" ) )
-                    {
-                        artifact.setMd5( artifactNode.getProperty( "md5" ).getString() );
-                    }
+        artifact.setNamespace( namespaceNode.getProperty( "namespace" ).getString() );
+        artifact.setProject( projectNode.getName() );
+        artifact.setProjectVersion( projectVersionNode.getName() );
+        artifact.setVersion( artifactNode.hasProperty( "version" )
+                                 ? artifactNode.getProperty( "version" ).getString()
+                                 : projectVersionNode.getName() );
 
-                    if ( artifactNode.hasProperty( "sha1" ) )
-                    {
-                        artifact.setSha1( artifactNode.getProperty( "sha1" ).getString() );
-                    }
+        if ( artifactNode.hasProperty( "jcr:lastModified" ) )
+        {
+            artifact.setFileLastModified( artifactNode.getProperty( "jcr:lastModified" ).getDate().getTimeInMillis() );
+        }
 
-                    if ( artifactNode.hasNode( "facets" ) )
-                    {
-                        NodeIterator j = artifactNode.getNode( "facets" ).getNodes();
+        if ( artifactNode.hasProperty( "whenGathered" ) )
+        {
+            artifact.setWhenGathered( artifactNode.getProperty( "whenGathered" ).getDate().getTime() );
+        }
 
-                        while ( j.hasNext() )
-                        {
-                            Node facetNode = j.nextNode();
+        if ( artifactNode.hasProperty( "size" ) )
+        {
+            artifact.setSize( artifactNode.getProperty( "size" ).getLong() );
+        }
 
-                            MetadataFacetFactory factory = metadataFacetFactories.get( facetNode.getName() );
-                            if ( factory == null )
-                            {
-                                log.error( "Attempted to load unknown project version metadata facet: " + facetNode.getName() );
-                            }
-                            else
-                            {
-                                MetadataFacet facet = factory.createMetadataFacet();
-                                Map<String, String> map = new HashMap<String, String>();
-                                PropertyIterator i = facetNode.getProperties();
-                                while ( i.hasNext() )
-                                {
-                                    Property p = i.nextProperty();
-                                    String property = p.getName();
-                                    map.put( property, p.getString() );
-                                }
-                                facet.fromProperties( map );
-                                artifact.addFacet( facet );
-                            }
-                        }
-                    }
-                    artifacts.add( artifact );
-                }
-            }
+        if ( artifactNode.hasProperty( "md5" ) )
+        {
+            artifact.setMd5( artifactNode.getProperty( "md5" ).getString() );
         }
-        catch ( RepositoryException e )
+
+        if ( artifactNode.hasProperty( "sha1" ) )
         {
-            // TODO
-            throw new RuntimeException( e );
+            artifact.setSha1( artifactNode.getProperty( "sha1" ).getString() );
         }
 
-        return artifacts;
+        if ( artifactNode.hasNode( "facets" ) )
+        {
+            NodeIterator j = artifactNode.getNode( "facets" ).getNodes();
+
+            while ( j.hasNext() )
+            {
+                Node facetNode = j.nextNode();
+
+                MetadataFacetFactory factory = metadataFacetFactories.get( facetNode.getName() );
+                if ( factory == null )
+                {
+                    log.error( "Attempted to load unknown project version metadata facet: " + facetNode.getName() );
+                }
+                else
+                {
+                    MetadataFacet facet = factory.createMetadataFacet();
+                    Map<String, String> map = new HashMap<String, String>();
+                    PropertyIterator i = facetNode.getProperties();
+                    while ( i.hasNext() )
+                    {
+                        Property p = i.nextProperty();
+                        String property = p.getName();
+                        map.put( property, p.getString() );
+                    }
+                    facet.fromProperties( map );
+                    artifact.addFacet( facet );
+                }
+            }
+        }
+        return artifact;
     }
 
     void close()
@@ -1207,25 +1189,69 @@ public class JcrMetadataRepository
 //        }
     }
 
-    private static class ArtifactComparator
-        implements Comparator<ArtifactMetadata>
+    private static String getFacetPath( String repositoryId, String facetId )
     {
-        public int compare( ArtifactMetadata artifact1, ArtifactMetadata artifact2 )
-        {
-            if ( artifact1.getWhenGathered() == artifact2.getWhenGathered() )
-            {
-                return 0;
-            }
-            if ( artifact1.getWhenGathered() == null )
-            {
-                return 1;
-            }
-            if ( artifact2.getWhenGathered() == null )
-            {
-                return -1;
-            }
-            return artifact1.getWhenGathered().compareTo( artifact2.getWhenGathered() );
-        }
+        return "repositories/" + repositoryId + "/facets/" + facetId;
+    }
+
+    private static String getFacetPath( String repositoryId, String facetId, String name )
+    {
+        return getFacetPath( repositoryId, facetId ) + "/" + name;
+    }
+
+    private Node getOrAddRepositoryNode( String repositoryId )
+        throws RepositoryException
+    {
+        Node root = session.getRootNode();
+        Node node = JcrUtils.getOrAddNode( root, "repositories" );
+        node = JcrUtils.getOrAddNode( node, repositoryId );
+        return node;
+    }
+
+    private Node getOrAddRepositoryContentNode( String repositoryId )
+        throws RepositoryException
+    {
+        Node node = getOrAddRepositoryNode( repositoryId );
+        return JcrUtils.getOrAddNode( node, "content" );
+    }
+
+    private Node getOrAddNamespaceNode( String repositoryId, String namespace )
+        throws RepositoryException
+    {
+        Node repo = getOrAddRepositoryContentNode( repositoryId );
+        return JcrUtils.getOrAddNode( repo, namespace );
+    }
+
+    private Node getOrAddProjectNode( String repositoryId, String namespace, String projectId )
+        throws RepositoryException
+    {
+        Node namespaceNode = getOrAddNamespaceNode( repositoryId, namespace );
+        return JcrUtils.getOrAddNode( namespaceNode, projectId );
+    }
+
+    private Node getOrAddProjectVersionNode( String repositoryId, String namespace, String projectId,
+                                             String projectVersion )
+        throws RepositoryException
+    {
+        Node projectNode = getOrAddProjectNode( repositoryId, namespace, projectId );
+        return JcrUtils.getOrAddNode( projectNode, projectVersion );
+    }
+
+    private Node getOrAddArtifactNode( String repositoryId, String namespace, String projectId, String projectVersion,
+                                       String id )
+        throws RepositoryException
+    {
+        Node versionNode = getOrAddProjectVersionNode( repositoryId, namespace, projectId, projectVersion );
+        Node node = JcrUtils.getOrAddNode( versionNode, id );
+        node.addMixin( "archiva:artifact" );
+        return node;
+    }
+
+    private static Calendar createCalendar( Date time )
+    {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime( time );
+        return cal;
     }
 
     private String join( Collection<String> ids )
@@ -1242,4 +1268,9 @@ public class JcrMetadataRepository
         }
         return null;
     }
+
+    public Session getJcrSession()
+    {
+        return session;
+    }
 }

Modified: archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/test/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepositoryTest.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/test/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepositoryTest.java?rev=1051396&r1=1051395&r2=1051396&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/test/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepositoryTest.java (original)
+++ archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/test/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepositoryTest.java Tue Dec 21 07:21:44 2010
@@ -23,8 +23,8 @@ import org.apache.archiva.metadata.model
 import org.apache.archiva.metadata.repository.AbstractMetadataRepositoryTest;
 import org.apache.commons.io.FileUtils;
 
-import java.io.File;
 import java.util.Map;
+import javax.jcr.RepositoryException;
 
 public class JcrMetadataRepositoryTest
     extends AbstractMetadataRepositoryTest
@@ -36,8 +36,7 @@ public class JcrMetadataRepositoryTest
     {
         super.setUp();
 
-        File directory = getTestFile( "target/test-repositories" );
-        FileUtils.deleteDirectory( directory );
+        FileUtils.deleteDirectory( getTestFile( "target/test-repositories" ) );
 
         Map<String, MetadataFacetFactory> factories = createTestMetadataFacetFactories();
 
@@ -53,6 +52,15 @@ public class JcrMetadataRepositoryTest
     {
         super.tearDown();
 
+        try
+        {
+            jcrMetadataRepository.getJcrSession().getRootNode().getNode( "repositories" ).remove();
+        }
+        catch ( RepositoryException e )
+        {
+            // ignore
+        }
+
         jcrMetadataRepository.close();
     }
 }

Modified: archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/test/repository.xml
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/test/repository.xml?rev=1051396&r1=1051395&r2=1051396&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/test/repository.xml (original)
+++ archiva/trunk/archiva-modules/plugins/metadata-store-jcr/src/test/repository.xml Tue Dec 21 07:21:44 2010
@@ -22,9 +22,9 @@
 
 <Repository>
   <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem"/>
-<!--<FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
-            <param name="path" value="${rep.home}/repository"/>
-        </FileSystem>  -->
+  <!--<FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+    <param name="path" value="${rep.home}/repository"/>
+</FileSystem>  -->
   <Security appName="Jackrabbit">
     <SecurityManager class="org.apache.jackrabbit.core.security.simple.SimpleSecurityManager" workspaceName="security"/>
     <AccessManager class="org.apache.jackrabbit.core.security.simple.SimpleAccessManager"/>
@@ -32,18 +32,22 @@
   </Security>
   <Workspaces rootPath="${rep.home}/workspaces" defaultWorkspace="default"/>
   <Workspace name="${wsp.name}">
-    <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem"/>
-    <PersistenceManager class="org.apache.jackrabbit.core.persistence.mem.InMemPersistenceManager"/>
-<!--<FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
-            <param name="path" value="${wsp.home}"/>
-        </FileSystem>    <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager"/> -->
+    <!--<FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem"/>-->
+    <!--<PersistenceManager class="org.apache.jackrabbit.core.persistence.mem.InMemPersistenceManager"/>-->
+    <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+      <param name="path" value="${wsp.home}"/>
+    </FileSystem>
+    <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager"/>
+    <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+      <param name="path" value="${wsp.home}/index"/>
+    </SearchIndex>
   </Workspace>
   <Versioning rootPath="${rep.home}/version">
     <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem"/>
     <PersistenceManager class="org.apache.jackrabbit.core.persistence.mem.InMemPersistenceManager"/>
-<!--<FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
-            <param name="path" value="${rep.home}/version"/>
-        </FileSystem>
-    <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager"/>-->
+    <!--<FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+           <param name="path" value="${rep.home}/version"/>
+       </FileSystem>
+   <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager"/>-->
   </Versioning>
 </Repository>