]> source.dussan.org Git - archiva.git/commitdiff
[MNG-1301] remove the problem reports dependency on the repository layer, start to...
authorBrett Porter <brett@apache.org>
Tue, 9 Mar 2010 04:24:32 +0000 (04:24 +0000)
committerBrett Porter <brett@apache.org>
Tue, 9 Mar 2010 04:24:32 +0000 (04:24 +0000)
git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@920649 13f79535-47bb-0310-9956-ffa450edef68

45 files changed:
archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/pom.xml
archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/maven/archiva/consumers/core/repository/AbstractRepositoryPurge.java
archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/maven/archiva/consumers/core/repository/CleanupReleasedSnapshotsRepositoryPurge.java
archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/maven/archiva/consumers/core/repository/DaysOldRepositoryPurge.java
archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/maven/archiva/consumers/core/repository/RepositoryPurgeConsumer.java
archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/maven/archiva/consumers/core/repository/RetentionCountRepositoryPurge.java
archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/maven/archiva/consumers/core/repository/AbstractRepositoryPurgeTest.java
archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/maven/archiva/consumers/core/repository/CleanupReleasedSnapshotsRepositoryPurgeTest.java
archiva-modules/archiva-base/archiva-repository-layer/pom.xml
archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/DefaultPathParser.java
archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/ManagedDefaultRepositoryContent.java
archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/events/RepositoryListener.java [deleted file]
archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/events/RepositoryListenerFactoryBean.java [deleted file]
archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/content/DefaultPathParserTest.java
archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/archiva/web/spring/RepositoryListenerFactoryBean.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/DeleteArtifactAction.java
archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml
archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/src/main/java/org/apache/archiva/web/xmlrpc/services/AdministrationServiceImpl.java
archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/src/test/java/org/apache/archiva/web/xmlrpc/services/AdministrationServiceImplTest.java
archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/storage/RepositoryPathTranslator.java
archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryListener.java [new file with mode: 0644]
archiva-modules/metadata/pom.xml
archiva-modules/metadata/test-repository/pom.xml [new file with mode: 0644]
archiva-modules/metadata/test-repository/src/main/resources/com/example/invalid-artifact.txt [new file with mode: 0644]
archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/maven-metadata.xml [new file with mode: 0644]
archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/maven-metadata.xml.md5 [new file with mode: 0644]
archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/maven-metadata.xml.sha1 [new file with mode: 0644]
archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar [new file with mode: 0644]
archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar.md5 [new file with mode: 0644]
archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar.sha1 [new file with mode: 0644]
archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.pom [new file with mode: 0644]
archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.pom.md5 [new file with mode: 0644]
archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.pom.sha1 [new file with mode: 0644]
archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/maven-metadata.xml [new file with mode: 0644]
archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/maven-metadata.xml.md5 [new file with mode: 0644]
archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/maven-metadata.xml.sha1 [new file with mode: 0644]
archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolver.java
archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryPathTranslator.java
archiva-modules/plugins/problem-reports/pom.xml
archiva-modules/plugins/problem-reports/src/main/java/org/apache/archiva/reports/RepositoryProblemEventListener.java
archiva-modules/plugins/problem-reports/src/main/java/org/apache/archiva/reports/consumers/DuplicateArtifactsConsumer.java
archiva-modules/plugins/problem-reports/src/test/java/org/apache/archiva/reports/consumers/DuplicateArtifactsConsumerTest.java [new file with mode: 0644]
archiva-modules/plugins/problem-reports/src/test/java/org/apache/archiva/reports/consumers/MockitoFactory.java [new file with mode: 0644]
archiva-modules/plugins/problem-reports/src/test/resources/META-INF/spring-context.xml [new file with mode: 0644]
pom.xml

index 8984cc7076de14d07f29cae5c46ef3fed71a134f..c3c302f937574aebbcb5516e1b39b8fd7cb3b89f 100644 (file)
@@ -18,7 +18,8 @@
   ~ under the License.
   -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>org.apache.archiva</groupId>
       <groupId>org.apache.archiva</groupId>
       <artifactId>archiva-repository-layer</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.archiva</groupId>
+      <artifactId>metadata-repository-api</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.codehaus.plexus</groupId>
       <artifactId>plexus-digest</artifactId>
     </dependency>
+
+    <!-- test dependencies -->
     <dependency>
       <groupId>org.codehaus.plexus</groupId>
       <artifactId>plexus-spring</artifactId>
       <scope>test</scope>
     </dependency>
-
-    <!-- test dependencies -->
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-simple</artifactId>
index f0ae08c2d1922b9feb6565da1b686f95e3a2154f..9ec6c8e5a44a321fee485ca7e3930f69b019c3d1 100644 (file)
@@ -19,18 +19,18 @@ package org.apache.maven.archiva.consumers.core.repository;
  * under the License.
  */
 
-import java.io.File;
-import java.io.FilenameFilter;
-import java.util.List;
-import java.util.Set;
-
+import org.apache.archiva.repository.events.RepositoryListener;
 import org.apache.maven.archiva.model.ArtifactReference;
 import org.apache.maven.archiva.repository.ManagedRepositoryContent;
 import org.apache.maven.archiva.repository.audit.AuditEvent;
-import org.apache.maven.archiva.repository.events.RepositoryListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.List;
+import java.util.Set;
+
 /**
  * Base class for all repository purge tasks.
  * 
@@ -67,6 +67,7 @@ public abstract class AbstractRepositoryPurge
             {   
                 File artifactFile = repository.toFile( reference );
 
+                // TODO: looks incomplete, might not delete related metadata?
                 for ( RepositoryListener listener : listeners )
                 {
                     listener.deleteArtifact( repository.getId(), reference.getGroupId(), reference.getArtifactId(),
index 44ca8caa1543b1a3a19b68bf20597dc6f46fe8ae..a242e2e8c0e881cf1f813818e3555bb9186592de 100644 (file)
@@ -19,12 +19,7 @@ package org.apache.maven.archiva.consumers.core.repository;
  * under the License.
  */
 
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
+import org.apache.archiva.repository.events.RepositoryListener;
 import org.apache.maven.archiva.common.utils.VersionComparator;
 import org.apache.maven.archiva.common.utils.VersionUtil;
 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
@@ -38,11 +33,16 @@ import org.apache.maven.archiva.repository.ManagedRepositoryContent;
 import org.apache.maven.archiva.repository.RepositoryContentFactory;
 import org.apache.maven.archiva.repository.RepositoryException;
 import org.apache.maven.archiva.repository.RepositoryNotFoundException;
-import org.apache.maven.archiva.repository.events.RepositoryListener;
 import org.apache.maven.archiva.repository.layout.LayoutException;
 import org.apache.maven.archiva.repository.metadata.MetadataTools;
 import org.apache.maven.archiva.repository.metadata.RepositoryMetadataException;
 
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 /**
  * <p>
  * This will look in a single managed repository, and purge any snapshots that are present
@@ -174,7 +174,7 @@ public class CleanupReleasedSnapshotsRepositoryPurge
                     versionRef.setVersion( version );
                     repository.deleteVersion( versionRef );
                     
-                    // TODO: looks incomplete, might not delete related artifacts?
+                    // TODO: looks incomplete, might not delete related metadata?
                     for ( RepositoryListener listener : listeners )
                     {
                         listener.deleteArtifact( repository.getId(), artifact.getGroupId(), artifact.getArtifactId(),
index bdca2646efe168ee06e1a33d7a2e73c5de91393f..7f15d59128932f17e70896515f40151684ba93b2 100644 (file)
@@ -19,6 +19,16 @@ package org.apache.maven.archiva.consumers.core.repository;
  * under the License.
  */
 
+import org.apache.archiva.repository.events.RepositoryListener;
+import org.apache.commons.lang.time.DateUtils;
+import org.apache.maven.archiva.common.utils.VersionComparator;
+import org.apache.maven.archiva.common.utils.VersionUtil;
+import org.apache.maven.archiva.model.ArtifactReference;
+import org.apache.maven.archiva.model.VersionedReference;
+import org.apache.maven.archiva.repository.ContentNotFoundException;
+import org.apache.maven.archiva.repository.ManagedRepositoryContent;
+import org.apache.maven.archiva.repository.layout.LayoutException;
+
 import java.io.File;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -30,16 +40,6 @@ import java.util.List;
 import java.util.Set;
 import java.util.regex.Matcher;
 
-import org.apache.commons.lang.time.DateUtils;
-import org.apache.maven.archiva.common.utils.VersionComparator;
-import org.apache.maven.archiva.common.utils.VersionUtil;
-import org.apache.maven.archiva.model.ArtifactReference;
-import org.apache.maven.archiva.model.VersionedReference;
-import org.apache.maven.archiva.repository.ContentNotFoundException;
-import org.apache.maven.archiva.repository.ManagedRepositoryContent;
-import org.apache.maven.archiva.repository.events.RepositoryListener;
-import org.apache.maven.archiva.repository.layout.LayoutException;
-
 /**
  * Purge from repository all snapshots older than the specified days in the repository configuration.
  * 
index c71de5ca22b722dd177d7555861e38f39681a26c..bcdc5c5fa6bcd42696c74a11a416ebe1c3b03a1d 100644 (file)
@@ -19,11 +19,7 @@ package org.apache.maven.archiva.consumers.core.repository;
  * under the License.
  */
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-
+import org.apache.archiva.repository.events.RepositoryListener;
 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
 import org.apache.maven.archiva.configuration.ConfigurationNames;
 import org.apache.maven.archiva.configuration.FileTypes;
@@ -35,13 +31,17 @@ import org.apache.maven.archiva.repository.ManagedRepositoryContent;
 import org.apache.maven.archiva.repository.RepositoryContentFactory;
 import org.apache.maven.archiva.repository.RepositoryException;
 import org.apache.maven.archiva.repository.RepositoryNotFoundException;
-import org.apache.maven.archiva.repository.events.RepositoryListener;
 import org.apache.maven.archiva.repository.metadata.MetadataTools;
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
 import org.codehaus.plexus.registry.Registry;
 import org.codehaus.plexus.registry.RegistryListener;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
 /**
  * Consumer for removing old snapshots in the repository based on the criteria
  * specified by the user.
@@ -94,7 +94,7 @@ public class RepositoryPurgeConsumer
 
     private boolean deleteReleasedSnapshots;
 
-    /** @plexus.requirement role="org.apache.maven.archiva.repository.events.RepositoryListener" */
+    /** @plexus.requirement role="org.apache.archiva.repository.events.RepositoryListener" */
     private List<RepositoryListener> listeners = Collections.emptyList();
     
     public String getId()
index 9ff3d44cee3a8a6b6e01425c019ce1c531f11050..d7798758cc11f25ab1e07d49a4fde2d1020bda1d 100644 (file)
@@ -19,21 +19,21 @@ package org.apache.maven.archiva.consumers.core.repository;
  * under the License.
  */
 
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
+import org.apache.archiva.repository.events.RepositoryListener;
 import org.apache.maven.archiva.common.utils.VersionComparator;
 import org.apache.maven.archiva.common.utils.VersionUtil;
 import org.apache.maven.archiva.model.ArtifactReference;
 import org.apache.maven.archiva.model.VersionedReference;
 import org.apache.maven.archiva.repository.ContentNotFoundException;
 import org.apache.maven.archiva.repository.ManagedRepositoryContent;
-import org.apache.maven.archiva.repository.events.RepositoryListener;
 import org.apache.maven.archiva.repository.layout.LayoutException;
 
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
 /**
  * Purge the repository by retention count. Retain only the specified number of snapshots.
  *
index e59ee05ea1981627b32b932435e8d84c02a7a326..6ef310fbc3c0b322023c9fda3e2d3b273e485161 100644 (file)
@@ -19,17 +19,17 @@ package org.apache.maven.archiva.consumers.core.repository;
  * under the License.
  */
 
-import java.io.File;
-import java.io.IOException;
-
+import org.apache.archiva.repository.events.RepositoryListener;
 import org.apache.commons.io.FileUtils;
 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
 import org.apache.maven.archiva.model.ArchivaArtifact;
 import org.apache.maven.archiva.repository.ManagedRepositoryContent;
-import org.apache.maven.archiva.repository.events.RepositoryListener;
 import org.codehaus.plexus.spring.PlexusInSpringTestCase;
 import org.easymock.MockControl;
 
+import java.io.File;
+import java.io.IOException;
+
 /**
  */
 public abstract class AbstractRepositoryPurgeTest
index fb04112cf2ed702bd1c4f0248a5cef809808cedb..01b771d461f3718305d18adf885ec5b64f1d0d1b 100644 (file)
@@ -19,18 +19,18 @@ package org.apache.maven.archiva.consumers.core.repository;
  * under the License.
  */
 
-import java.io.File;
-import java.util.Collections;
-
+import org.apache.archiva.repository.events.RepositoryListener;
 import org.apache.commons.io.FileUtils;
 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
 import org.apache.maven.archiva.configuration.Configuration;
 import org.apache.maven.archiva.repository.RepositoryContentFactory;
-import org.apache.maven.archiva.repository.events.RepositoryListener;
 import org.apache.maven.archiva.repository.metadata.MetadataTools;
 import org.custommonkey.xmlunit.XMLAssert;
 import org.easymock.MockControl;
 
+import java.io.File;
+import java.util.Collections;
+
 
 /**
  */
index 041f1e919249035ca26d0c4bbd92e94a233add4d..bfc9dc68a471ba6ed545e37c0e45209d0ee3c88c 100644 (file)
       <groupId>org.apache.archiva</groupId>
       <artifactId>metadata-model</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.archiva</groupId>
+      <artifactId>maven2-repository</artifactId>
+      <exclusions>
+        <exclusion>
+          <groupId>org.apache.archiva</groupId>
+          <artifactId>problem-reports</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
   </dependencies>
   <build>
     <plugins>
index 42ca3c1f99ef98f7848cc3f0bf5b50622cd5c9de..b9e6c674a5d2bf58beb042513ee2aca86975932e 100644 (file)
@@ -19,6 +19,9 @@ package org.apache.maven.archiva.repository.content;
  * under the License.
  */
 
+import org.apache.archiva.metadata.model.ArtifactMetadata;
+import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
+import org.apache.archiva.metadata.repository.storage.maven2.Maven2RepositoryPathTranslator;
 import org.apache.commons.lang.StringUtils;
 import org.apache.maven.archiva.common.utils.VersionUtil;
 import org.apache.maven.archiva.model.ArtifactReference;
@@ -27,12 +30,16 @@ import org.apache.maven.archiva.repository.layout.LayoutException;
 /**
  * DefaultPathParser is a parser for maven 2 (default layout) paths to ArtifactReference.
  *
+ * TODO: remove in favour of path translator, this is just delegating for the most part
+ *
  * @version $Id$
  */
 public class DefaultPathParser implements PathParser
 {
     private static final String INVALID_ARTIFACT_PATH = "Invalid path to Artifact: ";
 
+    private RepositoryPathTranslator pathTranslator = new Maven2RepositoryPathTranslator();
+
     /**
      * {@inheritDoc}
      * @see org.apache.maven.archiva.repository.content.PathParser#toArtifactReference(java.lang.String)
@@ -45,133 +52,78 @@ public class DefaultPathParser implements PathParser
             throw new LayoutException( "Unable to convert blank path." );
         }
 
-        ArtifactReference artifact = new ArtifactReference();
-
-        String normalizedPath = StringUtils.replace( path, "\\", "/" );
-        String pathParts[] = StringUtils.split( normalizedPath, '/' );
-
-        /* Minimum parts.
-         *
-         *   path = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar"
-         *   path[0] = "commons-lang";        // The Group ID
-         *   path[1] = "commons-lang";        // The Artifact ID
-         *   path[2] = "2.1";                 // The Version
-         *   path[3] = "commons-lang-2.1.jar" // The filename.
-         */
-
-        if ( pathParts.length < 4 )
+        ArtifactMetadata metadata;
+        try
         {
-            // Illegal Path Parts Length.
-            throw new LayoutException( "Not enough parts to the path [" + path
-                + "] to construct an ArchivaArtifact from. (Requires at least 4 parts)" );
+            metadata = pathTranslator.getArtifactForPath( null, path );
         }
-
-        // Maven 2.x path.
-        int partCount = pathParts.length;
-        int filenamePos = partCount - 1;
-        int baseVersionPos = partCount - 2;
-        int artifactIdPos = partCount - 3;
-        int groupIdPos = partCount - 4;
-
-        // Second to last is the baseVersion (the directory version)
-        String baseVersion = pathParts[baseVersionPos];
-
-        // Third to last is the artifact Id.
-        artifact.setArtifactId( pathParts[artifactIdPos] );
-
-        // Remaining pieces are the groupId.
-        for ( int i = 0; i <= groupIdPos; i++ )
+        catch ( IllegalArgumentException e )
         {
-            if ( i == 0 )
-            {
-                artifact.setGroupId( pathParts[i] );
-            }
-            else
-            {
-                artifact.setGroupId( artifact.getGroupId() + "." + pathParts[i] );
-            }
+            throw new LayoutException( e.getMessage(), e );
         }
 
-        try
+        ArtifactReference artifact = new ArtifactReference();
+        artifact.setGroupId( metadata.getNamespace() );
+        artifact.setArtifactId( metadata.getProject() );
+        artifact.setVersion( metadata.getVersion() );
+
+        // TODO: use Maven facet instead
+        String filename = metadata.getId();
+        FilenameParser parser = new FilenameParser( filename );
+        artifact.setArtifactId( parser.expect( artifact.getArtifactId() ) );
+        if ( artifact.getArtifactId() == null )
         {
-            // Last part is the filename
-            String filename = pathParts[filenamePos];
-
-            // Now we need to parse the filename to get the artifact version Id.
-            if ( StringUtils.isBlank( filename ) )
+            throw new LayoutException( INVALID_ARTIFACT_PATH + "filename format is invalid, "
+                + "should start with artifactId as stated in path." );
+        }
+        String baseVersion = VersionUtil.getBaseVersion( metadata.getVersion() );
+        artifact.setVersion( parser.expect( baseVersion ) );
+        if ( artifact.getVersion() == null )
+        {
+            // We working with a snapshot?
+            if ( VersionUtil.isSnapshot( baseVersion ) )
             {
-                throw new IllegalArgumentException( INVALID_ARTIFACT_PATH + "Unable to split blank filename." );
+                artifact.setVersion( parser.nextVersion() );
+                if ( !VersionUtil.isUniqueSnapshot( artifact.getVersion() ) )
+                {
+                    throw new LayoutException( INVALID_ARTIFACT_PATH + "filename format is invalid,"
+                        + "expected timestamp format in filename." );
+                }
             }
-
-            FilenameParser parser = new FilenameParser( filename );
-
-            // Expect the filename to start with the artifactId.
-            artifact.setArtifactId( parser.expect( artifact.getArtifactId() ) );
-
-            if ( artifact.getArtifactId() == null )
+            else
             {
                 throw new LayoutException( INVALID_ARTIFACT_PATH + "filename format is invalid, "
-                    + "should start with artifactId as stated in path." );
+                    + "expected version as stated in path." );
             }
-
-            // Process the version.
-            artifact.setVersion( parser.expect( baseVersion ) );
-
-            if ( artifact.getVersion() == null )
-            {
-                // We working with a snapshot?
-                if ( VersionUtil.isSnapshot( baseVersion ) )
-                {
-                    artifact.setVersion( parser.nextVersion() );
-                    if ( !VersionUtil.isUniqueSnapshot( artifact.getVersion() ) )
-                    {
-                        throw new LayoutException( INVALID_ARTIFACT_PATH + "filename format is invalid,"
-                            + "expected timestamp format in filename." );
-                    }
-                }
-                else
+        }
+        switch(parser.seperator())
+        {
+            case '-':
+                // Definately a classifier.
+                artifact.setClassifier( parser.remaining() );
+
+                // Set the type.
+                artifact.setType( ArtifactExtensionMapping.mapExtensionAndClassifierToType( artifact.getClassifier(), parser.getExtension() ) );
+                break;
+            case '.':
+                // We have an dual extension possibility.
+                String extension = parser.remaining() + '.' + parser.getExtension();
+                artifact.setType( extension );
+                break;
+            case 0:
+                // End of the filename, only a simple extension left. - Set the type.
+                String type = ArtifactExtensionMapping.mapExtensionToType( parser.getExtension() );
+                if ( type == null )
                 {
-                    throw new LayoutException( INVALID_ARTIFACT_PATH + "filename format is invalid, "
-                        + "expected version as stated in path." );
+                    throw new LayoutException( "Invalid artifact: no type was specified" );
                 }
-            }
-
-            // Do we have a classifier?
-            switch(parser.seperator())
-            {
-                case '-':
-                    // Definately a classifier.
-                    artifact.setClassifier( parser.remaining() );
-
-                    // Set the type.
-                    artifact.setType( ArtifactExtensionMapping.mapExtensionAndClassifierToType( artifact.getClassifier(), parser.getExtension() ) );
-                    break;
-                case '.':
-                    // We have an dual extension possibility.
-                    String extension = parser.remaining() + '.' + parser.getExtension();
-                    artifact.setType( extension );
-                    break;
-                case 0:
-                    // End of the filename, only a simple extension left. - Set the type.
-                    String type = ArtifactExtensionMapping.mapExtensionToType( parser.getExtension() );
-                    if ( type == null )
-                    {
-                        throw new LayoutException( "Invalid artifact: no type was specified" );
-                    }
-                    artifact.setType( type );
-                    break;
-            }
-
-            // Special case for maven plugins
-            if ( StringUtils.equals( "jar", artifact.getType() ) &&
-                 ArtifactExtensionMapping.isMavenPlugin( artifact.getArtifactId() ) )
-            {
-                artifact.setType( ArtifactExtensionMapping.MAVEN_PLUGIN );
-            }
+                artifact.setType( type );
+                break;
         }
-        catch ( LayoutException e )
+        if ( StringUtils.equals( "jar", artifact.getType() ) &&
+             ArtifactExtensionMapping.isMavenPlugin( artifact.getArtifactId() ) )
         {
-            throw e;
+            artifact.setType( ArtifactExtensionMapping.MAVEN_PLUGIN );
         }
 
         // Sanity Checks.
@@ -187,16 +139,6 @@ public class DefaultPathParser implements PathParser
                     + filenameBaseVersion );
             }
         }
-        else
-        {
-            // Non SNAPSHOT rules.
-            // Do we pass the simple test?
-            if ( !StringUtils.equals( baseVersion, artifact.getVersion() ) )
-            {
-                throw new LayoutException( "Invalid artifact: version declared in directory path does"
-                    + " not match what was found in the artifact filename." );
-            }
-        }
 
         return artifact;
     }
index 54f9b44aaed3ede3705e4590af1e7f56660eb45f..a000748a1ff52bbba07d740bda7c9778dc60a4d7 100644 (file)
@@ -19,11 +19,6 @@ package org.apache.maven.archiva.repository.content;
  * under the License.
  */
 
-import java.io.File;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-
 import org.apache.commons.io.FileUtils;
 import org.apache.maven.archiva.common.utils.PathUtil;
 import org.apache.maven.archiva.configuration.FileTypes;
@@ -36,6 +31,11 @@ import org.apache.maven.archiva.repository.ContentNotFoundException;
 import org.apache.maven.archiva.repository.ManagedRepositoryContent;
 import org.apache.maven.archiva.repository.layout.LayoutException;
 
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * ManagedDefaultRepositoryContent 
  *
@@ -332,9 +332,9 @@ public class ManagedDefaultRepositoryContent
     public ArtifactReference toArtifactReference( String path )
         throws LayoutException
     {
-        if ( ( path != null ) && path.startsWith( repository.getLocation() ) )
+        if ( ( path != null ) && path.startsWith( repository.getLocation() ) && repository.getLocation().length() > 0 )
         {
-            return super.toArtifactReference( path.substring( repository.getLocation().length() ) );
+            return super.toArtifactReference( path.substring( repository.getLocation().length() + 1 ) );
         }
 
         return super.toArtifactReference( path );
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/events/RepositoryListener.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/events/RepositoryListener.java
deleted file mode 100644 (file)
index 838a309..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.apache.maven.archiva.repository.events;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * Listen to events on the repository. This class is a stopgap 
- * refactoring measure until an event bus is in place to handle 
- * generic events such as these.
- */
-public interface RepositoryListener 
-{
-    /**
-     * Event for the deletion of a given artifact.
-     */
-    void deleteArtifact( String repositoryId, String namespace, String project, String version, String id );
-}
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/events/RepositoryListenerFactoryBean.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/events/RepositoryListenerFactoryBean.java
deleted file mode 100644 (file)
index cfd48c3..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.apache.maven.archiva.repository.events;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.List;
-
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-
-/**
- * @todo though we will eventually remove this altogether, an interim cleanup would be to genericise this
- * and replace the calls in RepositoryContentConsumers with calls to the same thing
- */
-public class RepositoryListenerFactoryBean
-    implements FactoryBean, ApplicationContextAware
-{
-
-    private ApplicationContext applicationContext;
-
-    public void setApplicationContext( ApplicationContext applicationContext )
-        throws BeansException
-    {
-        this.applicationContext = applicationContext;
-    }
-
-    public Object getObject()
-        throws Exception
-    {
-        return applicationContext.getBeansOfType( RepositoryListener.class ).values();
-    }
-
-    @SuppressWarnings("unchecked")
-    public Class<List> getObjectType()
-    {
-        return List.class;
-    }
-
-    public boolean isSingleton()
-    {
-        return true;
-    }
-
-    
-}
index e3b6d5c98913f637607758dfefaeb058092393ce..bb8fcbd38ad3f6d0ff0f87b8d8f39732ebf9ee2e 100644 (file)
@@ -195,6 +195,19 @@ public class DefaultPathParserTest
         assertLayout( path, groupId, artifactId, version, classifier, type );
     }
 
+    public void testWindowsPathSeparator()
+        throws LayoutException
+    {
+        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 );
+    }
+
     /**
      * [MRM-486] Can not deploy artifact test.maven-arch:test-arch due to "No ArtifactID Detected"
      */
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/archiva/web/spring/RepositoryListenerFactoryBean.java b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/archiva/web/spring/RepositoryListenerFactoryBean.java
new file mode 100644 (file)
index 0000000..5822902
--- /dev/null
@@ -0,0 +1,64 @@
+package org.apache.archiva.web.spring;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.repository.events.RepositoryListener;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+import java.util.List;
+
+/**
+ * @todo though we will eventually remove this altogether, an interim cleanup would be to genericise this
+ * and replace the calls in RepositoryContentConsumers with calls to the same thing
+ */
+public class RepositoryListenerFactoryBean
+    implements FactoryBean, ApplicationContextAware
+{
+
+    private ApplicationContext applicationContext;
+
+    public void setApplicationContext( ApplicationContext applicationContext )
+        throws BeansException
+    {
+        this.applicationContext = applicationContext;
+    }
+
+    public Object getObject()
+        throws Exception
+    {
+        return applicationContext.getBeansOfType( RepositoryListener.class ).values();
+    }
+
+    @SuppressWarnings("unchecked")
+    public Class<List> getObjectType()
+    {
+        return List.class;
+    }
+
+    public boolean isSingleton()
+    {
+        return true;
+    }
+
+    
+}
index caecd1e377a915bc4c3b4eeafd124d8a6041d4c0..aae9ac6924213f4297ab8a94e508913e1102ffa9 100644 (file)
@@ -19,23 +19,13 @@ package org.apache.maven.archiva.web.action;
  * under the License.
  */
 
-import java.io.File;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.TimeZone;
-
 import com.opensymphony.xwork2.Preparable;
 import com.opensymphony.xwork2.Validateable;
 import org.apache.archiva.checksum.ChecksumAlgorithm;
 import org.apache.archiva.checksum.ChecksummedFile;
 import org.apache.archiva.metadata.model.ArtifactMetadata;
 import org.apache.archiva.metadata.repository.MetadataRepository;
+import org.apache.archiva.repository.events.RepositoryListener;
 import org.apache.maven.archiva.common.utils.VersionComparator;
 import org.apache.maven.archiva.common.utils.VersionUtil;
 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
@@ -49,7 +39,6 @@ import org.apache.maven.archiva.repository.RepositoryException;
 import org.apache.maven.archiva.repository.RepositoryNotFoundException;
 import org.apache.maven.archiva.repository.audit.AuditEvent;
 import org.apache.maven.archiva.repository.audit.Auditable;
-import org.apache.maven.archiva.repository.events.RepositoryListener;
 import org.apache.maven.archiva.repository.metadata.MetadataTools;
 import org.apache.maven.archiva.repository.metadata.RepositoryMetadataException;
 import org.apache.maven.archiva.repository.metadata.RepositoryMetadataReader;
@@ -59,6 +48,17 @@ import org.apache.maven.archiva.security.ArchivaSecurityException;
 import org.apache.maven.archiva.security.PrincipalNotFoundException;
 import org.apache.maven.archiva.security.UserRepositories;
 
+import java.io.File;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+
 /**
  * Delete an artifact. Metadata will be updated if one exists, otherwise it would be created.
  *
@@ -109,7 +109,7 @@ public class DeleteArtifactAction
     private RepositoryContentFactory repositoryFactory;
 
     /**
-     * @plexus.requirement role="org.apache.maven.archiva.repository.events.RepositoryListener"
+     * @plexus.requirement role="org.apache.archiva.repository.events.RepositoryListener"
      */
     private List<RepositoryListener> listeners;
 
index 3973bb8ac9480ca83da99a2d4c1dfae5f74ea482..217d366ca07317c81fa1aaaab704102ef12bec84 100644 (file)
@@ -55,7 +55,7 @@
     <constructor-arg ref="metadataRepository"/>
     <constructor-arg ref="archivaTaskScheduler#repository"/>
     <constructor-arg>
-      <bean class="org.apache.maven.archiva.repository.events.RepositoryListenerFactoryBean" />
+      <bean class="org.apache.archiva.web.spring.RepositoryListenerFactoryBean" />
     </constructor-arg>       
   </bean> 
 
index 9a2f51fa23fe37dc3935ff24aa3e69f918f898d3..379288c116c79373969a527423fce111e8a43b7f 100644 (file)
@@ -19,12 +19,9 @@ package org.apache.archiva.web.xmlrpc.services;
  * under the License.
  */
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
 import org.apache.archiva.metadata.model.ArtifactMetadata;
 import org.apache.archiva.metadata.repository.MetadataRepository;
+import org.apache.archiva.repository.events.RepositoryListener;
 import org.apache.archiva.repository.scanner.RepositoryContentConsumers;
 import org.apache.archiva.scheduler.repository.RepositoryArchivaTaskScheduler;
 import org.apache.archiva.scheduler.repository.RepositoryTask;
@@ -45,11 +42,14 @@ import org.apache.maven.archiva.repository.ManagedRepositoryContent;
 import org.apache.maven.archiva.repository.RepositoryContentFactory;
 import org.apache.maven.archiva.repository.RepositoryException;
 import org.apache.maven.archiva.repository.RepositoryNotFoundException;
-import org.apache.maven.archiva.repository.events.RepositoryListener;
 import org.codehaus.plexus.registry.RegistryException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
 /**
  * AdministrationServiceImpl
  *
index 3102257725d8475412eee913ae5bfc015346e41d..d0a3e937741fc3e4beefccee433a6cc1dcd84bc5 100644 (file)
@@ -19,14 +19,9 @@ package org.apache.archiva.web.xmlrpc.services;
  * under the License.
  */
 
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 import org.apache.archiva.metadata.model.ArtifactMetadata;
 import org.apache.archiva.metadata.repository.MetadataRepository;
+import org.apache.archiva.repository.events.RepositoryListener;
 import org.apache.archiva.repository.scanner.RepositoryContentConsumers;
 import org.apache.archiva.scheduler.repository.RepositoryArchivaTaskScheduler;
 import org.apache.archiva.scheduler.repository.RepositoryTask;
@@ -47,12 +42,17 @@ import org.apache.maven.archiva.repository.RepositoryContentFactory;
 import org.apache.maven.archiva.repository.content.ManagedDefaultRepositoryContent;
 import org.apache.maven.archiva.repository.content.ManagedLegacyRepositoryContent;
 import org.apache.maven.archiva.repository.content.PathParser;
-import org.apache.maven.archiva.repository.events.RepositoryListener;
 import org.apache.maven.archiva.repository.layout.LayoutException;
 import org.codehaus.plexus.spring.PlexusInSpringTestCase;
 import org.easymock.MockControl;
 import org.easymock.classextension.MockClassControl;
 
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 /**
  * AdministrationServiceImplTest
  * 
index c877ec8ec1b0b86fd6ca01ccdaf44cfd0d42d82e..ee9358219ddc05ea1cc88dc3f34a707e94df03b8 100644 (file)
@@ -19,6 +19,8 @@ package org.apache.archiva.metadata.repository.storage;
  * under the License.
  */
 
+import org.apache.archiva.metadata.model.ArtifactMetadata;
+
 import java.io.File;
 
 public interface RepositoryPathTranslator
@@ -32,4 +34,9 @@ public interface RepositoryPathTranslator
     File toFile( File basedir, String namespace );
 
     File toFile( File basedir, String namespace, String projectId, String projectVersion );
+
+    ArtifactMetadata getArtifactForPath( String repoId, String relativePath );
+
+    ArtifactMetadata getArtifactFromId( String repoId, String namespace, String projectId, String projectVersion,
+                                        String id );
 }
diff --git a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryListener.java b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryListener.java
new file mode 100644 (file)
index 0000000..2978d1a
--- /dev/null
@@ -0,0 +1,33 @@
+package org.apache.archiva.repository.events;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Listen to events on the repository. This class is a stopgap 
+ * refactoring measure until an event bus is in place to handle 
+ * generic events such as these.
+ */
+public interface RepositoryListener 
+{
+    /**
+     * Event for the deletion of a given artifact.
+     */
+    void deleteArtifact( String repositoryId, String namespace, String project, String version, String id );
+}
index 646612a4517fb1136c18fa1fd06ad261b483da45..fc3c88642b9e5c3db4d073014bf678fc828bcd4a 100644 (file)
@@ -29,5 +29,6 @@
   <modules>
     <module>metadata-model</module>
     <module>metadata-repository-api</module>
+    <module>test-repository</module>
   </modules>
-</project>
+</project>
\ No newline at end of file
diff --git a/archiva-modules/metadata/test-repository/pom.xml b/archiva-modules/metadata/test-repository/pom.xml
new file mode 100644 (file)
index 0000000..2755b31
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>metadata</artifactId>
+    <groupId>org.apache.archiva</groupId>
+    <version>1.4-SNAPSHOT</version>
+  </parent>
+  <artifactId>test-repository</artifactId>
+  <name>Archiva Repository for Testing</name>
+</project>
diff --git a/archiva-modules/metadata/test-repository/src/main/resources/com/example/invalid-artifact.txt b/archiva-modules/metadata/test-repository/src/main/resources/com/example/invalid-artifact.txt
new file mode 100644 (file)
index 0000000..acfe113
--- /dev/null
@@ -0,0 +1 @@
+invalid path
diff --git a/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/maven-metadata.xml b/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/maven-metadata.xml
new file mode 100644 (file)
index 0000000..89f58d5
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>com.example.test</groupId>
+  <artifactId>test-artifact</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <versioning>
+    <snapshot>
+      <timestamp>20100308.230825</timestamp>
+      <buildNumber>1</buildNumber>
+    </snapshot>
+    <lastUpdated>20100308230825</lastUpdated>
+  </versioning>
+</metadata>
diff --git a/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/maven-metadata.xml.md5 b/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/maven-metadata.xml.md5
new file mode 100644 (file)
index 0000000..d774a53
--- /dev/null
@@ -0,0 +1 @@
+7210867ac16cd955db89cfca699e7c96
\ No newline at end of file
diff --git a/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/maven-metadata.xml.sha1 b/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/maven-metadata.xml.sha1
new file mode 100644 (file)
index 0000000..0e44079
--- /dev/null
@@ -0,0 +1 @@
+271faeb2039d026ee6a3c937375b5ff7d4b1d605
\ No newline at end of file
diff --git a/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar b/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar
new file mode 100644 (file)
index 0000000..dab36c0
Binary files /dev/null and b/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar differ
diff --git a/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar.md5 b/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar.md5
new file mode 100644 (file)
index 0000000..e98bc51
--- /dev/null
@@ -0,0 +1 @@
+cc2236dd70af3667080a786c7dcb4a9b
\ No newline at end of file
diff --git a/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar.sha1 b/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar.sha1
new file mode 100644 (file)
index 0000000..2d7e384
--- /dev/null
@@ -0,0 +1 @@
+edf5938e646956f445c6ecb719d44579cdeed974
\ No newline at end of file
diff --git a/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.pom b/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.pom
new file mode 100644 (file)
index 0000000..69a7d16
--- /dev/null
@@ -0,0 +1,24 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.example.test</groupId>
+  <artifactId>test-artifact</artifactId>
+  <packaging>jar</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>test-artifact</name>
+  <url>http://maven.apache.org</url>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <distributionManagement>
+    <repository>
+      <id>test-repo</id>
+      <url>file:${basedir}/repository</url>
+    </repository>
+  </distributionManagement>
+</project>
diff --git a/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.pom.md5 b/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.pom.md5
new file mode 100644 (file)
index 0000000..531fc33
--- /dev/null
@@ -0,0 +1 @@
+ce7eeb9586dc4992dc961d9f3a28006b
\ No newline at end of file
diff --git a/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.pom.sha1 b/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.pom.sha1
new file mode 100644 (file)
index 0000000..c0edca2
--- /dev/null
@@ -0,0 +1 @@
+be040c8462fd31d4e03749e3586afbb21f43594e
\ No newline at end of file
diff --git a/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/maven-metadata.xml b/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/maven-metadata.xml
new file mode 100644 (file)
index 0000000..2678fa1
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>com.example.test</groupId>
+  <artifactId>test-artifact</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <versioning>
+    <versions>
+      <version>1.0-SNAPSHOT</version>
+    </versions>
+    <lastUpdated>20100308230825</lastUpdated>
+  </versioning>
+</metadata>
diff --git a/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/maven-metadata.xml.md5 b/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/maven-metadata.xml.md5
new file mode 100644 (file)
index 0000000..3dff69b
--- /dev/null
@@ -0,0 +1 @@
+93afaac7340faadc7efd097952d79fa4
\ No newline at end of file
diff --git a/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/maven-metadata.xml.sha1 b/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/test-artifact/maven-metadata.xml.sha1
new file mode 100644 (file)
index 0000000..1ff7fb5
--- /dev/null
@@ -0,0 +1 @@
+d59d588343d61fd7d838984a0daa4aaa2546bf9d
\ No newline at end of file
index 168e3b1b5e7ed93d9f26d6a0e767505d0e8e1d36..39dc8144101797be62ddd4a3ce3363955b8fcf77 100644 (file)
@@ -60,8 +60,6 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * @plexus.component role="org.apache.archiva.metadata.repository.storage.StorageMetadataResolver" role-hint="maven2"
@@ -114,6 +112,7 @@ public class Maven2RepositoryMetadataResolver
                                                      String projectVersion )
         throws MetadataResolutionException
     {
+        // Remove problems associated with this version, since we'll be re-adding any that still exist
         // TODO: an event mechanism would remove coupling to the problem reporting plugin
         // TODO: this removes all problems - do we need something that just removes the problems created by this resolver?
         String name = RepositoryProblemFacet.createName( namespace, projectId, projectVersion, null );
@@ -490,54 +489,42 @@ public class Maven2RepositoryMetadataResolver
         {
             for ( File file : files )
             {
-                ArtifactMetadata metadata = new ArtifactMetadata();
-                metadata.setId( file.getName() );
-                metadata.setProject( projectId );
-                metadata.setNamespace( namespace );
-                metadata.setRepositoryId( repoId );
-                metadata.setWhenGathered( new Date() );
-                metadata.setFileLastModified( file.lastModified() );
-                ChecksummedFile checksummedFile = new ChecksummedFile( file );
-                try
-                {
-                    metadata.setMd5( checksummedFile.calculateChecksum( ChecksumAlgorithm.MD5 ) );
-                }
-                catch ( IOException e )
-                {
-                    log.error( "Unable to checksum file " + file + ": " + e.getMessage() );
-                }
-                try
-                {
-                    metadata.setSha1( checksummedFile.calculateChecksum( ChecksumAlgorithm.SHA1 ) );
-                }
-                catch ( IOException e )
-                {
-                    log.error( "Unable to checksum file " + file + ": " + e.getMessage() );
-                }
-                metadata.setSize( file.length() );
-
-                // TODO: very crude, migrate the functionality from the repository-layer here
-                if ( VersionUtil.isGenericSnapshot( projectVersion ) )
-                {
-                    String mainVersion = projectVersion.substring( 0, projectVersion.length() -
-                        8 ); // 8 is length of "SNAPSHOT"
-                    Matcher m = Pattern.compile(
-                        projectId + "-" + mainVersion + "([0-9]{8}.[0-9]{6}-[0-9]+).*" ).matcher( file.getName() );
-                    m.matches();
-                    String version = mainVersion + m.group( 1 );
-
-                    metadata.setVersion( version );
-                }
-                else
-                {
-                    metadata.setVersion( projectVersion );
-                }
+                ArtifactMetadata metadata = getArtifactFromFile( repoId, namespace, projectId, projectVersion, file );
                 artifacts.add( metadata );
             }
         }
         return artifacts;
     }
 
+    private ArtifactMetadata getArtifactFromFile( String repoId, String namespace, String projectId,
+                                                  String projectVersion, File file )
+    {
+        ArtifactMetadata metadata = pathTranslator.getArtifactFromId( repoId, namespace, projectId, projectVersion, file.getName() );
+
+        metadata.setWhenGathered( new Date() );
+        metadata.setFileLastModified( file.lastModified() );
+        ChecksummedFile checksummedFile = new ChecksummedFile( file );
+        try
+        {
+            metadata.setMd5( checksummedFile.calculateChecksum( ChecksumAlgorithm.MD5 ) );
+        }
+        catch ( IOException e )
+        {
+            log.error( "Unable to checksum file " + file + ": " + e.getMessage() );
+        }
+        try
+        {
+            metadata.setSha1( checksummedFile.calculateChecksum( ChecksumAlgorithm.SHA1 ) );
+        }
+        catch ( IOException e )
+        {
+            log.error( "Unable to checksum file " + file + ": " + e.getMessage() );
+        }
+        metadata.setSize( file.length() );
+
+        return metadata;
+    }
+
     private boolean isProject( File dir, Filter<String> filter )
     {
         // scan directories for a valid project version subdirectory, meaning this must be a project directory
index b92debbe4a3df27cc3789507011e47d64862ce38..acec739cf68be89edd1052d244fb845163068f26 100644 (file)
@@ -1,8 +1,14 @@
 package org.apache.archiva.metadata.repository.storage.maven2;
 
-import java.io.File;
-
+import org.apache.archiva.metadata.model.ArtifactMetadata;
 import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.archiva.common.utils.VersionUtil;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -113,4 +119,141 @@ public class Maven2RepositoryPathTranslator
     {
         return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR );
     }
+
+    private static String parseTimestampedVersionFromId( String projectId, String projectVersion, String id )
+    {
+        String mainVersion = projectVersion.substring( 0, projectVersion.length() - 8 ); // 8 is length of "SNAPSHOT"
+        if ( mainVersion.length() == 0 )
+        {
+            throw new IllegalArgumentException(
+                "Timestamped snapshots must contain the main version, filename was '" + id + "'" );
+        }
+        Matcher m = Pattern.compile( projectId + "-" + mainVersion + "([0-9]{8}.[0-9]{6}-[0-9]+).*" ).matcher( id );
+        m.matches();
+        return mainVersion + m.group( 1 );
+    }
+
+    public ArtifactMetadata getArtifactFromId( String repoId, String namespace, String projectId, String projectVersion,
+                                               String id )
+    {
+        ArtifactMetadata metadata = new ArtifactMetadata();
+        metadata.setId( id );
+        metadata.setProject( projectId );
+        metadata.setNamespace( namespace );
+        metadata.setRepositoryId( repoId );
+
+        if ( VersionUtil.isGenericSnapshot( projectVersion ) )
+        {
+            String version = parseTimestampedVersionFromId( projectId, projectVersion, id );
+
+            metadata.setVersion( version );
+        }
+        else
+        {
+            metadata.setVersion( projectVersion );
+        }
+        return metadata;
+    }
+
+    public ArtifactMetadata getArtifactForPath( String repoId, String relativePath )
+    {
+        String[] parts = relativePath.replace( '\\', '/' ).split( "/" );
+
+        int len = parts.length;
+        if ( len < 4 )
+        {
+            throw new IllegalArgumentException(
+                "Not a valid artifact path in a Maven 2 repository, not enough directories: " + relativePath );
+        }
+
+        String id = parts[--len];
+        String baseVersion = parts[--len];
+        String artifactId = parts[--len];
+        String groupId = StringUtils.join( Arrays.copyOfRange( parts, 0, len ), '.' );
+
+        if ( !id.startsWith( artifactId + "-" ) )
+        {
+            throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + id +
+                "' doesn't start with artifact ID '" + artifactId + "'" );
+        }
+
+        int index = artifactId.length() + 1;
+        String version;
+        if ( id.substring( index ).startsWith( baseVersion ) && !VersionUtil.isUniqueSnapshot( baseVersion ) )
+        {
+            // non-snapshot versions, or non-timestamped snapshot versions
+            version = baseVersion;
+        }
+        else if ( VersionUtil.isGenericSnapshot( baseVersion ) )
+        {
+            // timestamped snapshots
+            try
+            {
+                version = parseTimestampedVersionFromId( artifactId, baseVersion, id );
+            }
+            catch ( IllegalStateException e )
+            {
+                throw new IllegalArgumentException(
+                    "Not a valid artifact path in a Maven 2 repository, filename '" + id +
+                        "' doesn't contain a timestamped version matching snapshot '" + baseVersion + "'" );
+            }
+        }
+        else
+        {
+            // invalid
+            throw new IllegalArgumentException(
+                "Not a valid artifact path in a Maven 2 repository, filename '" + id + "' doesn't contain version '" +
+                    baseVersion + "'" );
+        }
+
+        String classifier;
+        String ext;
+        index += version.length();
+        if ( index == id.length() )
+        {
+            // no classifier or extension
+            classifier = null;
+            ext = null;
+        }
+        else
+        {
+            char c = id.charAt( index );
+            if ( c == '-' )
+            {
+                // classifier up until last '.'
+                int extIndex = id.lastIndexOf( '.' );
+                if ( extIndex > index )
+                {
+                    classifier = id.substring( index + 1, extIndex );
+                    ext = id.substring( extIndex + 1 );
+                }
+                else
+                {
+                    classifier = id.substring( index + 1 );
+                    ext = null;
+                }
+            }
+            else if ( c == '.' )
+            {
+                // rest is the extension
+                classifier = null;
+                ext = id.substring( index + 1 );
+            }
+            else
+            {
+                throw new IllegalArgumentException(
+                    "Not a valid artifact path in a Maven 2 repository, filename '" + id +
+                        "' expected classifier or extension but got '" + id.substring( index ) + "'" );
+            }
+        }
+
+        ArtifactMetadata metadata = new ArtifactMetadata();
+        metadata.setId( id );
+        metadata.setNamespace( groupId );
+        metadata.setProject( artifactId );
+        metadata.setRepositoryId( repoId );
+        metadata.setVersion( version );
+        // TODO: set classifier and extension on Maven facet
+        return metadata;
+    }
 }
index 5d98090a50e26c86c921672073f752daf5b2eb4b..c1f39808d7d086888e50471b76e800713f019c3e 100644 (file)
       <groupId>org.apache.archiva</groupId>
       <artifactId>metadata-repository-api</artifactId>
     </dependency>
-    <!-- TODO: we want to move the event handling, or perhaps centralise under deleteArtifact() in the metadata repository itself -->
     <dependency>
       <groupId>org.apache.archiva</groupId>
-      <artifactId>archiva-repository-layer</artifactId>
+      <artifactId>archiva-checksum</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.archiva</groupId>
-      <artifactId>archiva-checksum</artifactId>
+      <artifactId>archiva-model</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.archiva</groupId>
+      <artifactId>archiva-consumer-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-spring</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <version>1.8.3</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.archiva</groupId>
+      <artifactId>test-repository</artifactId>
+      <scope>test</scope>
     </dependency>
   </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>test-repository</id>
+            <phase>generate-test-resources</phase>
+            <goals>
+              <goal>unpack-dependencies</goal>
+            </goals>
+            <configuration>
+              <includeArtifactIds>test-repository</includeArtifactIds>
+              <outputDirectory>target/test-repository</outputDirectory>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
 </project>
index c0a03c326c2ddda79f76b023b2ac17a6ea3b41dc..cec2b086107b60fcebd5be83a25348499779c83a 100644 (file)
@@ -20,12 +20,12 @@ package org.apache.archiva.reports;
  */
 
 import org.apache.archiva.metadata.repository.MetadataRepository;
-import org.apache.maven.archiva.repository.events.RepositoryListener;
+import org.apache.archiva.repository.events.RepositoryListener;
 
 /**
  * Process repository management events and respond appropriately.
  *
- * @plexus.component role="org.apache.maven.archiva.repository.events.RepositoryListener" role-hint="problem-reports"
+ * @plexus.component role="org.apache.archiva.repository.events.RepositoryListener" role-hint="problem-reports"
  */
 public class RepositoryProblemEventListener
     implements RepositoryListener
index a9b365eee1ec6b9b72fe8ccd544dbc00bbfb26cc..9c3135a9222cc5f395ae7170cee69f29a9d6b34d 100644 (file)
@@ -19,17 +19,11 @@ package org.apache.archiva.reports.consumers;
  * under the License.
  */
 
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-
 import org.apache.archiva.checksum.ChecksumAlgorithm;
 import org.apache.archiva.checksum.ChecksummedFile;
 import org.apache.archiva.metadata.model.ArtifactMetadata;
 import org.apache.archiva.metadata.repository.MetadataRepository;
+import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
 import org.apache.archiva.reports.RepositoryProblemFacet;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
@@ -39,11 +33,6 @@ import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
 import org.apache.maven.archiva.consumers.AbstractMonitoredConsumer;
 import org.apache.maven.archiva.consumers.ConsumerException;
 import org.apache.maven.archiva.consumers.KnownRepositoryContentConsumer;
-import org.apache.maven.archiva.model.ArtifactReference;
-import org.apache.maven.archiva.repository.ManagedRepositoryContent;
-import org.apache.maven.archiva.repository.RepositoryContentFactory;
-import org.apache.maven.archiva.repository.RepositoryException;
-import org.apache.maven.archiva.repository.layout.LayoutException;
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
 import org.codehaus.plexus.registry.Registry;
@@ -51,6 +40,13 @@ import org.codehaus.plexus.registry.RegistryListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
 /**
  * Search the database of known SHA1 Checksums for potential duplicate artifacts.
  *
@@ -87,24 +83,23 @@ public class DuplicateArtifactsConsumer
      */
     private FileTypes filetypes;
 
-    /**
-     * @plexus.requirement
-     */
-    private RepositoryContentFactory repositoryFactory;
-
     private List<String> includes = new ArrayList<String>();
 
     private File repositoryDir;
 
     private String repoId;
 
-    private ManagedRepositoryContent repository;
-
     /**
      * @plexus.requirement
      */
     private MetadataRepository metadataRepository;
 
+    /**
+     * FIXME: needs to be selected based on the repository in question
+     * @plexus.requirement role-hint="maven2"
+     */
+    private RepositoryPathTranslator pathTranslator;
+
     public String getId()
     {
         return id;
@@ -133,16 +128,8 @@ public class DuplicateArtifactsConsumer
     public void beginScan( ManagedRepositoryConfiguration repo, Date whenGathered )
         throws ConsumerException
     {
-        try
-        {
-            repoId = repo.getId();
-            repository = repositoryFactory.getManagedRepositoryContent( repoId );
-            this.repositoryDir = new File( repository.getRepoRoot() );
-        }
-        catch ( RepositoryException e )
-        {
-            throw new ConsumerException( e.getMessage(), e );
-        }
+        repoId = repo.getId();
+        this.repositoryDir = new File( repo.getLocation() );
     }
 
     public void processFile( String path )
@@ -152,6 +139,8 @@ public class DuplicateArtifactsConsumer
 
         // TODO: would be quicker to somehow make sure it ran after the update database consumer, or as a part of that
         //  perhaps could use an artifact context that is retained for all consumers? First in can set the SHA-1
+        //  alternatively this could come straight from the storage resolver, which could populate the artifact metadata
+        //  in the later parse call with the desired checksum and use that
         String checksumSha1;
         ChecksummedFile checksummedFile = new ChecksummedFile( artifactFile );
         try
@@ -167,46 +156,45 @@ public class DuplicateArtifactsConsumer
 
         if ( CollectionUtils.isNotEmpty( results ) )
         {
-            if ( results.size() <= 1 )
-            {
-                // No duplicates detected.
-                log.debug( "Found no duplicate artifact results on: " + path + " (repository " + repoId + ")" );
-                return;
-            }
-
-            ArtifactReference artifactReference;
+            ArtifactMetadata originalArtifact;
             try
             {
-                artifactReference = repository.toArtifactReference( path );
+                originalArtifact = pathTranslator.getArtifactForPath( repoId, path );
             }
-            catch ( LayoutException e )
+            catch ( Exception e )
             {
-                log.warn( "Unable to report problem for path: " + path );
+                log.warn( "Not reporting problem for invalid artifact in checksum check: " + e.getMessage() );
                 return;
             }
 
             for ( ArtifactMetadata dupArtifact : results )
             {
                 String id = path.substring( path.lastIndexOf( "/" ) + 1 );
-                if ( dupArtifact.getId().equals( id ) &&
-                    dupArtifact.getNamespace().equals( artifactReference.getGroupId() ) &&
-                    dupArtifact.getProject().equals( artifactReference.getArtifactId() ) &&
-                    dupArtifact.getVersion().equals( artifactReference.getVersion() ) )
+                if ( dupArtifact.getId().equals( id ) && dupArtifact.getNamespace().equals(
+                    originalArtifact.getNamespace() ) && dupArtifact.getProject().equals(
+                    originalArtifact.getProject() ) && dupArtifact.getVersion().equals(
+                    originalArtifact.getVersion() ) )
                 {
                     // Skip reference to itself.
+                    if ( log.isDebugEnabled() )
+                    {
+                        log.debug( "Not counting duplicate for artifact " + dupArtifact + " for path " + path );
+                    }
                     continue;
                 }
 
                 RepositoryProblemFacet problem = new RepositoryProblemFacet();
                 problem.setRepositoryId( repoId );
-                problem.setNamespace( artifactReference.getGroupId() );
-                problem.setProject( artifactReference.getArtifactId() );
-                problem.setVersion( artifactReference.getVersion() );
+                problem.setNamespace( originalArtifact.getNamespace() );
+                problem.setProject( originalArtifact.getProject() );
+                problem.setVersion( originalArtifact.getVersion() );
                 problem.setId( id );
-                // TODO: proper path conversion for new metadata
-                problem.setMessage(
-                    "Duplicate Artifact Detected: " + path + " <--> " + dupArtifact.getNamespace().replace( '.', '/' ) +
-                        "/" + dupArtifact.getProject() + "/" + dupArtifact.getVersion() + "/" + dupArtifact.getId() );
+                // TODO: need to get the right storage resolver for the repository the dupe artifact is in, it might be
+                //       a different type
+                // TODO: we need the project version here, not the artifact version
+                problem.setMessage( "Duplicate Artifact Detected: " + path + " <--> " + pathTranslator.toPath(
+                    dupArtifact.getNamespace(), dupArtifact.getProject(), dupArtifact.getVersion(),
+                    dupArtifact.getId() ) );
                 problem.setProblem( "duplicate-artifact" );
 
                 metadataRepository.addMetadataFacet( repoId, problem );
diff --git a/archiva-modules/plugins/problem-reports/src/test/java/org/apache/archiva/reports/consumers/DuplicateArtifactsConsumerTest.java b/archiva-modules/plugins/problem-reports/src/test/java/org/apache/archiva/reports/consumers/DuplicateArtifactsConsumerTest.java
new file mode 100644 (file)
index 0000000..1a870c9
--- /dev/null
@@ -0,0 +1,215 @@
+package org.apache.archiva.reports.consumers;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.metadata.model.ArtifactMetadata;
+import org.apache.archiva.metadata.model.MetadataFacet;
+import org.apache.archiva.metadata.repository.MetadataRepository;
+import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
+import org.apache.archiva.reports.RepositoryProblemFacet;
+import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.apache.maven.archiva.consumers.ConsumerException;
+import org.apache.maven.archiva.consumers.KnownRepositoryContentConsumer;
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Matchers;
+
+import java.io.FileNotFoundException;
+import java.util.Arrays;
+import java.util.Date;
+
+import static org.mockito.Mockito.*;
+
+@SuppressWarnings( {"ThrowableInstanceNeverThrown"} )
+public class DuplicateArtifactsConsumerTest
+    extends PlexusInSpringTestCase
+{
+    private DuplicateArtifactsConsumer consumer;
+
+    private ManagedRepositoryConfiguration config;
+
+    private MetadataRepository metadataRepository;
+
+    private static final String TEST_REPO = "test-repo";
+
+    private static final String TEST_CHECKSUM = "edf5938e646956f445c6ecb719d44579cdeed974";
+
+    private static final String TEST_PROJECT = "test-artifact";
+
+    private static final String TEST_NAMESPACE = "com.example.test";
+
+    private static final String TEST_FILE =
+        "com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar";
+
+    private static final String TEST_VERSION = "1.0-20100308.230825-1";
+
+    private static final ArtifactMetadata TEST_METADATA = createMetadata( TEST_VERSION );
+
+    private RepositoryPathTranslator pathTranslator;
+
+    public void setUp()
+        throws Exception
+    {
+        super.setUp();
+
+        consumer = (DuplicateArtifactsConsumer) lookup( KnownRepositoryContentConsumer.class, "duplicate-artifacts" );
+        assertNotNull( consumer );
+
+        config = new ManagedRepositoryConfiguration();
+        config.setId( TEST_REPO );
+        config.setLocation( getTestFile( "target/test-repository" ).getAbsolutePath() );
+
+        metadataRepository = (MetadataRepository) lookup( MetadataRepository.class );
+
+        pathTranslator = (RepositoryPathTranslator) lookup( RepositoryPathTranslator.class, "maven2" );
+        when( pathTranslator.getArtifactForPath( TEST_REPO, TEST_FILE ) ).thenReturn( TEST_METADATA );
+    }
+
+    public void testConsumerArtifactNotDuplicated()
+        throws ConsumerException
+    {
+        when( metadataRepository.getArtifactsByChecksum( TEST_REPO, TEST_CHECKSUM ) ).thenReturn( Arrays.asList(
+            TEST_METADATA ) );
+
+        consumer.beginScan( config, new Date() );
+        consumer.processFile( TEST_FILE );
+        consumer.completeScan();
+
+        verify( metadataRepository, never() ).addMetadataFacet( eq( TEST_REPO ), Matchers.<MetadataFacet>anyObject() );
+    }
+
+    // TODO: Doesn't currently work
+//    public void testConsumerArtifactNotDuplicatedForOtherSnapshots()
+//        throws ConsumerException
+//    {
+//        when( metadataRepository.getArtifactsByChecksum( TEST_REPO, TEST_CHECKSUM ) ).thenReturn( Arrays.asList(
+//            TEST_METADATA, createMetadata( "1.0-20100309.002023-2" ) ) );
+//
+//        consumer.beginScan( config, new Date() );
+//        consumer.processFile( TEST_FILE );
+//        consumer.completeScan();
+//
+//        verify( metadataRepository, never() ).addMetadataFacet( eq( TEST_REPO ), Matchers.<MetadataFacet>anyObject() );
+//    }
+
+    public void testConsumerArtifactDuplicated()
+        throws ConsumerException
+    {
+        when( metadataRepository.getArtifactsByChecksum( TEST_REPO, TEST_CHECKSUM ) ).thenReturn( Arrays.asList(
+            TEST_METADATA, createMetadata( "1.0" ) ) );
+
+        consumer.beginScan( config, new Date() );
+        consumer.processFile( TEST_FILE );
+        consumer.completeScan();
+
+        ArgumentCaptor<RepositoryProblemFacet> argument = ArgumentCaptor.forClass( RepositoryProblemFacet.class );
+        verify( metadataRepository ).addMetadataFacet( eq( TEST_REPO ), argument.capture() );
+        RepositoryProblemFacet problem = argument.getValue();
+        assertProblem( problem );
+    }
+
+    public void testConsumerArtifactDuplicatedButSelfNotInMetadataRepository()
+        throws ConsumerException
+    {
+        when( metadataRepository.getArtifactsByChecksum( TEST_REPO, TEST_CHECKSUM ) ).thenReturn( Arrays.asList(
+            createMetadata( "1.0" ) ) );
+
+        consumer.beginScan( config, new Date() );
+        consumer.processFile( TEST_FILE );
+        consumer.completeScan();
+
+        ArgumentCaptor<RepositoryProblemFacet> argument = ArgumentCaptor.forClass( RepositoryProblemFacet.class );
+        verify( metadataRepository ).addMetadataFacet( eq( TEST_REPO ), argument.capture() );
+        RepositoryProblemFacet problem = argument.getValue();
+        assertProblem( problem );
+    }
+
+    public void testConsumerArtifactFileNotExist()
+        throws ConsumerException
+    {
+        consumer.beginScan( config, new Date() );
+        try
+        {
+            consumer.processFile( "com/example/test/test-artifact/2.0/test-artifact-2.0.jar" );
+            fail( "Should have failed to find file" );
+        }
+        catch ( ConsumerException e )
+        {
+            assertTrue( e.getCause() instanceof FileNotFoundException );
+        }
+        finally
+        {
+            consumer.completeScan();
+        }
+
+        verify( metadataRepository, never() ).addMetadataFacet( eq( TEST_REPO ), Matchers.<MetadataFacet>anyObject() );
+    }
+
+    public void testConsumerArtifactNotAnArtifactPathNoResults()
+        throws ConsumerException
+    {
+        consumer.beginScan( config, new Date() );
+        // No exception unnecessarily for something we can't report on
+        consumer.processFile( "com/example/invalid-artifact.txt" );
+        consumer.completeScan();
+
+        verify( metadataRepository, never() ).addMetadataFacet( eq( TEST_REPO ), Matchers.<MetadataFacet>anyObject() );
+    }
+
+    public void testConsumerArtifactNotAnArtifactPathResults()
+        throws ConsumerException
+    {
+        when( metadataRepository.getArtifactsByChecksum( eq( TEST_REPO ), anyString() ) ).thenReturn( Arrays.asList(
+            TEST_METADATA, createMetadata( "1.0" ) ) );
+
+        // override, this feels a little overspecified though
+        when( pathTranslator.getArtifactForPath( TEST_REPO, "com/example/invalid-artifact.txt" ) ).thenThrow(
+            new IllegalArgumentException() );
+
+        consumer.beginScan( config, new Date() );
+        // No exception unnecessarily for something we can't report on
+        consumer.processFile( "com/example/invalid-artifact.txt" );
+        consumer.completeScan();
+
+        verify( metadataRepository, never() ).addMetadataFacet( eq( TEST_REPO ), Matchers.<MetadataFacet>anyObject() );
+    }
+
+    private static void assertProblem( RepositoryProblemFacet problem )
+    {
+        assertEquals( TEST_REPO, problem.getRepositoryId() );
+        assertEquals( TEST_NAMESPACE, problem.getNamespace() );
+        assertEquals( TEST_PROJECT, problem.getProject() );
+        assertEquals( TEST_VERSION, problem.getVersion() );
+        assertEquals( TEST_PROJECT + "-" + TEST_VERSION + ".jar", problem.getId() );
+        assertNotNull( problem.getMessage() );
+        assertEquals( "duplicate-artifact", problem.getProblem() );
+    }
+
+    private static ArtifactMetadata createMetadata( String version )
+    {
+        ArtifactMetadata artifact = new ArtifactMetadata();
+        artifact.setId( TEST_PROJECT + "-" + version + ".jar" );
+        artifact.setNamespace( TEST_NAMESPACE );
+        artifact.setProject( TEST_PROJECT );
+        artifact.setVersion( version );
+        artifact.setRepositoryId( TEST_REPO );
+        return artifact;
+    }
+}
diff --git a/archiva-modules/plugins/problem-reports/src/test/java/org/apache/archiva/reports/consumers/MockitoFactory.java b/archiva-modules/plugins/problem-reports/src/test/java/org/apache/archiva/reports/consumers/MockitoFactory.java
new file mode 100644 (file)
index 0000000..e298e90
--- /dev/null
@@ -0,0 +1,51 @@
+package org.apache.archiva.reports.consumers;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.springframework.beans.factory.FactoryBean;
+
+import static org.mockito.Mockito.mock;
+
+public class MockitoFactory
+    implements FactoryBean
+{
+    private final Class<Object> type;
+
+    public MockitoFactory( Class<Object> type )
+    {
+        this.type = type;
+    }
+
+    public Object getObject()
+        throws Exception
+    {
+        return mock( type );
+    }
+
+    public Class getObjectType()
+    {
+        return type;
+    }
+
+    public boolean isSingleton()
+    {
+        return true;
+    }
+}
diff --git a/archiva-modules/plugins/problem-reports/src/test/resources/META-INF/spring-context.xml b/archiva-modules/plugins/problem-reports/src/test/resources/META-INF/spring-context.xml
new file mode 100644 (file)
index 0000000..0aafa26
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
+  <bean id="metadataRepositoryFactory" class="org.apache.archiva.reports.consumers.MockitoFactory"
+        name="metadataRepository">
+    <constructor-arg value="org.apache.archiva.metadata.repository.MetadataRepository"/>
+  </bean>
+  <bean id="repositoryPathTranslatorFactory" class="org.apache.archiva.reports.consumers.MockitoFactory"
+        name="repositoryPathTranslator#maven2">
+    <constructor-arg value="org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator"/>
+  </bean>
+</beans>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 735a38244023a7db3ea8d0827e6b086f13346581..851b5a9ceb2043cae3e27f652191278889870bff 100644 (file)
--- a/pom.xml
+++ b/pom.xml
         <artifactId>archiva-artifact-converter</artifactId>
         <version>1.4-SNAPSHOT</version>
       </dependency>
-      <dependency>
-        <groupId>org.apache.archiva</groupId>
-        <artifactId>archiva-artifact-reports</artifactId>
-        <version>1.4-SNAPSHOT</version>
-      </dependency>
       <dependency>
         <groupId>org.apache.archiva</groupId>
         <artifactId>archiva-checksum</artifactId>
         <artifactId>archiva-converter</artifactId>
         <version>1.4-SNAPSHOT</version>
       </dependency>
-      <dependency>
-        <groupId>org.apache.archiva</groupId>
-        <artifactId>archiva-dependency-graph</artifactId>
-        <version>1.4-SNAPSHOT</version>
-      </dependency>
       <dependency>
         <groupId>org.apache.archiva</groupId>
         <artifactId>archiva-core-consumers</artifactId>
       </dependency>
       <dependency>
         <groupId>org.apache.archiva</groupId>
-        <artifactId>archiva-database</artifactId>
-        <version>1.4-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.archiva</groupId>
-        <artifactId>archiva-database-consumers</artifactId>
+        <artifactId>test-repository</artifactId>
         <version>1.4-SNAPSHOT</version>
       </dependency>
       <dependency>