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/02/14 15:45:07 UTC

svn commit: r507550 [2/7] - in /maven/archiva/branches/archiva-MRM-239: ./ archiva-cli/src/main/java/org/apache/maven/archiva/cli/ archiva-converter/src/main/java/org/apache/maven/archiva/converter/ archiva-converter/src/main/java/org/apache/maven/arch...

Modified: maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/RepositoryTaskScheduler.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/RepositoryTaskScheduler.java?view=diff&rev=507550&r1=507549&r2=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/RepositoryTaskScheduler.java (original)
+++ maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/RepositoryTaskScheduler.java Wed Feb 14 06:44:59 2007
@@ -31,7 +31,7 @@
      */
     String ROLE = RepositoryTaskScheduler.class.getName();
 
-    void runIndexer()
+    void runDataRefresh()
         throws TaskExecutionException;
 
 }

Added: maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/executors/DataRefreshExecutor.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/executors/DataRefreshExecutor.java?view=auto&rev=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/executors/DataRefreshExecutor.java (added)
+++ maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/executors/DataRefreshExecutor.java Wed Feb 14 06:44:59 2007
@@ -0,0 +1,184 @@
+package org.apache.maven.archiva.scheduler.executors;
+
+/*
+ * 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.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory;
+import org.apache.maven.archiva.configuration.RepositoryConfiguration;
+import org.apache.maven.archiva.discoverer.Discoverer;
+import org.apache.maven.archiva.discoverer.DiscovererConsumer;
+import org.apache.maven.archiva.discoverer.DiscovererConsumerFactory;
+import org.apache.maven.archiva.discoverer.DiscovererException;
+import org.apache.maven.archiva.discoverer.DiscovererStatistics;
+import org.apache.maven.archiva.scheduler.task.DataRefreshTask;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.taskqueue.Task;
+import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
+import org.codehaus.plexus.taskqueue.execution.TaskExecutor;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * DataRefreshExecutor 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ * 
+ * @plexus.component role="org.codehaus.plexus.taskqueue.execution.TaskExecutor" 
+ *      role-hint="data-refresh"
+ */
+public class DataRefreshExecutor
+    extends AbstractLogEnabled
+    implements TaskExecutor
+{
+    /**
+     * Configuration store.
+     *
+     * @plexus.requirement
+     */
+    private ArchivaConfiguration archivaConfiguration;
+
+    /**
+     * @plexus.requirement
+     */
+    private ConfiguredRepositoryFactory repoFactory;
+
+    /**
+     * @plexus.configuration default-value="index-artifact"
+     */
+    private List consumerNames;
+
+    /**
+     * @plexus.requirement
+     */
+    private Discoverer discoverer;
+
+    /**
+     * @plexus.requirement
+     */
+    private DiscovererConsumerFactory consumerFactory;
+
+    public void executeTask( Task task )
+        throws TaskExecutionException
+    {
+        DataRefreshTask indexerTask = (DataRefreshTask) task;
+
+        getLogger().info( "Executing task from queue with job name: " + indexerTask.getJobName() );
+
+        execute();
+    }
+
+    private String toHumanTimestamp( long timestamp )
+    {
+        SimpleDateFormat dateFormat = new SimpleDateFormat();
+        return dateFormat.format( new Date( timestamp ) );
+    }
+
+    public void execute()
+        throws TaskExecutionException
+    {
+        Configuration configuration = archivaConfiguration.getConfiguration();
+
+        List consumers = new ArrayList();
+
+        for ( Iterator it = consumerNames.iterator(); it.hasNext(); )
+        {
+            String name = (String) it.next();
+            try
+            {
+                DiscovererConsumer consumer = consumerFactory.createConsumer( name );
+                consumers.add( consumer );
+            }
+            catch ( DiscovererException e )
+            {
+                throw new TaskExecutionException( e.getMessage(), e );
+            }
+        }
+
+        long time = System.currentTimeMillis();
+
+        for ( Iterator i = configuration.getRepositories().iterator(); i.hasNext(); )
+        {
+            RepositoryConfiguration repositoryConfiguration = (RepositoryConfiguration) i.next();
+
+            if ( !repositoryConfiguration.isIndexed() )
+            {
+                continue;
+            }
+
+            ArtifactRepository repository = repoFactory.createRepository( repositoryConfiguration );
+
+            List filteredConsumers = filterConsumers( consumers, repository );
+
+            DiscovererStatistics stats = discoverer.scanRepository( repository, filteredConsumers,
+                                                                    repositoryConfiguration.isIncludeSnapshots() );
+
+            getLogger().info( "----------------------------------------------------" );
+            getLogger().info( "Scan of Repository: " + repository.getId() );
+            getLogger().info( "   Started : " + toHumanTimestamp( stats.getTimestampStarted() ) );
+            getLogger().info( "   Finished: " + toHumanTimestamp( stats.getTimestampFinished() ) );
+            // TODO: pretty print ellapsed time.
+            getLogger().info( "   Duration: " + stats.getElapsedMilliseconds() + "ms" );
+            getLogger().info( "   Files   : " + stats.getFilesIncluded() );
+            getLogger().info( "   Consumed: " + stats.getFilesConsumed() );
+            getLogger().info( "   Skipped : " + stats.getFilesSkipped() );
+        }
+
+        time = System.currentTimeMillis() - time;
+
+        getLogger().info( "Finished data refresh process in " + time + "ms." );
+    }
+
+    /**
+     * Not all consumers work with all repositories.
+     * This will filter out those incompatible consumers based on the provided repository.
+     * 
+     * @param consumers the initial list of consumers.
+     * @param repository the repository to test consumer against.
+     * @return the filtered list of consumers.
+     */
+    private List filterConsumers( List consumers, ArtifactRepository repository )
+    {
+        List filtered = new ArrayList();
+
+        for ( Iterator it = consumers.iterator(); it.hasNext(); )
+        {
+            DiscovererConsumer consumer = (DiscovererConsumer) it.next();
+            if ( consumer.init( repository ) )
+            {
+                // Approved!
+                filtered.add( consumer );
+            }
+            else
+            {
+                getLogger().info( "Disabling consumer [" + consumer.getName() + "] for repository " + repository );
+            }
+        }
+
+        return filtered;
+    }
+
+}

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/executors/DataRefreshExecutor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/executors/DataRefreshExecutor.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/executors/DataRefreshExecutor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/DataRefreshTask.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/DataRefreshTask.java?view=auto&rev=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/DataRefreshTask.java (added)
+++ maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/DataRefreshTask.java Wed Feb 14 06:44:59 2007
@@ -0,0 +1,41 @@
+package org.apache.maven.archiva.scheduler.task;
+
+/**
+ * DataRefreshTask - task for discovering changes in the repository 
+ * and updating all associated data. 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class DataRefreshTask
+    implements RepositoryTask
+{
+    private String jobName;
+
+    private String policy;
+
+    public String getJobName()
+    {
+        return jobName;
+    }
+
+    public String getQueuePolicy()
+    {
+        return policy;
+    }
+
+    public void setJobName( String jobName )
+    {
+        this.jobName = jobName;
+    }
+
+    public void setQueuePolicy( String policy )
+    {
+        this.policy = policy;
+    }
+
+    public long getMaxExecutionTime()
+    {
+        return 0;
+    }
+}

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/DataRefreshTask.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/DataRefreshTask.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/DataRefreshTask.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/LegacyRepositoryConverterTest.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/LegacyRepositoryConverterTest.java?view=diff&rev=507550&r1=507549&r2=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/LegacyRepositoryConverterTest.java (original)
+++ maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/LegacyRepositoryConverterTest.java Wed Feb 14 06:44:59 2007
@@ -19,7 +19,7 @@
  * under the License.
  */
 
-import org.apache.maven.archiva.conversion.LegacyRepositoryConverter;
+import org.apache.maven.archiva.converter.legacy.LegacyRepositoryConverter;
 import org.codehaus.plexus.PlexusTestCase;
 
 import java.io.File;
@@ -39,6 +39,6 @@
 
         LegacyRepositoryConverter rm = (LegacyRepositoryConverter) lookup( LegacyRepositoryConverter.ROLE );
 
-        rm.convertLegacyRepository( legacyRepositoryDirectory, repositoryDirectory, null, true );
+        rm.convertLegacyRepository( legacyRepositoryDirectory, repositoryDirectory, true );
     }
 }

Modified: maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/repositories/DefaultActiveManagedRepositoriesTest.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/repositories/DefaultActiveManagedRepositoriesTest.java?view=diff&rev=507550&r1=507549&r2=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/repositories/DefaultActiveManagedRepositoriesTest.java (original)
+++ maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/repositories/DefaultActiveManagedRepositoriesTest.java Wed Feb 14 06:44:59 2007
@@ -27,7 +27,7 @@
 /**
  * DefaultActiveManagedRepositoriesTest
  *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
  * @version $Id$
  */
 public class DefaultActiveManagedRepositoriesTest

Copied: maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/scheduler/executors/DataRefreshExecutorTest.java (from r506385, maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/scheduler/executors/IndexerTaskExecutorTest.java)
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/scheduler/executors/DataRefreshExecutorTest.java?view=diff&rev=507550&p1=maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/scheduler/executors/IndexerTaskExecutorTest.java&r1=506385&p2=maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/scheduler/executors/DataRefreshExecutorTest.java&r2=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/scheduler/executors/IndexerTaskExecutorTest.java (original)
+++ maven/archiva/branches/archiva-MRM-239/archiva-core/src/test/java/org/apache/maven/archiva/scheduler/executors/DataRefreshExecutorTest.java Wed Feb 14 06:44:59 2007
@@ -22,7 +22,7 @@
 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.scheduler.task.IndexerTask;
+import org.apache.maven.archiva.scheduler.task.DataRefreshTask;
 import org.codehaus.plexus.PlexusTestCase;
 import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
 import org.codehaus.plexus.taskqueue.execution.TaskExecutor;
@@ -32,10 +32,10 @@
 /**
  * IndexerTaskExecutorTest
  *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
  * @version $Id$
  */
-public class IndexerTaskExecutorTest
+public class DataRefreshExecutorTest
     extends PlexusTestCase
 {
     private TaskExecutor taskExecutor;
@@ -45,7 +45,7 @@
     {
         super.setUp();
 
-        taskExecutor = (TaskExecutor) lookup( "org.codehaus.plexus.taskqueue.execution.TaskExecutor", "indexer" );
+        taskExecutor = (TaskExecutor) lookup( "org.codehaus.plexus.taskqueue.execution.TaskExecutor", "data-refresh" );
 
         ArchivaConfiguration archivaConfiguration =
             (ArchivaConfiguration) lookup( ArchivaConfiguration.class.getName() );
@@ -61,15 +61,15 @@
     public void testIndexer()
         throws TaskExecutionException
     {
-        taskExecutor.executeTask( new TestIndexerTask() );
+        taskExecutor.executeTask( new TestDataRefreshTask() );
     }
 
-    class TestIndexerTask
-        extends IndexerTask
+    class TestDataRefreshTask
+        extends DataRefreshTask
     {
         public String getJobName()
         {
-            return "TestIndexer";
+            return "TestDataRefresh";
         }
     }
 }

Modified: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/ArtifactDiscoverer.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/ArtifactDiscoverer.java?view=diff&rev=507550&r1=507549&r2=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/ArtifactDiscoverer.java (original)
+++ maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/ArtifactDiscoverer.java Wed Feb 14 06:44:59 2007
@@ -20,38 +20,18 @@
  */
 
 import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
-
-import java.util.List;
 
 /**
  * Interface for implementation that can discover artifacts within a repository.
  *
  * @author John Casey
  * @author Brett Porter
- * @todo do we want blacklisted patterns in another form? Part of the object construction?
- * @todo should includeSnapshots be configuration on the component? If not, should the methods be changed to include alternates for both possibilities (discoverReleaseArtifacts, discoverReleaseAndSnapshotArtifacts)?
- * @todo instead of a returned list, should a listener be passed in?
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
  */
 public interface ArtifactDiscoverer
     extends Discoverer
 {
     String ROLE = ArtifactDiscoverer.class.getName();
-
-    /**
-     * Discover artifacts in the repository. Only artifacts added since the last attempt at discovery will be found.
-     * This process guarantees never to miss an artifact, however it is possible that an artifact will be received twice
-     * consecutively even if unchanged, so any users of this list must handle such a situation gracefully.
-     *
-     * @param repository          the location of the repository
-     * @param blacklistedPatterns pattern that lists any files to prevent from being included when scanning
-     * @param filter              filter for artifacts to include in the discovered list
-     * @return the list of artifacts discovered
-     * @throws DiscovererException if there was an unrecoverable problem discovering artifacts or recording progress
-     */
-    List discoverArtifacts( ArtifactRepository repository, List blacklistedPatterns, ArtifactFilter filter )
-        throws DiscovererException;
 
     /**
      * Build an artifact from a path in the repository

Added: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DefaultDiscoverer.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DefaultDiscoverer.java?view=auto&rev=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DefaultDiscoverer.java (added)
+++ maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DefaultDiscoverer.java Wed Feb 14 06:44:59 2007
@@ -0,0 +1,168 @@
+package org.apache.maven.archiva.discoverer;
+
+/*
+ * 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.maven.artifact.repository.ArtifactRepository;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.util.DirectoryWalker;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Discoverer Implementation.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @plexus.component role="org.apache.maven.archiva.discoverer.Discoverer"
+ *    role-hint="default"
+ */
+public class DefaultDiscoverer
+    extends AbstractLogEnabled
+    implements Discoverer
+{
+    /**
+     * Standard patterns to exclude from discovery as they are usually noise.
+     */
+    private static final String[] STANDARD_DISCOVERY_EXCLUDES = {
+        "bin/**",
+        "reports/**",
+        ".index",
+        ".reports/**",
+        ".maven/**",
+        "**/*snapshot-version",
+        "*/website/**",
+        "*/licences/**",
+        "**/.htaccess",
+        "**/*.html",
+        "**/*.txt",
+        "**/README*",
+        "**/CHANGELOG*",
+        "**/KEYS*" };
+
+    public DefaultDiscoverer()
+    {
+    }
+
+    public DiscovererStatistics scanRepository( ArtifactRepository repository, List consumers, boolean includeSnapshots )
+    {
+        return walkRepository( repository, consumers, includeSnapshots, true );
+    }
+
+    public DiscovererStatistics walkRepository( ArtifactRepository repository, List consumers, boolean includeSnapshots )
+    {
+        return walkRepository( repository, consumers, includeSnapshots, false );
+    }
+
+    private DiscovererStatistics walkRepository( ArtifactRepository repository, List consumers,
+                                                 boolean includeSnapshots, boolean checkLastModified )
+    {
+        // Sanity Check
+
+        if ( repository == null )
+        {
+            throw new IllegalArgumentException( "Unable to operate on a null repository." );
+        }
+
+        if ( !"file".equals( repository.getProtocol() ) )
+        {
+            throw new UnsupportedOperationException( "Only filesystem repositories are supported." );
+        }
+
+        File repositoryBase = new File( repository.getBasedir() );
+
+        if ( !repositoryBase.exists() )
+        {
+            throw new UnsupportedOperationException( "Unable to scan a repository, directory "
+                + repositoryBase.getAbsolutePath() + " does not exist." );
+        }
+
+        if ( !repositoryBase.isDirectory() )
+        {
+            throw new UnsupportedOperationException( "Unable to scan a repository, path "
+                + repositoryBase.getAbsolutePath() + " is not a directory." );
+        }
+
+        // Setup Includes / Excludes.
+
+        List allExcludes = new ArrayList();
+        List allIncludes = new ArrayList();
+
+        // Exclude all of the SCM patterns.
+        allExcludes.addAll( FileUtils.getDefaultExcludesAsList() );
+
+        // Exclude all of the archiva noise patterns.
+        allExcludes.addAll( Arrays.asList( STANDARD_DISCOVERY_EXCLUDES ) );
+
+        if ( !includeSnapshots )
+        {
+            allExcludes.add( "**/*-SNAPSHOT*" );
+        }
+
+        Iterator it = consumers.iterator();
+        while ( it.hasNext() )
+        {
+            DiscovererConsumer consumer = (DiscovererConsumer) it.next();
+
+            // TODO Disabled, until I can find a better way to do this that doesn't clobber other consumers. - joakime
+            // addUniqueElements( consumer.getExcludePatterns(), allExcludes );
+            addUniqueElements( consumer.getIncludePatterns(), allIncludes );
+        }
+
+        // Setup Directory Walker
+
+        DirectoryWalker dirWalker = new DirectoryWalker();
+
+        dirWalker.setBaseDir( repositoryBase );
+
+        dirWalker.setIncludes( allIncludes );
+        dirWalker.setExcludes( allExcludes );
+
+        // Setup the Scan Instance
+
+        RepositoryScanner repoScanner = new RepositoryScanner( repository, consumers );
+        repoScanner.setCheckLastModified( checkLastModified );
+
+        repoScanner.setLogger( getLogger() );
+        dirWalker.addDirectoryWalkListener( repoScanner );
+
+        // Execute scan.
+        dirWalker.scan();
+
+        return repoScanner.getStatistics();
+    }
+
+    private void addUniqueElements( List fromList, List toList )
+    {
+        Iterator itFrom = fromList.iterator();
+        while ( itFrom.hasNext() )
+        {
+            Object o = itFrom.next();
+            if ( !toList.contains( o ) )
+            {
+                toList.add( o );
+            }
+        }
+    }
+}

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DefaultDiscoverer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DefaultDiscoverer.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DefaultDiscoverer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/Discoverer.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/Discoverer.java?view=diff&rev=507550&r1=507549&r2=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/Discoverer.java (original)
+++ maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/Discoverer.java Wed Feb 14 06:44:59 2007
@@ -19,26 +19,37 @@
  * under the License.
  */
 
-import java.util.Iterator;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+import java.util.List;
 
 /**
- * @author Edwin Punzalan
+ * Discoverer - generic discoverer of content in an ArtifactRepository. 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
  */
 public interface Discoverer
 {
     /**
-     * Get the list of paths kicked out during the discovery process.
-     *
-     * @return the paths as Strings.
+     * Scan the repository for changes.
+     * Report changes to the appropriate Consumer.
+     * 
+     * @param repository the repository to change.
+     * @param consumers use the provided list of consumers.
+     * @param includeSnapshots true to include snapshots in the scanning of this repository.
+     * @return the statistics for this scan.
      */
-    Iterator getKickedOutPathsIterator();
-
+    public DiscovererStatistics scanRepository( ArtifactRepository repository, List consumers, boolean includeSnapshots );
+    
     /**
-     * Get the list of paths excluded during the discovery process.
-     *
-     * @return the paths as Strings.
+     * Walk the entire repository, regardless of change.
+     * Report changes to the appropriate Consumer.
+     * 
+     * @param repository the repository to change.
+     * @param consumers use the provided list of consumers.
+     * @param includeSnapshots true to include snapshots in the walking of this repository.
+     * @return the statistics for this scan.
      */
-    Iterator getExcludedPathsIterator();
-
-    void setTrackOmittedPaths( boolean trackOmittedPaths );
+    public DiscovererStatistics walkRepository( ArtifactRepository repository, List consumers, boolean includeSnapshots );
 }

Added: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererConsumer.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererConsumer.java?view=auto&rev=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererConsumer.java (added)
+++ maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererConsumer.java Wed Feb 14 06:44:59 2007
@@ -0,0 +1,46 @@
+package org.apache.maven.archiva.discoverer;
+
+/*
+ * 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.maven.artifact.repository.ArtifactRepository;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * DiscovererConsumer 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public interface DiscovererConsumer
+{
+    public static final String ROLE = DiscovererConsumer.class.getName();
+
+    public String getName();
+    
+    public boolean init( ArtifactRepository repository );
+    
+    public List getExcludePatterns();
+    
+    public List getIncludePatterns();
+
+    public void processFile( File file ) throws DiscovererException;
+}

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererConsumer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererConsumer.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererConsumer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererConsumerFactory.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererConsumerFactory.java?view=auto&rev=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererConsumerFactory.java (added)
+++ maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererConsumerFactory.java Wed Feb 14 06:44:59 2007
@@ -0,0 +1,42 @@
+package org.apache.maven.archiva.discoverer;
+
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.context.Context;
+import org.codehaus.plexus.context.ContextException;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
+
+/**
+ * DiscovererConsumerFactory - factory for consumers.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ * @plexus.component role="org.apache.maven.archiva.discoverer.DiscovererConsumerFactory"
+ */
+public class DiscovererConsumerFactory
+implements Contextualizable
+{
+    private PlexusContainer container;
+    
+    public DiscovererConsumer createConsumer( String name ) throws DiscovererException
+    {
+        DiscovererConsumer consumer;
+        try
+        {
+            consumer = (DiscovererConsumer) container.lookup(DiscovererConsumer.ROLE, name);
+        }
+        catch ( ComponentLookupException e )
+        {
+            throw new DiscovererException("Unable to create consumer [" + name + "]: " + e.getMessage(), e);
+        }
+        
+        return consumer;
+    }
+
+    public void contextualize( Context context )
+        throws ContextException
+    {
+        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
+    }
+}

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererConsumerFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererConsumerFactory.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererConsumerFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererStatistics.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererStatistics.java?view=auto&rev=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererStatistics.java (added)
+++ maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererStatistics.java Wed Feb 14 06:44:59 2007
@@ -0,0 +1,182 @@
+package org.apache.maven.archiva.discoverer;
+
+/*
+ * 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.commons.lang.math.NumberUtils;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.codehaus.plexus.util.IOUtil;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+/**
+ * DiscovererStatistics 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class DiscovererStatistics
+{
+    public static final String STATS_FILENAME = ".stats";
+
+    private static final String PROP_FILES_CONSUMED = "scan.consumed.files";
+
+    private static final String PROP_FILES_INCLUDED = "scan.included.files";
+
+    private static final String PROP_FILES_SKIPPED = "scan.skipped.files";
+
+    private static final String PROP_TIMESTAMP_STARTED = "scan.started.timestamp";
+
+    private static final String PROP_TIMESTAMP_FINISHED = "scan.finished.timestamp";
+
+    protected long timestampStarted = 0;
+
+    protected long timestampFinished = 0;
+
+    protected long filesIncluded = 0;
+
+    protected long filesConsumed = 0;
+
+    protected long filesSkipped = 0;
+
+    private ArtifactRepository repository;
+
+    public DiscovererStatistics( ArtifactRepository repository )
+    {
+        this.repository = repository;
+        load();
+    }
+
+    public void load()
+    {
+        File repositoryBase = new File( this.repository.getBasedir() );
+
+        File scanProperties = new File( repositoryBase, STATS_FILENAME );
+        FileInputStream fis = null;
+        try
+        {
+            Properties props = new Properties();
+            fis = new FileInputStream( scanProperties );
+            props.load( fis );
+
+            timestampFinished = NumberUtils.toLong( props.getProperty( PROP_TIMESTAMP_FINISHED ), 0 );
+            timestampStarted = NumberUtils.toLong( props.getProperty( PROP_TIMESTAMP_STARTED ), 0 );
+            filesIncluded = NumberUtils.toLong( props.getProperty( PROP_FILES_INCLUDED ), 0 );
+            filesConsumed = NumberUtils.toLong( props.getProperty( PROP_FILES_CONSUMED ), 0 );
+            filesSkipped = NumberUtils.toLong( props.getProperty( PROP_FILES_SKIPPED ), 0 );
+        }
+        catch ( IOException e )
+        {
+            reset();
+        }
+        finally
+        {
+            IOUtil.close( fis );
+        }
+    }
+
+    public void save()
+        throws DiscovererException
+    {
+        Properties props = new Properties();
+        props.setProperty( PROP_TIMESTAMP_FINISHED, String.valueOf( timestampFinished ) );
+        props.setProperty( PROP_TIMESTAMP_STARTED, String.valueOf( timestampStarted ) );
+        props.setProperty( PROP_FILES_INCLUDED, String.valueOf( filesIncluded ) );
+        props.setProperty( PROP_FILES_CONSUMED, String.valueOf( filesConsumed ) );
+        props.setProperty( PROP_FILES_SKIPPED, String.valueOf( filesSkipped ) );
+
+        File repositoryBase = new File( this.repository.getBasedir() );
+        File statsFile = new File( repositoryBase, STATS_FILENAME );
+
+        FileOutputStream fos = null;
+        try
+        {
+            fos = new FileOutputStream( statsFile );
+            props.store( fos, "Last Scan Information, managed by Archiva. DO NOT EDIT" );
+            fos.flush();
+        }
+        catch ( IOException e )
+        {
+            throw new DiscovererException( "Unable to write scan stats to file " + statsFile.getAbsolutePath() + ": "
+                + e.getMessage(), e );
+        }
+        finally
+        {
+            IOUtil.close( fos );
+        }
+    }
+
+    public void reset()
+    {
+        timestampStarted = 0;
+        timestampFinished = 0;
+        filesIncluded = 0;
+        filesConsumed = 0;
+        filesSkipped = 0;
+    }
+
+    public long getElapsedMilliseconds()
+    {
+        return timestampFinished - timestampStarted;
+    }
+
+    public long getFilesConsumed()
+    {
+        return filesConsumed;
+    }
+
+    public long getFilesIncluded()
+    {
+        return filesIncluded;
+    }
+
+    public ArtifactRepository getRepository()
+    {
+        return repository;
+    }
+
+    public long getTimestampFinished()
+    {
+        return timestampFinished;
+    }
+
+    public long getTimestampStarted()
+    {
+        return timestampStarted;
+    }
+
+    public long getFilesSkipped()
+    {
+        return filesSkipped;
+    }
+
+    public void setTimestampFinished( long timestampFinished )
+    {
+        this.timestampFinished = timestampFinished;
+    }
+
+    public void setTimestampStarted( long timestampStarted )
+    {
+        this.timestampStarted = timestampStarted;
+    }
+}

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererStatistics.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererStatistics.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/DiscovererStatistics.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/PathUtil.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/PathUtil.java?view=auto&rev=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/PathUtil.java (added)
+++ maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/PathUtil.java Wed Feb 14 06:44:59 2007
@@ -0,0 +1,56 @@
+package org.apache.maven.archiva.discoverer;
+
+/*
+ * 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.io.File;
+
+/**
+ * PathUtil - simple utility methods for path manipulation. 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class PathUtil
+{
+    public static String getRelative( String basedir, File file )
+    {
+        return getRelative( basedir, file.getAbsolutePath() );
+    }
+
+    public static String getRelative( String basedir, String child )
+    {
+        if ( child.startsWith( basedir ) )
+        {
+            // simple solution.
+            return child.substring( basedir.length() + 1 );
+        }
+
+        String absoluteBasedir = new File( basedir ).getAbsolutePath();
+        if ( child.startsWith( absoluteBasedir ) )
+        {
+            // resolved basedir solution.
+            return child.substring( absoluteBasedir.length() + 1 );
+        }
+
+        // File is not within basedir.
+        throw new IllegalStateException( "Unable to obtain relative path of file " + child
+            + ", it is not within basedir " + basedir + "." );
+    }
+}

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/PathUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/PathUtil.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/PathUtil.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/RepositoryScanner.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/RepositoryScanner.java?view=auto&rev=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/RepositoryScanner.java (added)
+++ maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/RepositoryScanner.java Wed Feb 14 06:44:59 2007
@@ -0,0 +1,204 @@
+package org.apache.maven.archiva.discoverer;
+
+/*
+ * 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.commons.lang.SystemUtils;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.DirectoryWalkListener;
+import org.codehaus.plexus.util.SelectorUtils;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * RepositoryScanner - this is an instance of a scan against a repository.
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class RepositoryScanner
+    implements DirectoryWalkListener
+{
+    public static final String ROLE = RepositoryScanner.class.getName();
+
+    private List consumers;
+
+    private ArtifactRepository repository;
+
+    private Logger logger;
+
+    private boolean isCaseSensitive = true;
+
+    private DiscovererStatistics stats;
+
+    private boolean checkLastModified = true;
+
+    public RepositoryScanner( ArtifactRepository repository, List consumerList )
+    {
+        this.repository = repository;
+        this.consumers = consumerList;
+        stats = new DiscovererStatistics( repository );
+
+        Iterator it = this.consumers.iterator();
+        while ( it.hasNext() )
+        {
+            DiscovererConsumer consumer = (DiscovererConsumer) it.next();
+
+            if ( !consumer.init( this.repository ) )
+            {
+                throw new IllegalStateException( "Consumer [" + consumer.getName()
+                    + "] is reporting that it is incompatible with the [" + repository.getId() + "] repository." );
+            }
+        }
+
+        if ( SystemUtils.IS_OS_WINDOWS )
+        {
+            isCaseSensitive = false;
+        }
+    }
+
+    public DiscovererStatistics getStatistics()
+    {
+        return stats;
+    }
+
+    public void directoryWalkFinished()
+    {
+        getLogger().info( "Walk Finished." );
+        stats.timestampFinished = System.currentTimeMillis();
+        
+        if( isCheckLastModified() )
+        {
+            // Only save if dealing with 'last modified' concept.
+            
+            try
+            {
+                stats.save();
+            }
+            catch ( DiscovererException e )
+            {
+                getLogger().warn( "Unable to save Scan information.", e );
+            }
+        }
+    }
+
+    public void directoryWalkStarting( File basedir )
+    {
+        getLogger().info( "Walk Started." );
+        stats.reset();
+        stats.timestampStarted = System.currentTimeMillis();
+    }
+
+    public void directoryWalkStep( int percentage, File file )
+    {
+        getLogger().info( "Walk Step: " + percentage + ", " + file );
+
+        // Timestamp finished points to the last successful scan, not this current one.
+        if ( isCheckLastModified() && ( file.lastModified() <= stats.timestampFinished ) )
+        {
+            // Skip file as no change has occured.
+            getLogger().debug( "Skipping, No Change: " + file.getAbsolutePath() );
+            stats.filesSkipped++;
+            return;
+        }
+
+        synchronized ( consumers )
+        {
+            stats.filesIncluded++;
+
+            String relativePath = PathUtil.getRelative( repository.getBasedir(), file );
+
+            Iterator itConsumers = this.consumers.iterator();
+            while ( itConsumers.hasNext() )
+            {
+                DiscovererConsumer consumer = (DiscovererConsumer) itConsumers.next();
+
+                if ( isConsumerOfFile( consumer, relativePath ) )
+                {
+                    try
+                    {
+                        getLogger().info( "Sending to consumer: " + consumer.getName() );
+                        stats.filesConsumed++;
+                        consumer.processFile( file );
+                    }
+                    catch ( Exception e )
+                    {
+                        /* Intentionally Catch all exceptions.
+                         * So that the discoverer processing can continue.
+                         */
+                        getLogger()
+                            .error( "Unable to process file [" + file.getAbsolutePath() + "]: " + e.getMessage(), e );
+                    }
+                }
+                else
+                {
+                    getLogger().info( "Skipping consumer " + consumer.getName() + " for file " + relativePath );
+                }
+            }
+        }
+    }
+
+    private boolean isConsumerOfFile( DiscovererConsumer consumer, String relativePath )
+    {
+        Iterator it = consumer.getIncludePatterns().iterator();
+        // String name = file.getAbsolutePath();
+        while ( it.hasNext() )
+        {
+            String pattern = (String) it.next();
+            if ( SelectorUtils.matchPath( pattern, relativePath, isCaseSensitive ) )
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public boolean isCheckLastModified()
+    {
+        return checkLastModified;
+    }
+
+    public void setCheckLastModified( boolean checkLastModified )
+    {
+        this.checkLastModified = checkLastModified;
+    }
+
+    /**
+     * Debug method from DirectoryWalker.
+     */
+    public void debug( String message )
+    {
+        getLogger().debug( "Repository Scanner: " + message );
+    }
+
+    public Logger getLogger()
+    {
+        return logger;
+    }
+
+    public void setLogger( Logger logger )
+    {
+        this.logger = logger;
+    }
+
+}

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/RepositoryScanner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/RepositoryScanner.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/RepositoryScanner.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/AbstractLayoutArtifactBuilder.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/AbstractLayoutArtifactBuilder.java?view=auto&rev=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/AbstractLayoutArtifactBuilder.java (added)
+++ maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/AbstractLayoutArtifactBuilder.java Wed Feb 14 06:44:59 2007
@@ -0,0 +1,55 @@
+package org.apache.maven.archiva.discoverer.builders;
+
+/*
+ * 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.maven.artifact.factory.ArtifactFactory;
+
+/**
+ * AbstractLayoutArtifactBuilder 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public abstract class AbstractLayoutArtifactBuilder
+    implements LayoutArtifactBuilder
+{
+    /**
+     * @plexus.requirement
+     */
+    protected ArtifactFactory artifactFactory;
+
+    /**
+     * Constructor used by plexus
+     */
+    public AbstractLayoutArtifactBuilder()
+    {
+
+    }
+
+    /**
+     * Constructor used by manual process.
+     * 
+     * @param artifactFactory the artifact factory to use.
+     */
+    public AbstractLayoutArtifactBuilder( ArtifactFactory artifactFactory )
+    {
+        this.artifactFactory = artifactFactory;
+    }
+}

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/AbstractLayoutArtifactBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/AbstractLayoutArtifactBuilder.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/AbstractLayoutArtifactBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/BuilderException.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/BuilderException.java?view=auto&rev=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/BuilderException.java (added)
+++ maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/BuilderException.java Wed Feb 14 06:44:59 2007
@@ -0,0 +1,43 @@
+package org.apache.maven.archiva.discoverer.builders;
+
+/*
+ * 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.maven.archiva.discoverer.DiscovererException;
+
+/**
+ * BuilderException - used to indicate a problem during the building of an object from file. 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class BuilderException
+    extends DiscovererException
+{
+
+    public BuilderException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public BuilderException( String message )
+    {
+        super( message );
+    }
+}

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/BuilderException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/BuilderException.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/BuilderException.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/DefaultLayoutArtifactBuilder.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/DefaultLayoutArtifactBuilder.java?view=auto&rev=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/DefaultLayoutArtifactBuilder.java (added)
+++ maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/DefaultLayoutArtifactBuilder.java Wed Feb 14 06:44:59 2007
@@ -0,0 +1,214 @@
+package org.apache.maven.archiva.discoverer.builders;
+
+/*
+ * 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.maven.archiva.discoverer.DiscovererException;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.codehaus.plexus.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * DefaultLayoutArtifactBuilder - artifact builder for default layout repositories. 
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ * 
+ * @plexus.component role="org.apache.maven.archiva.discoverer.builders.LayoutArtifactBuilder"
+ *     role-hint="default"
+ */
+public class DefaultLayoutArtifactBuilder
+    extends AbstractLayoutArtifactBuilder
+    implements LayoutArtifactBuilder
+{
+    public DefaultLayoutArtifactBuilder()
+    {
+        super();
+    }
+
+    public DefaultLayoutArtifactBuilder( ArtifactFactory artifactFactory )
+    {
+        super( artifactFactory );
+    }
+
+    public Artifact build( String pathToArtifact )
+        throws BuilderException, DiscovererException
+    {
+        List pathParts = new ArrayList();
+        StringTokenizer st = new StringTokenizer( pathToArtifact, "/\\" );
+        while ( st.hasMoreTokens() )
+        {
+            pathParts.add( st.nextToken() );
+        }
+
+        Collections.reverse( pathParts );
+
+        Artifact artifact;
+        if ( pathParts.size() >= 4 )
+        {
+            // maven 2.x path
+
+            // the actual artifact filename.
+            String filename = (String) pathParts.remove( 0 );
+
+            // the next one is the version.
+            String version = (String) pathParts.remove( 0 );
+
+            // the next one is the artifactId.
+            String artifactId = (String) pathParts.remove( 0 );
+
+            // the remaining are the groupId.
+            Collections.reverse( pathParts );
+            String groupId = StringUtils.join( pathParts.iterator(), "." );
+
+            String remainingFilename = filename;
+            if ( remainingFilename.startsWith( artifactId + "-" ) )
+            {
+                remainingFilename = remainingFilename.substring( artifactId.length() + 1 );
+
+                String classifier = null;
+
+                // TODO: use artifact handler, share with legacy discoverer
+                String type;
+                if ( remainingFilename.endsWith( ".tar.gz" ) )
+                {
+                    type = "distribution-tgz";
+                    remainingFilename = remainingFilename
+                        .substring( 0, remainingFilename.length() - ".tar.gz".length() );
+                }
+                else if ( remainingFilename.endsWith( ".zip" ) )
+                {
+                    type = "distribution-zip";
+                    remainingFilename = remainingFilename.substring( 0, remainingFilename.length() - ".zip".length() );
+                }
+                else if ( remainingFilename.endsWith( "-test-sources.jar" ) )
+                {
+                    type = "java-source";
+                    classifier = "test-sources";
+                    remainingFilename = remainingFilename.substring( 0, remainingFilename.length()
+                        - "-test-sources.jar".length() );
+                }
+                else if ( remainingFilename.endsWith( "-sources.jar" ) )
+                {
+                    type = "java-source";
+                    classifier = "sources";
+                    remainingFilename = remainingFilename.substring( 0, remainingFilename.length()
+                        - "-sources.jar".length() );
+                }
+                else
+                {
+                    int index = remainingFilename.lastIndexOf( "." );
+                    if ( index >= 0 )
+                    {
+                        type = remainingFilename.substring( index + 1 );
+                        remainingFilename = remainingFilename.substring( 0, index );
+                    }
+                    else
+                    {
+                        throw new BuilderException( "Path filename does not have an extension." );
+                    }
+                }
+
+                Artifact result;
+                if ( classifier == null )
+                {
+                    result = artifactFactory
+                        .createArtifact( groupId, artifactId, version, Artifact.SCOPE_RUNTIME, type );
+                }
+                else
+                {
+                    result = artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, type,
+                                                                           classifier );
+                }
+
+                if ( result.isSnapshot() )
+                {
+                    // version is *-SNAPSHOT, filename is *-yyyyMMdd.hhmmss-b
+                    int classifierIndex = remainingFilename.indexOf( '-', version.length() + 8 );
+                    if ( classifierIndex >= 0 )
+                    {
+                        classifier = remainingFilename.substring( classifierIndex + 1 );
+                        remainingFilename = remainingFilename.substring( 0, classifierIndex );
+                        result = artifactFactory.createArtifactWithClassifier( groupId, artifactId, remainingFilename,
+                                                                               type, classifier );
+                    }
+                    else
+                    {
+                        result = artifactFactory.createArtifact( groupId, artifactId, remainingFilename,
+                                                                 Artifact.SCOPE_RUNTIME, type );
+                    }
+
+                    // poor encapsulation requires we do this to populate base version
+                    if ( !result.isSnapshot() )
+                    {
+                        throw new BuilderException( "Failed to create a snapshot artifact: " + result );
+                    }
+                    else if ( !result.getBaseVersion().equals( version ) )
+                    {
+                        throw new BuilderException(
+                                                    "Built snapshot artifact base version does not match path version: "
+                                                        + result.getBaseVersion() + "; should have been version: "
+                                                        + version );
+                    }
+                    else
+                    {
+                        artifact = result;
+                    }
+                }
+                else if ( !remainingFilename.startsWith( version ) )
+                {
+                    throw new BuilderException( "Built artifact version does not match path version" );
+                }
+                else if ( !remainingFilename.equals( version ) )
+                {
+                    if ( remainingFilename.charAt( version.length() ) == '-' )
+                    {
+                        classifier = remainingFilename.substring( version.length() + 1 );
+                        artifact = artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, type,
+                                                                                 classifier );
+                    }
+                    else
+                    {
+                        throw new BuilderException( "Path version does not corresspond to an artifact version" );
+                    }
+                }
+                else
+                {
+                    artifact = result;
+                }
+            }
+            else
+            {
+                throw new BuilderException( "Path filename does not correspond to an artifact." );
+            }
+        }
+        else
+        {
+            throw new BuilderException( "Path is too short to build an artifact from." );
+        }
+
+        return artifact;
+    }
+}

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/DefaultLayoutArtifactBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/DefaultLayoutArtifactBuilder.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/DefaultLayoutArtifactBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/LayoutArtifactBuilder.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/LayoutArtifactBuilder.java?view=auto&rev=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/LayoutArtifactBuilder.java (added)
+++ maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/LayoutArtifactBuilder.java Wed Feb 14 06:44:59 2007
@@ -0,0 +1,37 @@
+package org.apache.maven.archiva.discoverer.builders;
+
+/*
+ * 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.maven.archiva.discoverer.DiscovererException;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+
+/**
+ * LayoutArtifactBuilder 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ * 
+ * @todo this concept should really exist inside of the {@link ArtifactRepositoryLayout}
+ */
+public interface LayoutArtifactBuilder
+{
+    public Artifact build( String pathToArtifact ) throws BuilderException, DiscovererException;
+}

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/LayoutArtifactBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/LayoutArtifactBuilder.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/LayoutArtifactBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/LegacyLayoutArtifactBuilder.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/LegacyLayoutArtifactBuilder.java?view=auto&rev=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/LegacyLayoutArtifactBuilder.java (added)
+++ maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/LegacyLayoutArtifactBuilder.java Wed Feb 14 06:44:59 2007
@@ -0,0 +1,299 @@
+package org.apache.maven.archiva.discoverer.builders;
+
+/*
+ * 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.maven.archiva.discoverer.DiscovererException;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.StringTokenizer;
+
+/**
+ * LegacyLayoutArtifactBuilder 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ * 
+ *  @plexus.component role="org.apache.maven.archiva.discoverer.builders.LayoutArtifactBuilder"
+ *     role-hint="legacy"
+ */
+public class LegacyLayoutArtifactBuilder
+    extends AbstractLayoutArtifactBuilder
+    implements LayoutArtifactBuilder
+{
+    public LegacyLayoutArtifactBuilder()
+    {
+        super();
+    }
+
+    public LegacyLayoutArtifactBuilder( ArtifactFactory artifactFactory )
+    {
+        super( artifactFactory );
+    }
+
+    public Artifact build( String pathToArtifact )
+        throws BuilderException, DiscovererException
+    {
+        StringTokenizer tokens = new StringTokenizer( pathToArtifact, "/\\" );
+
+        Artifact result;
+
+        int numberOfTokens = tokens.countTokens();
+
+        if ( numberOfTokens == 3 )
+        {
+            String groupId = tokens.nextToken();
+
+            String type = tokens.nextToken();
+
+            if ( type.endsWith( "s" ) )
+            {
+                type = type.substring( 0, type.length() - 1 );
+
+                // contains artifactId, version, classifier, and extension.
+                String avceGlob = tokens.nextToken();
+
+                //noinspection CollectionDeclaredAsConcreteClass
+                LinkedList avceTokenList = new LinkedList();
+
+                StringTokenizer avceTokenizer = new StringTokenizer( avceGlob, "-" );
+                while ( avceTokenizer.hasMoreTokens() )
+                {
+                    avceTokenList.addLast( avceTokenizer.nextToken() );
+                }
+
+                String lastAvceToken = (String) avceTokenList.removeLast();
+
+                // TODO: share with other discoverer, use artifact handlers instead
+                if ( lastAvceToken.endsWith( ".tar.gz" ) )
+                {
+                    type = "distribution-tgz";
+
+                    lastAvceToken = lastAvceToken.substring( 0, lastAvceToken.length() - ".tar.gz".length() );
+
+                    avceTokenList.addLast( lastAvceToken );
+                }
+                else if ( lastAvceToken.endsWith( "sources.jar" ) )
+                {
+                    type = "java-source";
+
+                    lastAvceToken = lastAvceToken.substring( 0, lastAvceToken.length() - ".jar".length() );
+
+                    avceTokenList.addLast( lastAvceToken );
+                }
+                else if ( lastAvceToken.endsWith( "javadoc.jar" ) )
+                {
+                    type = "javadoc.jar";
+
+                    lastAvceToken = lastAvceToken.substring( 0, lastAvceToken.length() - ".jar".length() );
+
+                    avceTokenList.addLast( lastAvceToken );
+                }
+                else if ( lastAvceToken.endsWith( ".zip" ) )
+                {
+                    type = "distribution-zip";
+
+                    lastAvceToken = lastAvceToken.substring( 0, lastAvceToken.length() - ".zip".length() );
+
+                    avceTokenList.addLast( lastAvceToken );
+                }
+                else
+                {
+                    int extPos = lastAvceToken.lastIndexOf( '.' );
+
+                    if ( extPos > 0 )
+                    {
+                        String ext = lastAvceToken.substring( extPos + 1 );
+                        if ( type.equals( ext ) || "plugin".equals( type ) )
+                        {
+                            lastAvceToken = lastAvceToken.substring( 0, extPos );
+
+                            avceTokenList.addLast( lastAvceToken );
+                        }
+                        else
+                        {
+                            throw new BuilderException( "Path type does not match the extension" );
+                        }
+                    }
+                    else
+                    {
+                        throw new BuilderException( "Path filename does not have an extension" );
+                    }
+                }
+
+                // let's discover the version, and whatever's leftover will be either
+                // a classifier, or part of the artifactId, depending on position.
+                // Since version is at the end, we have to move in from the back.
+                Collections.reverse( avceTokenList );
+
+                // TODO: this is obscene - surely a better way?
+                String validVersionParts = "([Dd][Ee][Vv][_.0-9]*)|" + "([Ss][Nn][Aa][Pp][Ss][Hh][Oo][Tt])|"
+                    + "([0-9][_.0-9a-zA-Z]*)|" + "([Gg]?[_.0-9ab]*([Pp][Rr][Ee]|[Rr][Cc]|[Gg]|[Mm])[_.0-9]*)|"
+                    + "([Aa][Ll][Pp][Hh][Aa][_.0-9]*)|" + "([Bb][Ee][Tt][Aa][_.0-9]*)|" + "([Rr][Cc][_.0-9]*)|"
+                    + "([Tt][Ee][Ss][Tt][_.0-9]*)|" + "([Dd][Ee][Bb][Uu][Gg][_.0-9]*)|"
+                    + "([Uu][Nn][Oo][Ff][Ff][Ii][Cc][Ii][Aa][Ll][_.0-9]*)|" + "([Cc][Uu][Rr][Rr][Ee][Nn][Tt])|"
+                    + "([Ll][Aa][Tt][Ee][Ss][Tt])|" + "([Ff][Cc][Ss])|" + "([Rr][Ee][Ll][Ee][Aa][Ss][Ee][_.0-9]*)|"
+                    + "([Nn][Ii][Gg][Hh][Tt][Ll][Yy])|" + "[Ff][Ii][Nn][Aa][Ll]|" + "([AaBb][_.0-9]*)";
+
+                StringBuffer classifierBuffer = new StringBuffer();
+                StringBuffer versionBuffer = new StringBuffer();
+
+                boolean firstVersionTokenEncountered = false;
+                boolean firstToken = true;
+
+                int tokensIterated = 0;
+                for ( Iterator it = avceTokenList.iterator(); it.hasNext(); )
+                {
+                    String token = (String) it.next();
+
+                    boolean tokenIsVersionPart = token.matches( validVersionParts );
+
+                    StringBuffer bufferToUpdate;
+
+                    // NOTE: logic in code is reversed, since we're peeling off the back
+                    // Any token after the last versionPart will be in the classifier.
+                    // Any token UP TO first non-versionPart is part of the version.
+                    if ( !tokenIsVersionPart )
+                    {
+                        if ( firstVersionTokenEncountered )
+                        {
+                            //noinspection BreakStatement
+                            break;
+                        }
+                        else
+                        {
+                            bufferToUpdate = classifierBuffer;
+                        }
+                    }
+                    else
+                    {
+                        firstVersionTokenEncountered = true;
+
+                        bufferToUpdate = versionBuffer;
+                    }
+
+                    if ( firstToken )
+                    {
+                        firstToken = false;
+                    }
+                    else
+                    {
+                        bufferToUpdate.insert( 0, '-' );
+                    }
+
+                    bufferToUpdate.insert( 0, token );
+
+                    tokensIterated++;
+                }
+
+                // Now, restore the proper ordering so we can build the artifactId.
+                Collections.reverse( avceTokenList );
+
+                // if we didn't find a version, then punt. Use the last token
+                // as the version, and set the classifier empty.
+                if ( versionBuffer.length() < 1 )
+                {
+                    if ( avceTokenList.size() > 1 )
+                    {
+                        int lastIdx = avceTokenList.size() - 1;
+
+                        versionBuffer.append( avceTokenList.get( lastIdx ) );
+                        avceTokenList.remove( lastIdx );
+                    }
+
+                    classifierBuffer.setLength( 0 );
+                }
+                else
+                {
+                    // if everything is kosher, then pop off all the classifier and
+                    // version tokens, leaving the naked artifact id in the list.
+                    avceTokenList = new LinkedList( avceTokenList.subList( 0, avceTokenList.size() - tokensIterated ) );
+                }
+
+                StringBuffer artifactIdBuffer = new StringBuffer();
+
+                firstToken = true;
+                for ( Iterator it = avceTokenList.iterator(); it.hasNext(); )
+                {
+                    String token = (String) it.next();
+
+                    if ( firstToken )
+                    {
+                        firstToken = false;
+                    }
+                    else
+                    {
+                        artifactIdBuffer.append( '-' );
+                    }
+
+                    artifactIdBuffer.append( token );
+                }
+
+                String artifactId = artifactIdBuffer.toString();
+
+                if ( artifactId.length() > 0 )
+                {
+                    int lastVersionCharIdx = versionBuffer.length() - 1;
+                    if ( lastVersionCharIdx > -1 && versionBuffer.charAt( lastVersionCharIdx ) == '-' )
+                    {
+                        versionBuffer.setLength( lastVersionCharIdx );
+                    }
+
+                    String version = versionBuffer.toString();
+
+                    if ( version.length() > 0 )
+                    {
+                        if ( classifierBuffer.length() > 0 )
+                        {
+                            result = artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, type,
+                                                                                   classifierBuffer.toString() );
+                        }
+                        else
+                        {
+                            result = artifactFactory.createArtifact( groupId, artifactId, version,
+                                                                     Artifact.SCOPE_RUNTIME, type );
+                        }
+                    }
+                    else
+                    {
+                        throw new BuilderException( "Path filename version is empty" );
+                    }
+                }
+                else
+                {
+                    throw new BuilderException( "Path filename artifactId is empty" );
+                }
+            }
+            else
+            {
+                throw new BuilderException( "Path artifact type does not corresspond to an artifact type" );
+            }
+        }
+        else
+        {
+            throw new BuilderException( "Path does not match a legacy repository path for an artifact" );
+        }
+
+        return result;
+    }
+}

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/LegacyLayoutArtifactBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/LegacyLayoutArtifactBuilder.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/builders/LegacyLayoutArtifactBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/consumers/AbstractDiscovererConsumer.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/consumers/AbstractDiscovererConsumer.java?view=auto&rev=507550
==============================================================================
--- maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/consumers/AbstractDiscovererConsumer.java (added)
+++ maven/archiva/branches/archiva-MRM-239/archiva-discoverer/src/main/java/org/apache/maven/archiva/discoverer/consumers/AbstractDiscovererConsumer.java Wed Feb 14 06:44:59 2007
@@ -0,0 +1,62 @@
+package org.apache.maven.archiva.discoverer.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.maven.archiva.discoverer.DiscovererConsumer;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * AbstractDiscovererConsumer 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public abstract class AbstractDiscovererConsumer
+    extends AbstractLogEnabled
+    implements DiscovererConsumer
+{
+    /**
+     * @plexus.requirement
+     */
+    protected ArtifactFactory artifactFactory;
+
+    protected ArtifactRepository repository;
+
+    public List getExcludePatterns()
+    {
+        return Collections.EMPTY_LIST;
+    }
+
+    public boolean init( ArtifactRepository repository )
+    {
+        this.repository = repository;
+        return isEnabled();
+    }
+    
+    protected boolean isEnabled()
+    {
+        return true;
+    }
+}