]> source.dussan.org Git - archiva.git/commitdiff
[MRM-425 and MRM-426]
authorMaria Odea B. Ching <oching@apache.org>
Mon, 23 Jul 2007 16:48:30 +0000 (16:48 +0000)
committerMaria Odea B. Ching <oching@apache.org>
Mon, 23 Jul 2007 16:48:30 +0000 (16:48 +0000)
- Added and modified code for handling snapshots (if the versions of a specific artifact snapshot are only timestamped versions, add a
generic snapshot which is pointing to the latest timestamp version) in DefaultRepositoryBrowsing and ProjectModelToDatabaseConsumer.
- Updated pom validations in ProjectModelToDatabaseConsumer - handling of timestamped versions were considered
- Added isUniqueSnapshot(..) and isGenericSnapshot(..) in VersionUtil
- Added new attribute 'modelVersion' in DependencyTreeTag to get the in-pom version. Did not use the version attribute so as to retain the
actual version being browsed. Also updated DependencyTree
- Updated the ff. pages for the version to be displayed: artifactInfo.jspf, showArtifact.jsp, dependencyTree.jsp and artifactDecorator.jsp
- Updated the version in SearchResultHit

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

archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/VersionUtil.java
archiva-base/archiva-consumers/archiva-database-consumers/src/main/java/org/apache/maven/archiva/consumers/database/ProjectModelToDatabaseConsumer.java
archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/SearchResultHit.java
archiva-database/src/main/java/org/apache/maven/archiva/database/browsing/DefaultRepositoryBrowsing.java
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/DependencyTree.java
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/DependencyTreeTag.java
archiva-web/archiva-webapp/src/main/resources/META-INF/taglib.tld
archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/artifact/dependencyTree.jsp
archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/decorators/artifactDecorator.jsp
archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/include/artifactInfo.jspf
archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/showArtifact.jsp

index 228c3ff0f7d41b46fc63f402ac5c34132cc14ac1..69626f634b4428be73997933755c506f3b46ff57 100644 (file)
@@ -151,4 +151,20 @@ public class VersionUtil
             return version;
         }
     }
+
+    public static boolean isUniqueSnapshot( String version )
+    {             
+        Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( version );
+        if( m.matches() )
+        {
+            return true;
+        }
+
+        return false;
+    }
+
+    public static boolean isGenericSnapshot( String version )
+    {
+        return version.endsWith( SNAPSHOT );    
+    }
 }
index 3104dc40a6fecd2a253b19f6c877911799a2d809..e586ac3d529edcff64144eb15a8a8b44e877e3f4 100644 (file)
@@ -42,20 +42,20 @@ import org.apache.maven.archiva.repository.project.ProjectModelException;
 import org.apache.maven.archiva.repository.project.ProjectModelFilter;
 import org.apache.maven.archiva.repository.project.ProjectModelReader;
 import org.apache.maven.archiva.repository.project.filters.EffectiveProjectModelFilter;
+import org.apache.maven.archiva.common.utils.VersionUtil;
 
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 
 /**
- * ProjectModelToDatabaseConsumer 
+ * ProjectModelToDatabaseConsumer
  *
  * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
  * @version $Id$
- * 
  * @plexus.component role="org.apache.maven.archiva.consumers.DatabaseUnprocessedArtifactConsumer"
- *                   role-hint="update-db-project"
- *                   instantiation-strategy="per-lookup"
+ * role-hint="update-db-project"
+ * instantiation-strategy="per-lookup"
  */
 public class ProjectModelToDatabaseConsumer
     extends AbstractMonitoredConsumer
@@ -102,9 +102,8 @@ public class ProjectModelToDatabaseConsumer
     private ProjectModelFilter expressionModelFilter;
 
     /**
-     * @plexus.requirement 
-     *          role="org.apache.maven.archiva.repository.project.ProjectModelFilter"
-     *          role-hint="effective"
+     * @plexus.requirement role="org.apache.maven.archiva.repository.project.ProjectModelFilter"
+     * role-hint="effective"
      */
     private EffectiveProjectModelFilter effectiveModelFilter;
 
@@ -167,13 +166,24 @@ public class ProjectModelToDatabaseConsumer
             // Resolve the project model
             model = effectiveModelFilter.filter( model );
 
+            // The version should be updated to the filename version if it is a unique snapshot
+            FilenameParts parts = RepositoryLayoutUtils.splitFilename( artifactFile.getName(), null );
+            if ( model.getVersion().equals( VersionUtil.getBaseVersion( parts.version ) ) &&
+                VersionUtil.isUniqueSnapshot( parts.version ) )
+            {
+                model.setVersion( parts.version );
+            }
+
             if ( isValidModel( model, artifact ) )
             {
+                getLogger().info( "Add project model " + model + " to database." );
+
                 dao.getProjectModelDAO().saveProjectModel( model );
             }
             else
             {
-                getLogger().warn( "Invalid or corrupt pom. Project model " + model + " was not added in the database." );
+                getLogger().warn(
+                    "Invalid or corrupt pom. Project model " + model + " was not added in the database." );
             }
 
         }
@@ -191,9 +201,8 @@ public class ProjectModelToDatabaseConsumer
         catch ( Throwable t )
         {
             // Catch the other errors in the process to allow the rest of the process to complete.
-            getLogger().error(
-                               "Unable to process model " + artifactFile + " due to : " + t.getClass().getName()
-                                   + " : " + t.getMessage(), t );
+            getLogger().error( "Unable to process model " + artifactFile + " due to : " + t.getClass().getName() +
+                " : " + t.getMessage(), t );
         }
     }
 
@@ -279,51 +288,26 @@ public class ProjectModelToDatabaseConsumer
         try
         {
             FilenameParts parts = RepositoryLayoutUtils.splitFilename( artifactFile.getName(), null );
-            if ( !parts.artifactId.equalsIgnoreCase( model.getArtifactId() ) )
-            {
-                getLogger().warn(
-                                  "Project Model " + model + " artifactId: " + model.getArtifactId()
-                                        + " does not match the pom file's artifactId: " + parts.artifactId );
 
-                addProblem( artifact, "Project Model " + model + " artifactId: " + model.getArtifactId()
-                    + " does not match the pom file's artifactId: " + parts.artifactId );
-
-                return false;
-            }
-
-            if ( !parts.version.equalsIgnoreCase( model.getVersion() ) )
+            if ( !parts.artifactId.equalsIgnoreCase( model.getArtifactId() ) )
             {
-                getLogger().warn(
-                                  "Project Model " + model + " version: " + model.getVersion()
-                                        + " does not match the pom file's version: " + parts.version );
+                getLogger().warn( "Project Model " + model + " artifactId: " + model.getArtifactId() +
+                    " does not match the pom file's artifactId: " + parts.artifactId );
 
-                addProblem( artifact, "Project Model " + model + " version: " + model.getVersion()
-                    + " does not match the pom file's version: " + parts.version );
+                addProblem( artifact, "Project Model " + model + " artifactId: " + model.getArtifactId() +
+                    " does not match the pom file's artifactId: " + parts.artifactId );
 
                 return false;
             }
 
-            String constructedFilename;
-
-            if( parts.classifier != null )
+            if ( !parts.version.equalsIgnoreCase( model.getVersion() ) &&
+                !VersionUtil.getBaseVersion( parts.version ).equalsIgnoreCase( model.getVersion() ) )
             {
-                constructedFilename = model.getArtifactId() + "-" + model.getVersion() + "-" +
-                    parts.classifier.trim() + ".pom";
-            }
-            else
-            {
-                constructedFilename = model.getArtifactId() + "-" + model.getVersion() + ".pom";
-            }                           
+                getLogger().warn( "Project Model " + model + " version: " + model.getVersion() +
+                    " does not match the pom file's version: " + parts.version );
 
-            //check if the file name matches the values indicated in the pom
-            if ( !artifactFile.getName().equalsIgnoreCase( constructedFilename ) )
-            {
-                getLogger().warn(
-                                  "Artifact " + artifact + " does not match the artifactId and/or version "
-                                      + "specified in the project model " + model );
-
-                addProblem( artifact, "Artifact " + artifact + " does not match the artifactId and/or version "
-                    + "specified in the project model " + model );
+                addProblem( artifact, "Project Model " + model + " version: " + model.getVersion() +
+                    " does not match the pom file's version: " + parts.version );
 
                 return false;
             }
@@ -361,4 +345,5 @@ public class ProjectModelToDatabaseConsumer
             throw new ConsumerException( emsg, e );
         }
     }
+
 }
index 002d02249da49eed6b4e22b30937abbafeb65f8a..8b207fde888f6d350d2101deeb36d2179f708a69 100644 (file)
@@ -90,8 +90,8 @@ public class SearchResultHit
     public void addArtifact( ArchivaArtifact artifact )
     {
         this.artifacts.add( artifact );
-
-        String ver = artifact.getBaseVersion();
+                
+        String ver = artifact.getVersion();        
 
         if ( !this.versions.contains( ver ) )
         {
@@ -110,7 +110,7 @@ public class SearchResultHit
 
         if ( StringUtils.isBlank( this.version ) )
         {
-            this.version = ver;
+            this.version = ver;            
         }
     }
 
index f99e26ac72093a7a71ebf58d8158eb132aefdf9c..6234952b8a80c4ce9323e4ca5007305232edaf9f 100644 (file)
@@ -32,17 +32,20 @@ import org.apache.maven.archiva.database.constraints.UniqueVersionConstraint;
 import org.apache.maven.archiva.database.updater.DatabaseUpdater;
 import org.apache.maven.archiva.model.ArchivaArtifact;
 import org.apache.maven.archiva.model.ArchivaProjectModel;
+import org.apache.maven.archiva.common.utils.VersionUtil;
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
 
 /**
- * DefaultRepositoryBrowsing 
+ * DefaultRepositoryBrowsing
  *
  * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
  * @version $Id$
- * 
  * @plexus.component role="org.apache.maven.archiva.database.browsing.RepositoryBrowsing"
  */
 public class DefaultRepositoryBrowsing
@@ -77,6 +80,8 @@ public class DefaultRepositoryBrowsing
 
         BrowsingResults results = new BrowsingResults( groupId, artifactId );
 
+        processSnapshots( versions );
+
         results.setVersions( versions );
 
         return results;
@@ -101,45 +106,168 @@ public class DefaultRepositoryBrowsing
 
     public ArchivaProjectModel selectVersion( String groupId, String artifactId, String version )
         throws ObjectNotFoundException, ArchivaDatabaseException
+    {
+        ArchivaArtifact pomArtifact = getArtifact( groupId, artifactId, version );
+
+        ArchivaProjectModel model;
+        version = pomArtifact.getVersion();
+
+        if ( !pomArtifact.getModel().isProcessed() )
+        {
+            // Process it.
+            dbUpdater.updateUnprocessed( pomArtifact );
+        }
+
+        model = getProjectModel( groupId, artifactId, version );
+
+        return model;
+    }
+
+    private ArchivaArtifact getArtifact( String groupId, String artifactId, String version )
+        throws ObjectNotFoundException, ArchivaDatabaseException
     {
         ArchivaArtifact pomArtifact = null;
 
         try
         {
             pomArtifact = dao.getArtifactDAO().getArtifact( groupId, artifactId, version, null, "pom" );
+        }
+        catch ( ObjectNotFoundException e )
+        {
+            pomArtifact = handleGenericSnapshots( groupId, artifactId, version, pomArtifact );
+        }
+
+        if ( pomArtifact == null )
+        {
+            throw new ObjectNotFoundException(
+                "Unable to find artifact [" + groupId + ":" + artifactId + ":" + version + "]" );
+        }
+        return pomArtifact;
+    }
+
+    public List getUsedBy( String groupId, String artifactId, String version )
+        throws ArchivaDatabaseException
+    {
+        ProjectsByArtifactUsageConstraint constraint =
+            new ProjectsByArtifactUsageConstraint( groupId, artifactId, version );
+        List results = dao.getProjectModelDAO().queryProjectModels( constraint );
+        if ( results == null )
+        {
+            // defensive. to honor contract as specified. never null.
+            return Collections.EMPTY_LIST;
+        }
+
+        return results;
+    }
+
+    /**
+     * Add generic (*-SNAPSHOT) snapshot versions in the list for artifacts with only unique version (timestamped)
+     * snapshots.
+     * <p/>
+     * Ex.
+     * artifact1 has the ff. versions retrieved from the db:
+     * - 1.0
+     * - 1.1-20061118.060401-2
+     * - 1.1-20061118.060402-3
+     * - 2.2-20071007.070101-1
+     * - 2.2-20071007.070110-2
+     * - 2.2-SNAPSHOT
+     * <p/>
+     * This method will add a '1.1-SNAPSHOT' in the list since there is no generic snapshot entry for it.
+     * When this version is browsed, the pom of the latest snapshot will be displayed.
+     *
+     * @param versions
+     */
+    private void processSnapshots( List versions )
+    {
+        Map snapshots = new HashMap();
 
-            if ( pomArtifact == null )
+        getLogger().info( "Processing snapshots." );
+
+        for ( Iterator iter = versions.iterator(); iter.hasNext(); )
+        {
+            String version = (String) iter.next();
+            if ( VersionUtil.isSnapshot( version ) )
             {
-                throw new ObjectNotFoundException( "Unable to find artifact [" + groupId + ":" + artifactId + ":"
-                    + version + "]" );
+                String baseVersion = VersionUtil.getBaseVersion( version );
+                if ( !snapshots.containsKey( baseVersion ) )
+                {
+                    snapshots.put( baseVersion, baseVersion );
+                }
             }
         }
-        catch ( ObjectNotFoundException e )
+
+        for ( Iterator it = ( snapshots.entrySet() ).iterator(); it.hasNext(); )
         {
-            throw e;
+            String baseVersion = (String) ( (Map.Entry) it.next() ).getValue();
+            if ( !versions.contains( baseVersion ) )
+            {
+                versions.add( baseVersion );
+            }
         }
+    }
 
-        ArchivaProjectModel model;
-
-        if ( pomArtifact.getModel().isProcessed() )
+    /**
+     * Handles querying of generic (*-SNAPSHOT) snapshot version.
+     * Process:
+     * - Get all the timestamped/unique versions of the artifact from the db
+     * - Sort the queried project models
+     * - Reverse the list of queried project models to get the latest timestamp version
+     * - Loop through the list and get the first one to match the generic (*-SNAPHOT) version
+     *
+     * @param groupId
+     * @param artifactId
+     * @param version
+     * @param pomArtifact
+     * @throws ArchivaDatabaseException
+     */
+    private ArchivaArtifact handleGenericSnapshots( String groupId, String artifactId, String version,
+                                                    ArchivaArtifact pomArtifact )
+        throws ArchivaDatabaseException
+    {
+        if ( VersionUtil.isGenericSnapshot( version ) )
         {
-            // It's been processed. return it.
-            model = dao.getProjectModelDAO().getProjectModel( groupId, artifactId, version );
-            return model;
+            List versions = dao.query( new UniqueVersionConstraint( groupId, artifactId ) );
+            Collections.sort( versions );
+            Collections.reverse( versions );
+
+            for ( Iterator iter = versions.iterator(); iter.hasNext(); )
+            {
+                String uniqueVersion = (String) iter.next();
+
+                if ( VersionUtil.getBaseVersion( uniqueVersion ).equals( version ) )
+                {
+                    getLogger().info( "Retrieving artifact with version " + uniqueVersion );
+                    pomArtifact = dao.getArtifactDAO().getArtifact( groupId, artifactId, uniqueVersion, null, "pom" );
+
+                    return pomArtifact;
+                }
+            }
         }
 
-        // Process it.
-        dbUpdater.updateUnprocessed( pomArtifact );
+        return null;
+    }
 
-        // Find it.
+    /**
+     * Get the project model from the database.
+     *
+     * @param groupId
+     * @param artifactId
+     * @param version
+     * @return
+     * @throws ArchivaDatabaseException
+     */
+    private ArchivaProjectModel getProjectModel( String groupId, String artifactId, String version )
+        throws ArchivaDatabaseException
+    {
         try
         {
-            model = dao.getProjectModelDAO().getProjectModel( groupId, artifactId, version );
+            ArchivaProjectModel model = dao.getProjectModelDAO().getProjectModel( groupId, artifactId, version );
 
             if ( model == null )
             {
-                throw new ObjectNotFoundException( "Unable to find project model for [" + groupId + ":" + artifactId
-                    + ":" + version + "]" );
+                throw new ObjectNotFoundException(
+                    "Unable to find project model for [" + groupId + ":" + artifactId + ":" + version + "]" );
             }
 
             return model;
@@ -150,18 +278,4 @@ public class DefaultRepositoryBrowsing
         }
     }
 
-    public List getUsedBy( String groupId, String artifactId, String version )
-        throws ArchivaDatabaseException
-    {
-        ProjectsByArtifactUsageConstraint constraint = new ProjectsByArtifactUsageConstraint( groupId, artifactId,
-                                                                                              version );
-        List results = dao.getProjectModelDAO().queryProjectModels( constraint );
-        if ( results == null )
-        {
-            // defensive. to honor contract as specified. never null.
-            return Collections.EMPTY_LIST;
-        }
-
-        return results;
-    }
 }
index e0ae244f5afdec240a7415f90297825fab42c240..744e393ba2ee9578f58fad83daffe31605541439 100644 (file)
@@ -113,7 +113,7 @@ public class DependencyTree
         }
     }
 
-    public List gatherTreeList( String groupId, String artifactId, String version, String nodevar,
+    public List gatherTreeList( String groupId, String artifactId, String modelVersion, String nodevar,
                                 PageContext pageContext )
         throws JspException
     {
@@ -124,7 +124,7 @@ public class DependencyTree
             throw new JspException( emsg );
         }
 
-        DependencyGraph graph = fetchGraph( groupId, artifactId, version );
+        DependencyGraph graph = fetchGraph( groupId, artifactId, modelVersion );
 
         if ( graph == null )
         {
@@ -213,18 +213,20 @@ public class DependencyTree
         }
     }
 
-    private DependencyGraph fetchGraph( String groupId, String artifactId, String version )
+    private DependencyGraph fetchGraph( String groupId, String artifactId, String modelVersion )
     {
         // TODO Cache the results to disk, in XML format, in the same place as the artifact is located.
 
         VersionedReference projectRef = new VersionedReference();
         projectRef.setGroupId( groupId );
         projectRef.setArtifactId( artifactId );
-        projectRef.setVersion( version );
+        projectRef.setVersion( modelVersion );
 
         try
         {
-            return graphFactory.getGraph( projectRef );
+            DependencyGraph depGraph = graphFactory.getGraph( projectRef );
+            return depGraph;
         }
         catch ( GraphTaskException e )
         {
index 4dab8fc977805b3464532232a4956f162093fef1..451daa34465ee53c549e17c0c1d926cd4732de8f 100644 (file)
@@ -68,6 +68,8 @@ public class DependencyTreeTag
 
     private TreeEntry currentTreeEntry;
 
+    private String modelVersion;
+
     public int doAfterBody()
         throws JspException
     {
@@ -123,7 +125,7 @@ public class DependencyTreeTag
             nodevar = "node";
         }
 
-        this.tree = deptree.gatherTreeList( groupId, artifactId, version, nodevar, pageContext );
+        this.tree = deptree.gatherTreeList( groupId, artifactId, modelVersion, nodevar, pageContext );
 
         if ( CollectionUtils.isEmpty( this.tree ) )
         {
@@ -172,6 +174,11 @@ public class DependencyTreeTag
         this.version = version;
     }
 
+    public void setModelVersion( String modelVersion )
+    {
+        this.modelVersion = modelVersion;
+    }
+
     private void exposeVariables()
         throws JspException
     {
index 5c28a40d6bec67e90a117c29dcc1a4ce33f33908..43473f122ec4a6bda662d57dcd2454b8c51daf69 100644 (file)
         <description><![CDATA[The version]]></description>
       </attribute>
 
+      <attribute>
+        <name>modelVersion</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+
+        <description><![CDATA[The version of the project model. Used to verify the dependency graph for generic snapshots not yet in the repo.]]></description>
+      </attribute>
+
       <attribute>
         <name>nodevar</name>
         <required>false</required>
index 69144918f5ffeb5b6d2f169cfb51609bd8e44c70..da2758350534c14ac5552165a722f6ebbcef34e2 100644 (file)
@@ -21,7 +21,8 @@
 <%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
 <%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
 
-<archiva:dependency-tree groupId="${groupId}" artifactId="${artifactId}" version="${version}">
+<archiva:dependency-tree groupId="${groupId}" artifactId="${artifactId}" version="${version}"
+                         modelVersion="${model.version}">
   <my:showArtifactLink groupId="${node.groupId}" artifactId="${node.artifactId}"
-                       version="${node.version}"/>
+                       version="${node.version}"/>  
 </archiva:dependency-tree>
index f9debf4c68f39b33d25a6be512d6f54d70136f1b..29515ec140638c6721a6ebd40debef9f62e752f7 100644 (file)
   </div>
 
 <div class="sidebar3">
-  <archiva:downloadArtifact groupId="${groupId}" artifactId="${artifactId}" version="${Version}" />
+  <archiva:downloadArtifact groupId="${groupId}" artifactId="${artifactId}" version="${model.version}" />
 </div>
   
   <decorator:body />
index b64c51cb7b592d8e3f29324f29bd282d50ed010e..43243548b7ec91bc23d6cf2bc263808b29f581d5 100644 (file)
@@ -31,7 +31,7 @@
     </ww:url>
   </c:set>
   <a href="${url}">${model.artifactId}</a> /
-  <strong>${model.version}</strong>
+  <strong>${version}</strong>
 
   <%-- TODO: new versions?
     (<strong class="statusFailed">Newer version available:</strong>
 <pre class="pom">
     &lt;dependency>
       &lt;groupId>${model.groupId}&lt;/groupId>
-      &lt;artifactId>${model.artifactId}&lt;/artifactId>
-      &lt;version>${model.version}&lt;/version><c:if test="${model.packaging != 'jar'}">
+      &lt;artifactId>${model.artifactId}&lt;/artifactId>     
+      &lt;version>${version}&lt;/version><c:if test="${model.packaging != 'jar'}">
       &lt;type>${model.packaging}&lt;/type></c:if>
     &lt;/dependency>
 </pre>
index ab40ad175acdb5b961722a8ba2d356d95c9face9..3ba975c725054a5a74aca36edf4baf337223a857 100644 (file)
@@ -96,7 +96,7 @@
         <ww:url action="showArtifactDependencyTree">
           <ww:param name="groupId" value="%{groupId}"/>
           <ww:param name="artifactId" value="%{artifactId}"/>
-          <ww:param name="version" value="%{version}"/>
+          <ww:param name="version" value="%{version}"/>          
         </ww:url>
       </c:set>
       <my:currentWWUrl url="${url}">Dependency Tree</my:currentWWUrl>
     </span>
   </div>
 
-<div class="sidebar3">
-  <archiva:downloadArtifact groupId="${groupId}" artifactId="${artifactId}" version="${Version}" />
+<div class="sidebar3">  
+  <archiva:downloadArtifact groupId="${model.groupId}" artifactId="${model.artifactId}" version="${model.version}" />
 </div>
 
   <%-- TODO: perhaps using ajax? --%>