You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by jo...@apache.org on 2007/09/10 04:59:49 UTC

svn commit: r574120 [1/2] - in /maven/archiva/trunk/archiva-base/archiva-repository-layer/src: main/java/org/apache/maven/archiva/repository/content/ main/java/org/apache/maven/archiva/repository/layout/ main/java/org/apache/maven/archiva/repository/me...

Author: joakime
Date: Sun Sep  9 19:59:47 2007
New Revision: 574120

URL: http://svn.apache.org/viewvc?rev=574120&view=rev
Log:
[MRM-432] Proxy Connectors are unable to download artifacts with alpha numerical version numbers
Broke out metadata handling from BidirectionalRepositoryLayout into recent MetadataTools class.
Simplified test cases for default and legacy layout.
Test cases now perform round-trip for each example: reference -> path -> reference

Modified:
    maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/LegacyArtifactExtensionMapping.java
    maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayout.java
    maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayout.java
    maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayout.java
    maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/RepositoryLayoutUtils.java
    maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/MetadataTools.java
    maven/archiva/trunk/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/AbstractBidirectionalRepositoryLayoutTestCase.java
    maven/archiva/trunk/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayoutTest.java
    maven/archiva/trunk/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayoutTest.java
    maven/archiva/trunk/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/metadata/MetadataToolsTest.java

Modified: maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/LegacyArtifactExtensionMapping.java
URL: http://svn.apache.org/viewvc/maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/LegacyArtifactExtensionMapping.java?rev=574120&r1=574119&r2=574120&view=diff
==============================================================================
--- maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/LegacyArtifactExtensionMapping.java (original)
+++ maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/LegacyArtifactExtensionMapping.java Sun Sep  9 19:59:47 2007
@@ -54,11 +54,11 @@
         }
         else if ( normalizedName.endsWith( "-sources.jar" ) )
         {
-            return "jar";
+            return "java-source";
         }
         else if ( normalizedName.endsWith( "-javadoc.jar" ) )
         {
-            return "jar";
+            return "javadoc.jar";
         }
         else
         {

Modified: maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayout.java
URL: http://svn.apache.org/viewvc/maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayout.java?rev=574120&r1=574119&r2=574120&view=diff
==============================================================================
--- maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayout.java (original)
+++ maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayout.java Sun Sep  9 19:59:47 2007
@@ -21,7 +21,6 @@
 
 import org.apache.maven.archiva.model.ArchivaArtifact;
 import org.apache.maven.archiva.model.ArtifactReference;
-import org.apache.maven.archiva.model.ProjectReference;
 import org.apache.maven.archiva.model.VersionedReference;
 
 /**
@@ -63,22 +62,6 @@
     public String toPath( ArtifactReference reference );
 
     /**
-     * Given an {@link VersionedReference}, return the relative path to that reference.
-     *
-     * @param reference the versioned project reference to use.
-     * @return the relative path to the project reference.
-     */
-    public String toPath( VersionedReference reference );
-
-    /**
-     * Given an ProjectReference, return the relative path to that reference.
-     *
-     * @param reference the project reference to use.
-     * @return the relative path to the project reference.
-     */
-    public String toPath( ProjectReference reference );
-
-    /**
      * Given a repository relative path to a filename, return the {@link ArchivaArtifact} object suitable for the path.
      *
      * @param path the path relative to the repository base dir for the artifact.
@@ -87,28 +70,6 @@
      * @throws LayoutException if there was a problem converting the path to an artifact.
      */
     public ArchivaArtifact toArtifact( String path )
-        throws LayoutException;
-
-    /**
-     * Given a repository relative path to a filename, return the {@link ProjectReference} object suitable for the path.
-     *
-     * @param path the path relative to the repository base dir for the artifact.
-     * @return the {@link ProjectReference} representing the path.  (or null if path cannot be converted to
-     *         a {@link ProjectReference})
-     * @throws LayoutException if there was a problem converting the path to an artifact.
-     */
-    public ProjectReference toProjectReference( String path )
-        throws LayoutException;
-
-    /**
-     * Given a repository relative path to a filename, return the {@link VersionedReference} object suitable for the path.
-     *
-     * @param path the path relative to the repository base dir for the artifact.
-     * @return the {@link VersionedReference} representing the path.  (or null if path cannot be converted to
-     *         a {@link VersionedReference})
-     * @throws LayoutException if there was a problem converting the path to an artifact.
-     */
-    public VersionedReference toVersionedReference( String path )
         throws LayoutException;
 
     /**

Modified: maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayout.java
URL: http://svn.apache.org/viewvc/maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayout.java?rev=574120&r1=574119&r2=574120&view=diff
==============================================================================
--- maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayout.java (original)
+++ maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayout.java Sun Sep  9 19:59:47 2007
@@ -23,8 +23,6 @@
 import org.apache.maven.archiva.common.utils.VersionUtil;
 import org.apache.maven.archiva.model.ArchivaArtifact;
 import org.apache.maven.archiva.model.ArtifactReference;
-import org.apache.maven.archiva.model.ProjectReference;
-import org.apache.maven.archiva.model.VersionedReference;
 import org.apache.maven.archiva.repository.content.DefaultArtifactExtensionMapping;
 
 /**
@@ -37,8 +35,6 @@
 public class DefaultBidirectionalRepositoryLayout
     implements BidirectionalRepositoryLayout
 {
-    private static final String MAVEN_METADATA = "maven-metadata.xml";
-
     class PathReferences
     {
         public String groupId;
@@ -79,7 +75,7 @@
     public ArchivaArtifact toArtifact( String path )
         throws LayoutException
     {
-        PathReferences pathrefs = toPathReferences( path, true );
+        PathReferences pathrefs = toPathReferences( path );
 
         ArchivaArtifact artifact = new ArchivaArtifact( pathrefs.groupId, pathrefs.artifactId,
                                                         pathrefs.fileParts.version, pathrefs.fileParts.classifier,
@@ -91,7 +87,7 @@
     public ArtifactReference toArtifactReference( String path )
         throws LayoutException
     {
-        PathReferences pathrefs = toPathReferences( path, true );
+        PathReferences pathrefs = toPathReferences( path );
 
         ArtifactReference reference = new ArtifactReference();
         reference.setGroupId( pathrefs.groupId );
@@ -105,78 +101,25 @@
 
     public String toPath( ArchivaArtifact artifact )
     {
-        return toPath( artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion(), artifact
-            .getVersion(), artifact.getClassifier(), artifact.getType() );
-    }
-
-    public String toPath( ArtifactReference reference )
-    {
-        String baseVersion = VersionUtil.getBaseVersion( reference.getVersion() );
-        return toPath( reference.getGroupId(), reference.getArtifactId(), baseVersion, reference.getVersion(),
-                       reference.getClassifier(), reference.getType() );
-    }
-
-    public String toPath( ProjectReference reference )
-    {
-        StringBuffer path = new StringBuffer();
-
-        path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR );
-        path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
-        path.append( MAVEN_METADATA );
-
-        return path.toString();
-    }
-
-    public String toPath( VersionedReference reference )
-    {
-        StringBuffer path = new StringBuffer();
-
-        path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR );
-        path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
-        if ( reference.getVersion() != null )
+        if ( artifact == null )
         {
-            // add the version only if it is present
-            path.append( VersionUtil.getBaseVersion( reference.getVersion() ) ).append( PATH_SEPARATOR );
+            throw new IllegalArgumentException( "Artifact cannot be null" );
         }
-        path.append( MAVEN_METADATA );
 
-        return path.toString();
-    }
-
-    public ProjectReference toProjectReference( String path )
-        throws LayoutException
-    {
-        if ( !path.endsWith( "/maven-metadata.xml" ) )
-        {
-            throw new LayoutException(
-                "Only paths ending in '/maven-metadata.xml' can be " + "converted to a ProjectReference." );
-        }
-
-        PathReferences pathrefs = toPathReferences( path, false );
-        ProjectReference reference = new ProjectReference();
-        reference.setGroupId( pathrefs.groupId );
-        reference.setArtifactId( pathrefs.artifactId );
-
-        return reference;
+        return toPath( artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion(), artifact
+            .getVersion(), artifact.getClassifier(), artifact.getType() );
     }
 
-    public VersionedReference toVersionedReference( String path )
-        throws LayoutException
+    public String toPath( ArtifactReference reference )
     {
-        if ( !path.endsWith( "/maven-metadata.xml" ) )
+        if ( reference == null )
         {
-            throw new LayoutException(
-                "Only paths ending in '/maven-metadata.xml' can be " + "converted to a VersionedReference." );
+            throw new IllegalArgumentException( "Artifact reference cannot be null" );
         }
 
-        PathReferences pathrefs = toPathReferences( path, false );
-
-        VersionedReference reference = new VersionedReference();
-        reference.setGroupId( pathrefs.groupId );
-        reference.setArtifactId( pathrefs.artifactId );
-        reference.setVersion( pathrefs.baseVersion );
-
-        return reference;
+        String baseVersion = VersionUtil.getBaseVersion( reference.getVersion() );
+        return toPath( reference.getGroupId(), reference.getArtifactId(), baseVersion, reference.getVersion(),
+                       reference.getClassifier(), reference.getType() );
     }
 
     private String formatAsDirectory( String directory )
@@ -215,7 +158,7 @@
     {
         try
         {
-            toPathReferences( path, false );
+            toPathReferences( path );
             return true;
         }
         catch ( LayoutException e )
@@ -224,13 +167,17 @@
         }
     }
 
-    private PathReferences toPathReferences( String path, boolean parseFilename )
+    private PathReferences toPathReferences( String path )
         throws LayoutException
     {
+        if ( StringUtils.isBlank( path ) )
+        {
+            throw new LayoutException( "Unable to convert blank path." );
+        }
+
         PathReferences prefs = new PathReferences();
 
         String normalizedPath = StringUtils.replace( path, "\\", "/" );
-
         String pathParts[] = StringUtils.split( normalizedPath, '/' );
 
         /* Minimum parts.
@@ -245,8 +192,8 @@
         if ( pathParts.length < 4 )
         {
             // Illegal Path Parts Length.
-            throw new LayoutException( "Not enough parts to the path [" + path +
-                "] to construct an ArchivaArtifact from. (Requires at least 4 parts)" );
+            throw new LayoutException( "Not enough parts to the path [" + path
+                + "] to construct an ArchivaArtifact from. (Requires at least 4 parts)" );
         }
 
         // Maven 2.x path.
@@ -259,17 +206,6 @@
         // Second to last is the baseVersion (the directory version)
         prefs.baseVersion = pathParts[baseVersionPos];
 
-        if ( "maven-metadata.xml".equals( pathParts[filenamePos] ) )
-        {
-            if ( !VersionUtil.isVersion( prefs.baseVersion ) )
-            {
-                // We have a simple path without a version identifier.
-                prefs.baseVersion = null;
-                artifactIdPos++;
-                groupIdPos++;
-            }
-        }
-
         // Third to last is the artifact Id.
         prefs.artifactId = pathParts[artifactIdPos];
 
@@ -287,25 +223,84 @@
             // Now we need to parse the filename to get the artifact version Id. 
             prefs.fileParts = RepositoryLayoutUtils.splitFilename( filename, prefs.artifactId );
 
+            /* If classifier is discovered, see if it deserves to be.
+             * 
+             * Filenames like "comm-3.0-u1.jar" might be identified as having a version of "3.0"
+             * and a classifier of "u1".
+             * 
+             * This routine will take the version + classifier and compare it to the prefs.baseVersion and 
+             * move the classifierensure that
+             * 
+             * javax/comm/3.0-u1/comm-3.0-u1.jar
+             */
+            if ( StringUtils.isNotBlank( prefs.fileParts.classifier ) )
+            {
+                String conjoinedVersion = prefs.fileParts.version + "-" + prefs.fileParts.classifier; 
+                
+                if( StringUtils.equals( prefs.baseVersion, conjoinedVersion ) )
+                {
+                    prefs.fileParts.version = conjoinedVersion;
+                    prefs.fileParts.classifier = null;
+                }
+            }
+
             prefs.type = extensionMapper.getType( filename );
         }
         catch ( LayoutException e )
         {
-            if ( parseFilename )
-            {
-                throw e;
-            }
+            throw e;
         }
 
         // Sanity Checks.
         if ( prefs.fileParts != null )
         {
-            String artifactBaseVersion = VersionUtil.getBaseVersion( prefs.fileParts.version );
-            if ( !artifactBaseVersion.equals( prefs.baseVersion ) )
+            /* Compare artifact version to path baseversion.
+             * 
+             * Version naming in the wild can be strange at times.
+             * Sometimes what is seen as a classifier is actually part of the version id.
+             * 
+             * To compensate for this, the path is checked against the artifact.version and
+             *  the concatenation of the artifact.version + "-" + artifact.classifier
+             */
+            String pathVersion = prefs.baseVersion;
+            String artifactVersion = prefs.fileParts.version;
+
+            // Do we have a snapshot version?
+            if ( VersionUtil.isSnapshot( artifactVersion ) )
+            {
+                // Rules are different for SNAPSHOTS
+                if ( !VersionUtil.isGenericSnapshot( pathVersion ) )
+                {
+                    String baseVersion = VersionUtil.getBaseVersion( prefs.fileParts.version );
+                    throw new LayoutException( "Invalid snapshot artifact location, version directory should be "
+                        + baseVersion );
+                }
+            }
+            else
             {
-                throw new LayoutException( "Invalid artifact location, version directory and filename mismatch." );
+                // Non SNAPSHOT rules.
+                // Do we pass the simple test?
+                if ( !StringUtils.equals( pathVersion, artifactVersion ) )
+                {
+                    // Do we have a classifier?  If so, test the conjoined case.
+                    if ( StringUtils.isNotBlank( prefs.fileParts.classifier ) )
+                    {
+                        String artifactLongVersion = artifactVersion + "-" + prefs.fileParts.classifier;
+                        if ( !StringUtils.equals( pathVersion, artifactLongVersion ) )
+                        {
+                            throw new LayoutException( "Invalid artifact: version declared in directory path does"
+                                + " not match what was found in the artifact filename." );
+                        }
+                    }
+                    else
+                    {
+                        throw new LayoutException( "Invalid artifact: version declared in directory path does"
+                            + " not match what was found in the artifact filename." );
+                    }
+                }
             }
 
+            // Test if the artifactId present on the directory path is the same as the artifactId filename.
             if ( !prefs.artifactId.equals( prefs.fileParts.artifactId ) )
             {
                 throw new LayoutException( "Invalid artifact Id" );

Modified: maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayout.java
URL: http://svn.apache.org/viewvc/maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayout.java?rev=574120&r1=574119&r2=574120&view=diff
==============================================================================
--- maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayout.java (original)
+++ maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayout.java Sun Sep  9 19:59:47 2007
@@ -22,8 +22,6 @@
 import org.apache.commons.lang.StringUtils;
 import org.apache.maven.archiva.model.ArchivaArtifact;
 import org.apache.maven.archiva.model.ArtifactReference;
-import org.apache.maven.archiva.model.ProjectReference;
-import org.apache.maven.archiva.model.VersionedReference;
 import org.apache.maven.archiva.repository.content.LegacyArtifactExtensionMapping;
 
 import java.util.HashMap;
@@ -39,7 +37,9 @@
 public class LegacyBidirectionalRepositoryLayout
     implements BidirectionalRepositoryLayout
 {
-    private static final String MAVEN_METADATA = "maven-metadata.xml";
+    private static final String DIR_JAVADOC = "javadoc.jars";
+
+    private static final String DIR_JAVA_SOURCE = "java-sources";
 
     private static final String PATH_SEPARATOR = "/";
 
@@ -62,31 +62,8 @@
 
     public String toPath( ArchivaArtifact artifact )
     {
-        return toPath( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getClassifier(),
-                       artifact.getType() );
-    }
-
-    public String toPath( ProjectReference reference )
-    {
-        StringBuffer path = new StringBuffer();
-
-        path.append( reference.getGroupId() ).append( PATH_SEPARATOR );
-        path.append( getDirectory( null, "jar" ) ).append( PATH_SEPARATOR );
-        path.append( MAVEN_METADATA );
-
-        return path.toString();
-    }
-
-    public String toPath( VersionedReference reference )
-    {
-        // NOTE: A legacy repository cannot contain a versioned reference to the metadata.
-        StringBuffer path = new StringBuffer();
-
-        path.append( reference.getGroupId() ).append( PATH_SEPARATOR );
-        path.append( getDirectory( null, "jar" ) ).append( PATH_SEPARATOR );
-        path.append( MAVEN_METADATA );
-
-        return path.toString();
+        return toPath( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(),
+                       artifact.getClassifier(), artifact.getType() );
     }
 
     public String toPath( ArtifactReference reference )
@@ -124,12 +101,12 @@
         {
             if ( "sources".equals( classifier ) )
             {
-                return "source.jars";
+                return DIR_JAVA_SOURCE;
             }
 
             if ( "javadoc".equals( classifier ) )
             {
-                return "javadoc.jars";
+                return DIR_JAVADOC;
             }
         }
 
@@ -156,7 +133,7 @@
         public FilenameParts fileParts;
     }
 
-    private PathReferences toPathReferences( String path, boolean parseFilename )
+    private PathReferences toPathReferences( String path )
         throws LayoutException
     {
         PathReferences prefs = new PathReferences();
@@ -176,8 +153,8 @@
         if ( pathParts.length != 3 )
         {
             // Illegal Path Parts Length.
-            throw new LayoutException( "Invalid number of parts to the path [" + path +
-                "] to construct an ArchivaArtifact from. (Required to be 3 parts)" );
+            throw new LayoutException( "Invalid number of parts to the path [" + path
+                + "] to construct an ArchivaArtifact from. (Required to be 3 parts)" );
         }
 
         // The Group ID.
@@ -186,43 +163,46 @@
         // The Expected Type.
         prefs.pathType = pathParts[1];
 
-        if ( parseFilename )
-        {
-            // The Filename.
-            String filename = pathParts[2];
+        // The Filename.
+        String filename = pathParts[2];
 
-            prefs.fileParts = RepositoryLayoutUtils.splitFilename( filename, null );
+        prefs.fileParts = RepositoryLayoutUtils.splitFilename( filename, null );
 
-            prefs.type = extensionMapper.getType( prefs.pathType, filename );
+        String trimPathType = prefs.pathType.substring( 0, prefs.pathType.length() - 1 );
+        prefs.type = extensionMapper.getType( trimPathType, filename );
 
-            // Sanity Checks.
-            if ( StringUtils.isEmpty( prefs.fileParts.extension ) )
-            {
-                throw new LayoutException( "Invalid artifact, no extension." );
-            }
+        // Sanity Check: does it have an extension?
+        if ( StringUtils.isEmpty( prefs.fileParts.extension ) )
+        {
+            throw new LayoutException( "Invalid artifact, no extension." );
+        }
 
-            if ( !prefs.type.equals( prefs.fileParts.extension ) )
-            {
-                throw new LayoutException( "Invalid artifact, mismatch on extension <" + prefs.fileParts.extension +
-                    "> and expected layout specified type <" + prefs.pathType + "> (mapped type: <" + prefs.type +
-                    ">) on path <" + path + ">" );
-            }
+        // Sanity Check: pathType should end in "s".
+        if ( !prefs.pathType.toLowerCase().endsWith( "s" ) )
+        {
+            throw new LayoutException( "Invalid path, the type specified in the path <" + prefs.pathType
+                + "> does not end in the letter <s>." );
         }
 
-        return prefs;
-    }
+        // Sanity Check: does extension match pathType on path?
+        String expectedExtension = extensionMapper.getExtension( trimPathType );
+        String actualExtension = prefs.fileParts.extension;
 
-    public ProjectReference toProjectReference( String path )
-        throws LayoutException
-    {
-        throw new LayoutException( "Cannot parse legacy paths to a Project Reference." );
+        if ( !expectedExtension.equals( actualExtension ) )
+        {
+            throw new LayoutException( "Invalid artifact, mismatch on extension <" + prefs.fileParts.extension
+                + "> and layout specified type <" + prefs.pathType + "> (which maps to extension: <"
+                + expectedExtension + ">) on path <" + path + ">" );
+        }
+
+        return prefs;
     }
 
     public boolean isValidPath( String path )
     {
         try
         {
-            toPathReferences( path, false );
+            toPathReferences( path );
             return true;
         }
         catch ( LayoutException e )
@@ -234,7 +214,7 @@
     public ArchivaArtifact toArtifact( String path )
         throws LayoutException
     {
-        PathReferences pathrefs = toPathReferences( path, true );
+        PathReferences pathrefs = toPathReferences( path );
 
         ArchivaArtifact artifact = new ArchivaArtifact( pathrefs.groupId, pathrefs.fileParts.artifactId,
                                                         pathrefs.fileParts.version, pathrefs.fileParts.classifier,
@@ -246,7 +226,7 @@
     public ArtifactReference toArtifactReference( String path )
         throws LayoutException
     {
-        PathReferences pathrefs = toPathReferences( path, true );
+        PathReferences pathrefs = toPathReferences( path );
 
         ArtifactReference reference = new ArtifactReference();
 
@@ -258,11 +238,4 @@
 
         return reference;
     }
-
-    public VersionedReference toVersionedReference( String path )
-        throws LayoutException
-    {
-        return null;
-    }
-
 }

Modified: maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/RepositoryLayoutUtils.java
URL: http://svn.apache.org/viewvc/maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/RepositoryLayoutUtils.java?rev=574120&r1=574119&r2=574120&view=diff
==============================================================================
--- maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/RepositoryLayoutUtils.java (original)
+++ maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/RepositoryLayoutUtils.java Sun Sep  9 19:59:47 2007
@@ -141,7 +141,17 @@
 
         if ( versionStart < 0 )
         {
-            throw new LayoutException( "Unable to determine version from filename " + filename );
+            // Assume rest of string is the version Id.
+            
+            if ( fileParts.length > 0 )
+            {
+                versionStart = 0;
+                versionEnd = fileParts.length;
+            }
+            else
+            {
+                throw new LayoutException( "Unable to determine version from filename " + filename );
+            }
         }
 
         // Gather up the ArtifactID - Version - Classifier pieces found. 

Modified: maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/MetadataTools.java
URL: http://svn.apache.org/viewvc/maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/MetadataTools.java?rev=574120&r1=574119&r2=574120&view=diff
==============================================================================
--- maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/MetadataTools.java (original)
+++ maven/archiva/trunk/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/MetadataTools.java Sun Sep  9 19:59:47 2007
@@ -71,6 +71,12 @@
      */
     private static Logger log = LoggerFactory.getLogger( MetadataTools.class );
 
+    public static final String MAVEN_METADATA = "maven-metadata.xml";
+
+    private static final char PATH_SEPARATOR = '/';
+
+    private static final char GROUP_SEPARATOR = '.';
+
     /**
      * @plexus.requirement
      */
@@ -90,6 +96,8 @@
 
     private Map<String, Set<String>> proxies;
 
+    private static final char NUMS[] = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
+
     public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
     {
         if ( ConfigurationNames.isProxyConnector( propertyName ) )
@@ -113,8 +121,7 @@
     public Set<String> gatherAvailableVersions( ArchivaRepository managedRepository, ProjectReference reference )
         throws LayoutException, IOException
     {
-        BidirectionalRepositoryLayout layout = layoutFactory.getLayout( managedRepository.getLayoutType() );
-        String path = layout.toPath( reference );
+        String path = toPath( reference );
 
         int idx = path.lastIndexOf( '/' );
         if ( idx > 0 )
@@ -191,7 +198,7 @@
         throws LayoutException, IOException
     {
         BidirectionalRepositoryLayout layout = layoutFactory.getLayout( managedRepository.getLayoutType() );
-        String path = layout.toPath( reference );
+        String path = toPath( reference );
 
         int idx = path.lastIndexOf( '/' );
         if ( idx > 0 )
@@ -246,7 +253,7 @@
         throws LayoutException, IOException
     {
         BidirectionalRepositoryLayout layout = layoutFactory.getLayout( managedRepository.getLayoutType() );
-        String path = layout.toPath( reference );
+        String path = toPath( reference );
 
         int idx = path.lastIndexOf( '/' );
         if ( idx > 0 )
@@ -336,6 +343,127 @@
         return foundVersions;
     }
 
+    /**
+     * Take a path to a maven-metadata.xml, and attempt to translate it to a VersionedReference. 
+     * 
+     * @param path
+     * @return
+     */
+    public VersionedReference toVersionedReference( String path )
+        throws RepositoryMetadataException
+    {
+        if ( !path.endsWith( "/" + MAVEN_METADATA ) )
+        {
+            throw new RepositoryMetadataException( "Cannot convert to versioned reference, not a metadata file. " );
+        }
+
+        VersionedReference reference = new VersionedReference();
+
+        String normalizedPath = StringUtils.replace( path, "\\", "/" );
+        String pathParts[] = StringUtils.split( normalizedPath, '/' );
+
+        int versionOffset = pathParts.length - 2;
+        int artifactIdOffset = versionOffset - 1;
+        int groupIdEnd = artifactIdOffset - 1;
+
+        reference.setVersion( pathParts[versionOffset] );
+
+        if ( !hasNumberAnywhere( reference.getVersion() ) )
+        {
+            // Scary check, but without it, all paths are version references;
+            throw new RepositoryMetadataException(
+                                                   "Not a versioned reference, as version id on path has no number in it." );
+        }
+
+        reference.setArtifactId( pathParts[artifactIdOffset] );
+
+        StringBuffer gid = new StringBuffer();
+        for ( int i = 0; i <= groupIdEnd; i++ )
+        {
+            if ( i > 0 )
+            {
+                gid.append( "." );
+            }
+            gid.append( pathParts[i] );
+        }
+
+        reference.setGroupId( gid.toString() );
+
+        return reference;
+    }
+
+    private boolean hasNumberAnywhere( String version )
+    {
+        return StringUtils.indexOfAny( version, NUMS ) != ( -1 );
+    }
+
+    public ProjectReference toProjectReference( String path )
+        throws RepositoryMetadataException
+    {
+        if ( !path.endsWith( "/" + MAVEN_METADATA ) )
+        {
+            throw new RepositoryMetadataException( "Cannot convert to versioned reference, not a metadata file. " );
+        }
+
+        ProjectReference reference = new ProjectReference();
+
+        String normalizedPath = StringUtils.replace( path, "\\", "/" );
+        String pathParts[] = StringUtils.split( normalizedPath, '/' );
+
+        // Assume last part of the path is the version.
+
+        int artifactIdOffset = pathParts.length - 2;
+        int groupIdEnd = artifactIdOffset - 1;
+
+        reference.setArtifactId( pathParts[artifactIdOffset] );
+
+        StringBuffer gid = new StringBuffer();
+        for ( int i = 0; i <= groupIdEnd; i++ )
+        {
+            if ( i > 0 )
+            {
+                gid.append( "." );
+            }
+            gid.append( pathParts[i] );
+        }
+
+        reference.setGroupId( gid.toString() );
+
+        return reference;
+    }
+
+    public String toPath( ProjectReference reference )
+    {
+        StringBuffer path = new StringBuffer();
+
+        path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR );
+        path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
+        path.append( MAVEN_METADATA );
+
+        return path.toString();
+    }
+
+    public String toPath( VersionedReference reference )
+    {
+        StringBuffer path = new StringBuffer();
+
+        path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR );
+        path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
+        if ( reference.getVersion() != null )
+        {
+            // add the version only if it is present
+            path.append( VersionUtil.getBaseVersion( reference.getVersion() ) ).append( PATH_SEPARATOR );
+        }
+        path.append( MAVEN_METADATA );
+
+        return path.toString();
+    }
+
+    private String formatAsDirectory( String directory )
+    {
+        return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR );
+    }
+
     private boolean matchesArtifactPattern( String relativePath )
     {
         Iterator<String> it = this.artifactPatterns.iterator();
@@ -402,10 +530,8 @@
 
     public ArchivaRepositoryMetadata readProxyMetadata( ArchivaRepository managedRepository,
                                                         ProjectReference reference, String proxyId )
-        throws LayoutException
     {
-        BidirectionalRepositoryLayout layout = layoutFactory.getLayout( managedRepository.getLayoutType() );
-        String metadataPath = getRepositorySpecificName( proxyId, layout.toPath( reference ) );
+        String metadataPath = getRepositorySpecificName( proxyId, toPath( reference ) );
         File metadataFile = new File( managedRepository.getUrl().getPath(), metadataPath );
 
         try
@@ -423,10 +549,8 @@
 
     public ArchivaRepositoryMetadata readProxyMetadata( ArchivaRepository managedRepository,
                                                         VersionedReference reference, String proxyId )
-        throws LayoutException
     {
-        BidirectionalRepositoryLayout layout = layoutFactory.getLayout( managedRepository.getLayoutType() );
-        String metadataPath = getRepositorySpecificName( proxyId, layout.toPath( reference ) );
+        String metadataPath = getRepositorySpecificName( proxyId, toPath( reference ) );
         File metadataFile = new File( managedRepository.getUrl().getPath(), metadataPath );
 
         try
@@ -458,8 +582,7 @@
     public void updateMetadata( ArchivaRepository managedRepository, ProjectReference reference )
         throws LayoutException, RepositoryMetadataException, IOException
     {
-        BidirectionalRepositoryLayout layout = layoutFactory.getLayout( managedRepository.getLayoutType() );
-        File metadataFile = new File( managedRepository.getUrl().getPath(), layout.toPath( reference ) );
+        File metadataFile = new File( managedRepository.getUrl().getPath(), toPath( reference ) );
 
         ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
         metadata.setGroupId( reference.getGroupId() );
@@ -525,7 +648,7 @@
         throws LayoutException, RepositoryMetadataException, IOException
     {
         BidirectionalRepositoryLayout layout = layoutFactory.getLayout( managedRepository.getLayoutType() );
-        File metadataFile = new File( managedRepository.getUrl().getPath(), layout.toPath( reference ) );
+        File metadataFile = new File( managedRepository.getUrl().getPath(), toPath( reference ) );
 
         ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
         metadata.setGroupId( reference.getGroupId() );

Modified: maven/archiva/trunk/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/AbstractBidirectionalRepositoryLayoutTestCase.java
URL: http://svn.apache.org/viewvc/maven/archiva/trunk/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/AbstractBidirectionalRepositoryLayoutTestCase.java?rev=574120&r1=574119&r2=574120&view=diff
==============================================================================
--- maven/archiva/trunk/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/AbstractBidirectionalRepositoryLayoutTestCase.java (original)
+++ maven/archiva/trunk/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/AbstractBidirectionalRepositoryLayoutTestCase.java Sun Sep  9 19:59:47 2007
@@ -81,19 +81,14 @@
 
         assertNotNull( expectedId + " - Should not be null.", actualArtifact );
 
-        String expectedType = type;
-
-        // Special Case.
-        if ( "ejb-client".equals( type ) )
-        {
-            expectedType = "jar";
-        }
-
         assertEquals( expectedId + " - Group ID", groupId, actualArtifact.getGroupId() );
         assertEquals( expectedId + " - Artifact ID", artifactId, actualArtifact.getArtifactId() );
+        if ( StringUtils.isNotBlank( classifier ) )
+        {
+            assertEquals( expectedId + " - Classifier", classifier, actualArtifact.getClassifier() );
+        }
         assertEquals( expectedId + " - Version ID", version, actualArtifact.getVersion() );
-        assertEquals( expectedId + " - Classifier", classifier, actualArtifact.getClassifier() );
-        assertEquals( expectedId + " - Type", expectedType, actualArtifact.getType() );
+        assertEquals( expectedId + " - Type", type, actualArtifact.getType() );
     }
 
     protected void assertArtifactReference( ArtifactReference actualReference, String groupId, String artifactId,
@@ -104,19 +99,14 @@
 
         assertNotNull( expectedId + " - Should not be null.", actualReference );
 
-        String expectedType = type;
-
-        // Special Case.
-        if ( "ejb-client".equals( type ) )
-        {
-            expectedType = "jar";
-        }
-
         assertEquals( expectedId + " - Group ID", groupId, actualReference.getGroupId() );
         assertEquals( expectedId + " - Artifact ID", artifactId, actualReference.getArtifactId() );
+        if ( StringUtils.isNotBlank( classifier ) )
+        {
+            assertEquals( expectedId + " - Classifier", classifier, actualReference.getClassifier() );
+        }
         assertEquals( expectedId + " - Version ID", version, actualReference.getVersion() );
-        assertEquals( expectedId + " - Classifier", classifier, actualReference.getClassifier() );
-        assertEquals( expectedId + " - Type", expectedType, actualReference.getType() );
+        assertEquals( expectedId + " - Type", type, actualReference.getType() );
     }
 
     protected void assertVersionedReference( VersionedReference actualReference, String groupId, String artifactId,

Modified: maven/archiva/trunk/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayoutTest.java
URL: http://svn.apache.org/viewvc/maven/archiva/trunk/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayoutTest.java?rev=574120&r1=574119&r2=574120&view=diff
==============================================================================
--- maven/archiva/trunk/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayoutTest.java (original)
+++ maven/archiva/trunk/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayoutTest.java Sun Sep  9 19:59:47 2007
@@ -19,15 +19,8 @@
  * under the License.
  */
 
-import org.apache.commons.lang.StringUtils;
 import org.apache.maven.archiva.model.ArchivaArtifact;
 import org.apache.maven.archiva.model.ArtifactReference;
-import org.apache.maven.archiva.model.ProjectReference;
-import org.apache.maven.archiva.model.VersionedReference;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
 
 /**
  * DefaultBidirectionalRepositoryLayoutTest 
@@ -38,479 +31,306 @@
 public class DefaultBidirectionalRepositoryLayoutTest
     extends AbstractBidirectionalRepositoryLayoutTestCase
 {
-    class LayoutExample
-    {
-        public String groupId;
-
-        public String artifactId;
-
-        public String version;
-
-        public String classifier;
-
-        public String type;
-
-        public String pathArtifact;
-
-        public String pathVersiond;
-
-        public String pathProjectd;
-
-        public LayoutExample( String groupId, String artifactId, String version, String classifier, String type )
-        {
-            super();
-            this.groupId = groupId;
-            this.artifactId = artifactId;
-            this.version = version;
-            this.classifier = classifier;
-            this.type = type;
-        }
-
-        public void setDelimitedPath( String delimPath )
-        {
-            // Silly Test Writer! Don't end the path with a slash!
-            if ( delimPath.endsWith( "/" ) )
-            {
-                delimPath = delimPath.substring( 0, delimPath.length() - 1 );
-            }
-
-            String parts[] = StringUtils.split( delimPath, '|' );
-            switch ( parts.length )
-            {
-                case 3:
-                    this.pathArtifact = parts[0] + "/" + parts[1] + "/" + parts[2];
-                case 2:
-                    this.pathVersiond = parts[0] + "/" + parts[1] + "/maven-metadata.xml";
-                case 1:
-                    this.pathProjectd = parts[0] + "/maven-metadata.xml";
-                    break;
-                default:
-                    fail( "Unknown number of path pieces, expected between 1 and 3, got <" + parts.length + "> on <"
-                        + delimPath + ">" );
-            }
-        }
-
-        public boolean isSuitableForArtifactTest()
-        {
-            return ( this.type != null ) && ( this.classifier != null ) && ( this.version != null );
-        }
-
-        public boolean isSuitableForVersionedTest()
-        {
-            return ( this.type == null ) && ( this.classifier == null ) && ( this.version != null );
-        }
+    private BidirectionalRepositoryLayout layout;
 
-        public boolean isSuitableForProjectTest()
-        {
-            return ( this.type == null ) && ( this.classifier == null ) && ( this.version == null );
-        }
+    public void testBadPathMissingType()
+    {
+        assertBadPath( "invalid/invalid/1/invalid-1", "missing type" );
     }
 
-    class InvalidExample
+    public void testBadPathReleaseInSnapshotDir()
     {
-        public String path;
-
-        public String reason;
-
-        public boolean hasFilename;
-
-        public InvalidExample( String path, boolean hasFilename, String reason )
-        {
-            super();
-            this.path = path;
-            this.hasFilename = hasFilename;
-            this.reason = reason;
-        }
+        assertBadPath( "invalid/invalid/1.0-SNAPSHOT/invalid-1.0.jar", "non snapshot artifact inside of a snapshot dir" );
     }
 
-    private BidirectionalRepositoryLayout layout;
-
-    public List /*<LayoutExample>*/getGoodExamples()
+    public void testBadPathTimestampedSnapshotNotInSnapshotDir()
     {
-        List ret = new ArrayList();
-
-        LayoutExample example;
-
-        // Artifact References
-        example = new LayoutExample( "com.foo", "foo-tool", "1.0", null, "jar" );
-        example.setDelimitedPath( "com/foo/foo-tool|1.0|foo-tool-1.0.jar" );
-        ret.add( example );
-
-        example = new LayoutExample( "com.foo", "foo-client", "1.0", null, "ejb-client" );
-        example.setDelimitedPath( "com/foo/foo-client|1.0|foo-client-1.0.jar" );
-        ret.add( example );
-
-        example = new LayoutExample( "com.foo.lib", "foo-lib", "2.1-alpha-1", "sources", "java-source" );
-        example.setDelimitedPath( "com/foo/lib/foo-lib|2.1-alpha-1|foo-lib-2.1-alpha-1-sources.jar" );
-        ret.add( example );
-
-        example = new LayoutExample( "com.foo", "foo-connector", "2.1-20060822.123456-35", null, "jar" );
-        example.setDelimitedPath( "com/foo/foo-connector/2.1-SNAPSHOT/foo-connector-2.1-20060822.123456-35.jar" );
-        ret.add( example );
-
-        example = new LayoutExample( "org.apache.maven.test", "get-metadata-snapshot", "1.0-20050831.101112-1", null,
-                                     "jar" );
-        example
-            .setDelimitedPath( "org/apache/maven/test/get-metadata-snapshot|1.0-SNAPSHOT|get-metadata-snapshot-1.0-20050831.101112-1.jar" );
-        ret.add( example );
-
-        example = new LayoutExample( "commons-lang", "commons-lang", "2.1", null, "jar" );
-        example.setDelimitedPath( "commons-lang/commons-lang|2.1|commons-lang-2.1.jar" );
-        ret.add( example );
-
-        example = new LayoutExample( "com.foo", "foo-tool", "1.0", null, "jar" );
-        example.setDelimitedPath( "com/foo/foo-tool|1.0|foo-tool-1.0.jar" );
-        ret.add( example );
-
-        // Versioned References (done here by setting classifier and type to null)
-        example = new LayoutExample( "com.foo", "foo-tool", "1.0", null, null );
-        example.setDelimitedPath( "com/foo/foo-tool|1.0" );
-        ret.add( example );
-
-        example = new LayoutExample( "net.i.have.a.really.long.path.just.for.the.hell.of.it", "a", "1.1-alpha-1", null,
-                                     null );
-        example.setDelimitedPath( "net/i/have/a/really/long/path/just/for/the/hell/of/it/a|1.1-alpha-1" );
-        ret.add( example );
-
-        example = new LayoutExample( "com.foo", "foo-connector", "2.1-20060822.123456-35", null, null );
-        example.setDelimitedPath( "com/foo/foo-connector|2.1-SNAPSHOT" );
-        ret.add( example );
-
-        example = new LayoutExample( "com.foo", "foo-connector", "2.1-SNAPSHOT", null, null );
-        example.setDelimitedPath( "com/foo/foo-connector|2.1-SNAPSHOT" );
-        ret.add( example );
-
-        // Project References (done here by setting version, classifier, and type to null)
-        example = new LayoutExample( "com.foo", "foo-tool", null, null, null );
-        example.setDelimitedPath( "com/foo/foo-tool/" );
-        ret.add( example );
-
-        example = new LayoutExample( "net.i.have.a.really.long.path.just.for.the.hell.of.it", "a", null, null, null );
-        example.setDelimitedPath( "net/i/have/a/really/long/path/just/for/the/hell/of/it/a/" );
-        ret.add( example );
-
-        example = new LayoutExample( "com.foo", "foo-connector", null, null, null );
-        example.setDelimitedPath( "com/foo/foo-connector" );
-        ret.add( example );
-
-        return ret;
+        assertBadPath( "invalid/invalid/1.0-20050611.123456-1/invalid-1.0-20050611.123456-1.jar",
+                       "Timestamped Snapshot artifact not inside of an Snapshot dir" );
     }
 
-    public List /*<InvalidExample>*/getInvalidPaths()
+    public void testBadPathTooShort()
     {
-        List ret = new ArrayList();
-
-        InvalidExample example;
-
-        example = new InvalidExample( "invalid/invalid/1/invalid-1", false, "missing type" );
-        ret.add( example );
-
-        example = new InvalidExample( "invalid/invalid/1.0-SNAPSHOT/invalid-1.0.jar", true,
-                                      "non snapshot artifact inside of a snapshot dir" );
-        ret.add( example );
-
-        example = new InvalidExample( "invalid/invalid-1.0.jar", true, "path is too short" );
-        ret.add( example );
-
-        example = new InvalidExample( "invalid/invalid/1.0-20050611.123456-1/invalid-1.0-20050611.123456-1.jar", true,
-                                      "Timestamped Snapshot artifact not inside of an Snapshot dir" );
-        ret.add( example );
-
-        example = new InvalidExample( "invalid/invalid/1.0/invalid-2.0.jar", true,
-                                      "version mismatch between path and artifact" );
-        ret.add( example );
-
-        example = new InvalidExample( "invalid/invalid/1.0/invalid-1.0b.jar", true,
-                                      "version mismatch between path and artifact" );
-        ret.add( example );
-
-        example = new InvalidExample( "org/apache/maven/test/1.0-SNAPSHOT/wrong-artifactId-1.0-20050611.112233-1.jar",
-                                      true, "wrong artifact id" );
-
-        return ret;
+        assertBadPath( "invalid/invalid-1.0.jar", "path is too short" );
     }
 
-    public void testArtifactToPath()
+    public void testBadPathVersionMismatchA()
     {
-        Iterator it = getGoodExamples().iterator();
-        while ( it.hasNext() )
-        {
-            LayoutExample example = (LayoutExample) it.next();
-            if ( example.isSuitableForArtifactTest() )
-            {
-                ArchivaArtifact artifact = createArtifact( example.groupId, example.artifactId, example.version,
-                                                           example.classifier, example.type );
-                assertEquals( "Artifact <" + artifact + "> to path:", example.pathArtifact, layout.toPath( artifact ) );
-            }
-        }
+        assertBadPath( "invalid/invalid/1.0/invalid-2.0.jar", "version mismatch between path and artifact" );
     }
 
-    public void testArtifactReferenceToPath()
+    public void testBadPathVersionMismatchB()
     {
-        Iterator it = getGoodExamples().iterator();
-        while ( it.hasNext() )
-        {
-            LayoutExample example = (LayoutExample) it.next();
-            if ( example.isSuitableForArtifactTest() )
-            {
-                ArtifactReference reference = new ArtifactReference();
-                reference.setGroupId( example.groupId );
-                reference.setArtifactId( example.artifactId );
-                reference.setVersion( example.version );
-                reference.setClassifier( example.classifier );
-                reference.setType( example.type );
-
-                assertEquals( "ArtifactReference <" + reference + "> to path:", example.pathArtifact, layout
-                    .toPath( reference ) );
-            }
-        }
+        assertBadPath( "invalid/invalid/1.0/invalid-1.0b.jar", "version mismatch between path and artifact" );
     }
 
-    public void testVersionedReferenceToPath()
+    public void testBadPathWrongArtifactId()
     {
-        Iterator it = getGoodExamples().iterator();
-        while ( it.hasNext() )
-        {
-            LayoutExample example = (LayoutExample) it.next();
-            if ( example.isSuitableForVersionedTest() || example.isSuitableForArtifactTest() )
-            {
-                VersionedReference reference = new VersionedReference();
-                reference.setGroupId( example.groupId );
-                reference.setArtifactId( example.artifactId );
-                reference.setVersion( example.version );
-
-                assertEquals( "VersionedReference <" + reference + "> to path:", example.pathVersiond, layout
-                    .toPath( reference ) );
-            }
-        }
+        assertBadPath( "org/apache/maven/test/1.0-SNAPSHOT/wrong-artifactId-1.0-20050611.112233-1.jar",
+                       "wrong artifact id" );
     }
 
-    public void testProjectReferenceToPath()
+    /** 
+     * [MRM-432] Oddball version spec.
+     * Example of an oddball / unusual version spec.
+     * @throws LayoutException 
+     */
+    public void testGoodButOddVersionSpecGanymedSsh2()
+        throws LayoutException
     {
-        Iterator it = getGoodExamples().iterator();
-        while ( it.hasNext() )
-        {
-            LayoutExample example = (LayoutExample) it.next();
-            if ( example.isSuitableForProjectTest() || example.isSuitableForVersionedTest()
-                || example.isSuitableForArtifactTest() )
-            {
-                ProjectReference reference = new ProjectReference();
-                reference.setGroupId( example.groupId );
-                reference.setArtifactId( example.artifactId );
+        String groupId = "ch.ethz.ganymed";
+        String artifactId = "ganymed-ssh2";
+        String version = "build210";
+        String classifier = null;
+        String type = "jar";
+        String path = "ch/ethz/ganymed/ganymed-ssh2/build210/ganymed-ssh2-build210.jar";
+
+        assertLayout( path, groupId, artifactId, version, classifier, type );
+    }
+
+    /** 
+     * [MRM-432] Oddball version spec.
+     * Example of an oddball / unusual version spec.
+     * @throws LayoutException 
+     */
+    public void testGoodButOddVersionSpecJavaxComm()
+        throws LayoutException
+    {
+        String groupId = "javax";
+        String artifactId = "comm";
+        String version = "3.0-u1";
+        String classifier = null;
+        String type = "jar";
+        String path = "javax/comm/3.0-u1/comm-3.0-u1.jar";
+
+        assertLayout( path, groupId, artifactId, version, classifier, type );
+    }
+
+    /** 
+     * [MRM-432] Oddball version spec.
+     * Example of an oddball / unusual version spec.
+     * @throws LayoutException 
+     */
+    public void testGoodButOddVersionSpecJavaxPersistence()
+        throws LayoutException
+    {
+        String groupId = "javax.persistence";
+        String artifactId = "ejb";
+        String version = "3.0-public_review";
+        String classifier = null;
+        String type = "jar";
+        String path = "javax/persistence/ejb/3.0-public_review/ejb-3.0-public_review.jar";
+
+        /* 
+         * The version id of "public_review" can cause problems. is it part of
+         * the version spec? or the classifier?
+         * Since the path spec below shows it in the path, then it is really
+         * part of the version spec. 
+         */
 
-                assertEquals( "ProjectReference <" + reference + "> to path:", example.pathProjectd, layout
-                    .toPath( reference ) );
-            }
-        }
+        assertLayout( path, groupId, artifactId, version, classifier, type );
     }
 
-    public void testInvalidPathToArtifact()
+    public void testGoodComFooTool()
+        throws LayoutException
     {
-        Iterator it = getInvalidPaths().iterator();
-        while ( it.hasNext() )
-        {
-            InvalidExample example = (InvalidExample) it.next();
+        String groupId = "com.foo";
+        String artifactId = "foo-tool";
+        String version = "1.0";
+        String classifier = null;
+        String type = "jar";
+        String path = "com/foo/foo-tool/1.0/foo-tool-1.0.jar";
 
-            try
-            {
-                layout.toArtifact( example.path );
-                fail( "Should have thrown a LayoutException on the invalid path [" + example.path + "] because of ["
-                    + example.reason + "]" );
-            }
-            catch ( LayoutException e )
-            {
-                /* expected path */
-            }
-        }
+        assertLayout( path, groupId, artifactId, version, classifier, type );
     }
 
-    public void testInvalidPathToArtifactReference()
+    public void testGoodCommonsLang()
+        throws LayoutException
     {
-        Iterator it = getInvalidPaths().iterator();
-        while ( it.hasNext() )
-        {
-            InvalidExample example = (InvalidExample) it.next();
+        String groupId = "commons-lang";
+        String artifactId = "commons-lang";
+        String version = "2.1";
+        String classifier = null;
+        String type = "jar";
+        String path = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
+
+        assertLayout( path, groupId, artifactId, version, classifier, type );
+    }
+
+    /**
+     * Test the ejb-client type spec.
+     * Type specs are not a 1 to 1 map to the extension. 
+     * This tests that effect.
+     * @throws LayoutException 
+     */
+    public void testGoodFooEjbClient()
+        throws LayoutException
+    {
+        String groupId = "com.foo";
+        String artifactId = "foo-client";
+        String version = "1.0";
+        String classifier = null;
+        String type = "ejb-client"; // oddball type-spec (should result in jar extension)
+        String path = "com/foo/foo-client/1.0/foo-client-1.0.jar";
+
+        assertLayout( path, groupId, artifactId, version, classifier, type );
+    }
 
-            try
-            {
-                layout.toArtifactReference( example.path );
-                fail( "Should have thrown a LayoutException on the invalid path [" + example.path + "] because of ["
-                    + example.reason + "]" );
-            }
-            catch ( LayoutException e )
-            {
-                /* expected path */
-            }
-        }
+    /**
+     * Test the classifier, and java-source type spec.
+     * @throws LayoutException 
+     */
+    public void testGoodFooLibSources()
+        throws LayoutException
+    {
+        String groupId = "com.foo.lib";
+        String artifactId = "foo-lib";
+        String version = "2.1-alpha-1";
+        String classifier = "sources";
+        String type = "java-source"; // oddball type-spec (should result in jar extension)
+        String path = "com/foo/lib/foo-lib/2.1-alpha-1/foo-lib-2.1-alpha-1-sources.jar";
+
+        assertLayout( path, groupId, artifactId, version, classifier, type );
     }
 
-    public void testInvalidPathToVersionedReference()
+    /**
+     * A timestamped versioned artifact, should reside in a SNAPSHOT baseversion directory.
+     * @throws LayoutException 
+     */
+    public void testGoodSnapshotMavenTest()
+        throws LayoutException
     {
-        Iterator it = getInvalidPaths().iterator();
-        while ( it.hasNext() )
-        {
-            InvalidExample example = (InvalidExample) it.next();
+        String groupId = "org.apache.archiva.test";
+        String artifactId = "redonkulous";
+        String version = "3.1-beta-1-20050831.101112-42";
+        String classifier = null;
+        String type = "jar";
+        String path = "org/apache/archiva/test/redonkulous/3.1-beta-1-SNAPSHOT/redonkulous-3.1-beta-1-20050831.101112-42.jar";
 
-            try
-            {
-                layout.toVersionedReference( example.path );
-                if ( example.hasFilename )
-                {
-                    fail( "Should have thrown a LayoutException on the invalid path [" + example.path
-                        + "] because of [" + example.reason + "]" );
-                }
-            }
-            catch ( LayoutException e )
-            {
-                /* expected path */
-            }
-        }
+        assertLayout( path, groupId, artifactId, version, classifier, type );
     }
 
-    public void testInvalidPathToProjectReference()
+    public void testToArtifactOnEmptyPath()
     {
-        Iterator it = getInvalidPaths().iterator();
-        while ( it.hasNext() )
+        try
         {
-            InvalidExample example = (InvalidExample) it.next();
-
-            try
-            {
-                layout.toProjectReference( example.path );
-                if ( example.hasFilename )
-                {
-                    fail( "Should have thrown a LayoutException on the invalid path [" + example.path
-                        + "] because of [" + example.reason + "]" );
-                }
-            }
-            catch ( LayoutException e )
-            {
-                /* expected path */
-            }
+            layout.toArtifact( "" );
+            fail( "Should have failed due to empty path." );
+        }
+        catch ( LayoutException e )
+        {
+            /* expected path */
         }
     }
 
-    public void testPathToArtifact()
-        throws LayoutException
+    public void testToArtifactOnNullPath()
     {
-        Iterator it = getGoodExamples().iterator();
-        while ( it.hasNext() )
+        try
         {
-            LayoutExample example = (LayoutExample) it.next();
-            if ( example.isSuitableForArtifactTest() )
-            {
-                ArchivaArtifact artifact = layout.toArtifact( example.pathArtifact );
-                assertArtifact( artifact, example.groupId, example.artifactId, example.version, example.classifier,
-                                example.type );
-            }
+            layout.toArtifact( null );
+            fail( "Should have failed due to null path." );
+        }
+        catch ( LayoutException e )
+        {
+            /* expected path */
         }
     }
 
-    public void testPathToArtifactReference()
-        throws LayoutException
+    public void testToArtifactReferenceOnEmptyPath()
     {
-        Iterator it = getGoodExamples().iterator();
-        while ( it.hasNext() )
+        try
         {
-            LayoutExample example = (LayoutExample) it.next();
-            if ( example.isSuitableForArtifactTest() )
-            {
-                ArtifactReference reference = layout.toArtifactReference( example.pathArtifact );
-                assertArtifactReference( reference, example.groupId, example.artifactId, example.version,
-                                         example.classifier, example.type );
-            }
+            layout.toArtifactReference( "" );
+            fail( "Should have failed due to empty path." );
+        }
+        catch ( LayoutException e )
+        {
+            /* expected path */
         }
     }
 
-    public void testPathToVersionedReference()
-        throws LayoutException
+    public void testToArtifactReferenceOnNullPath()
     {
-        Iterator it = getGoodExamples().iterator();
-        while ( it.hasNext() )
+        try
         {
-            LayoutExample example = (LayoutExample) it.next();
-            if ( example.isSuitableForVersionedTest() )
-            {
-                VersionedReference reference = layout.toVersionedReference( example.pathVersiond );
-                
-                String baseVersion = reference.getVersion();
-
-                assertVersionedReference( reference, example.groupId, example.artifactId, baseVersion );
-            }
+            layout.toArtifactReference( null );
+            fail( "Should have failed due to null path." );
+        }
+        catch ( LayoutException e )
+        {
+            /* expected path */
         }
     }
 
-    public void testPathToProjectReference()
-        throws LayoutException
+    public void testToPathOnNullArtifactReference()
     {
-        Iterator it = getGoodExamples().iterator();
-        while ( it.hasNext() )
+        try
         {
-            LayoutExample example = (LayoutExample) it.next();
-            if ( example.isSuitableForProjectTest() )
-            {
-                ProjectReference reference = layout.toProjectReference( example.pathProjectd );
-
-                assertProjectReference( reference, example.groupId, example.artifactId );
-            }
+            ArtifactReference reference = null;
+            layout.toPath( reference );
+            fail( "Should have failed due to null artifact reference." );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            /* expected path */
         }
     }
 
-    public void testRoundtripArtifactToPathToArtifact()
-        throws LayoutException
+    public void testToPathOnNullArtifact()
     {
-        Iterator it = getGoodExamples().iterator();
-        while ( it.hasNext() )
+        try
         {
-            LayoutExample example = (LayoutExample) it.next();
-            if ( example.isSuitableForArtifactTest() )
-            {
-                ArchivaArtifact artifact = createArtifact( example.groupId, example.artifactId, example.version,
-                                                           example.classifier, example.type );
-                String testPath = layout.toPath( artifact );
-                assertEquals( "Artifact <" + artifact + "> to path:", example.pathArtifact, testPath );
-                ArchivaArtifact testArtifact = layout.toArtifact( testPath );
-                assertArtifact( testArtifact, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(),
-                                artifact.getClassifier(), artifact.getType() );
-            }
+            ArchivaArtifact artifact = null;
+            layout.toPath( artifact );
+            fail( "Should have failed due to null artifact." );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            /* expected path */
         }
     }
 
-    public void testRoundtripPathToArtifactToPath()
-        throws LayoutException
+    protected void assertBadPath( String path, String reason )
     {
-        Iterator it = getGoodExamples().iterator();
-        while ( it.hasNext() )
+        try
         {
-            LayoutExample example = (LayoutExample) it.next();
-            if ( example.isSuitableForArtifactTest() )
-            {
-                ArchivaArtifact artifact = layout.toArtifact( example.pathArtifact );
-                assertArtifact( artifact, example.groupId, example.artifactId, example.version, example.classifier,
-                                example.type );
-                String testPath = layout.toPath( artifact );
-                assertEquals( "Artifact <" + artifact + "> to path:", example.pathArtifact, testPath );
-            }
+            layout.toArtifact( path );
+            fail( "Should have thrown a LayoutException on the invalid path [" + path + "] because of [" + reason + "]" );
+        }
+        catch ( LayoutException e )
+        {
+            /* expected path */
         }
     }
 
-    public void testTimestampedSnapshotRoundtrip()
+    /**
+     * Perform a roundtrip through the layout routines to determine success.
+     */
+    private void assertLayout( String path, String groupId, String artifactId, String version, String classifier,
+                               String type )
         throws LayoutException
     {
-        String originalPath = "org/apache/maven/test/get-metadata-snapshot/1.0-SNAPSHOT/get-metadata-snapshot-1.0-20050831.101112-1.jar";
-        ArchivaArtifact artifact = layout.toArtifact( originalPath );
-        assertArtifact( artifact, "org.apache.maven.test", "get-metadata-snapshot", "1.0-20050831.101112-1", "", "jar" );
-
-        assertEquals( originalPath, layout.toPath( artifact ) );
-
-        ArtifactReference aref = new ArtifactReference();
-        aref.setGroupId( artifact.getGroupId() );
-        aref.setArtifactId( artifact.getArtifactId() );
-        aref.setVersion( artifact.getVersion() );
-        aref.setClassifier( artifact.getClassifier() );
-        aref.setType( artifact.getType() );
+        ArchivaArtifact expectedArtifact = createArtifact( groupId, artifactId, version, classifier, type );
+
+        // --- Artifact Tests.
+        // Artifact to Path 
+        assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, layout.toPath( expectedArtifact ) );
+
+        // Path to Artifact.
+        ArchivaArtifact testArtifact = layout.toArtifact( path );
+        assertArtifact( testArtifact, groupId, artifactId, version, classifier, type );
+
+        // And back again, using test Artifact from previous step.
+        assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, layout.toPath( testArtifact ) );
+
+        // --- Artifact Reference Tests
+
+        // Path to Artifact Reference.
+        ArtifactReference testReference = layout.toArtifactReference( path );
+        assertArtifactReference( testReference, groupId, artifactId, version, classifier, type );
 
-        assertEquals( originalPath, layout.toPath( aref ) );
+        // And back again, using test Reference from previous step.
+        assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, layout.toPath( testReference ) );
     }
 
     protected void setUp()