You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@continuum.apache.org by ol...@apache.org on 2008/07/25 00:31:26 UTC

svn commit: r679588 [5/8] - in /continuum/branches/CONTINUUM-782: ./ continuum-api/ continuum-api/src/main/java/org/apache/continuum/purge/ continuum-api/src/main/java/org/apache/continuum/purge/controller/ continuum-api/src/main/java/org/apache/contin...

Added: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/content/ManagedDefaultRepositoryContent.java
URL: http://svn.apache.org/viewvc/continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/content/ManagedDefaultRepositoryContent.java?rev=679588&view=auto
==============================================================================
--- continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/content/ManagedDefaultRepositoryContent.java (added)
+++ continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/content/ManagedDefaultRepositoryContent.java Thu Jul 24 15:31:19 2008
@@ -0,0 +1,440 @@
+package org.apache.continuum.purge.repository.content;
+
+/*
+ * 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;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.continuum.model.repository.LocalRepository;
+import org.apache.continuum.purge.repository.utils.FileTypes;
+import org.apache.maven.archiva.common.utils.PathUtil;
+import org.apache.maven.archiva.common.utils.VersionUtil;
+import org.apache.maven.archiva.model.ArtifactReference;
+import org.apache.maven.archiva.model.ProjectReference;
+import org.apache.maven.archiva.model.VersionedReference;
+import org.apache.maven.archiva.repository.content.ArtifactExtensionMapping;
+import org.apache.maven.archiva.repository.content.DefaultPathParser;
+import org.apache.maven.archiva.repository.content.PathParser;
+import org.apache.maven.archiva.repository.ContentNotFoundException;
+import org.apache.maven.archiva.repository.layout.LayoutException;
+
+/**
+ * Taken from Archiva's ManagedDefaultRepositoryContent and made some few changes.
+ * 
+ * @plexus.component 
+ *      role="org.apache.continuum.purge.repository.content.RepositoryManagedContent"
+ *      role-hint="default"
+ *      instantiation-strategy="per-lookup"
+ */
+public class ManagedDefaultRepositoryContent
+    implements RepositoryManagedContent
+{
+    public static final String MAVEN_METADATA = "maven-metadata.xml";
+
+    protected static final char PATH_SEPARATOR = '/';
+
+    protected static final char GROUP_SEPARATOR = '.';
+
+    protected static final char ARTIFACT_SEPARATOR = '-';
+    
+    private PathParser defaultPathParser = new DefaultPathParser();
+
+    /**
+     * @plexus.requirement role-hint="file-types"
+     */
+    private FileTypes filetypes;
+    
+    private LocalRepository repository;
+    
+    public void deleteVersion( VersionedReference reference )
+        throws ContentNotFoundException
+    {
+        String path = toMetadataPath( reference );
+        File projectPath = new File( getRepoRoot(), path );
+        
+        File projectDir = projectPath.getParentFile();
+        if( projectDir.exists() && projectDir.isDirectory() )
+        {
+            try
+            {
+                FileUtils.deleteDirectory( projectDir );
+            }
+            catch ( IOException e )
+            {
+                // TODO: log this somewhere?
+            }
+        }
+    }
+    
+    public int getId()
+    {
+        return repository.getId();
+    }
+
+    public Set<ArtifactReference> getRelatedArtifacts( ArtifactReference reference )
+        throws ContentNotFoundException, LayoutException
+    {
+        File artifactFile = toFile( reference );
+        File repoDir = artifactFile.getParentFile();
+    
+        if ( !repoDir.exists() )
+        {
+            throw new ContentNotFoundException( "Unable to get related artifacts using a non-existant directory: "
+                + repoDir.getAbsolutePath() );
+        }
+    
+        if ( !repoDir.isDirectory() )
+        {
+            throw new ContentNotFoundException( "Unable to get related artifacts using a non-directory: "
+                + repoDir.getAbsolutePath() );
+        }
+    
+        Set<ArtifactReference> foundArtifacts = new HashSet<ArtifactReference>();
+    
+        // First gather up the versions found as artifacts in the managed repository.
+        File repoFiles[] = repoDir.listFiles();
+        for ( int i = 0; i < repoFiles.length; i++ )
+        {
+            if ( repoFiles[i].isDirectory() )
+            {
+                // Skip it. it's a directory.
+                continue;
+            }
+    
+            String relativePath = PathUtil.getRelative( repository.getLocation(), repoFiles[i] );
+    
+            if ( filetypes.matchesArtifactPattern( relativePath ) )
+            {
+                ArtifactReference artifact = toArtifactReference( relativePath );
+                
+                // Test for related, groupId / artifactId / version must match.
+                if ( artifact.getGroupId().equals( reference.getGroupId() )
+                    && artifact.getArtifactId().equals( reference.getArtifactId() )
+                    && artifact.getVersion().equals( reference.getVersion() ) )
+                {
+                    foundArtifacts.add( artifact );
+                }
+            }
+        }
+    
+        return foundArtifacts;
+    }
+    
+    public String getRepoRoot()
+    {
+        return repository.getLocation();
+    }
+    
+    public LocalRepository getRepository()
+    {
+        return repository;
+    }
+    
+    /**
+     * Gather the Available Versions (on disk) for a specific Project Reference, based on filesystem
+     * information.
+     *
+     * @return the Set of available versions, based on the project reference.
+     * @throws LayoutException 
+     * @throws LayoutException
+     */
+    public Set<String> getVersions( ProjectReference reference )
+        throws ContentNotFoundException, LayoutException
+    {
+        String path = toMetadataPath( reference );
+
+        int idx = path.lastIndexOf( '/' );
+        if ( idx > 0 )
+        {
+            path = path.substring( 0, idx );
+        }
+
+        File repoDir = new File( repository.getLocation(), path );
+
+        if ( !repoDir.exists() )
+        {
+            throw new ContentNotFoundException( "Unable to get Versions on a non-existant directory: "
+                + repoDir.getAbsolutePath() );
+        }
+
+        if ( !repoDir.isDirectory() )
+        {
+            throw new ContentNotFoundException( "Unable to get Versions on a non-directory: "
+                + repoDir.getAbsolutePath() );
+        }
+
+        Set<String> foundVersions = new HashSet<String>();
+        VersionedReference versionRef = new VersionedReference();
+        versionRef.setGroupId( reference.getGroupId() );
+        versionRef.setArtifactId( reference.getArtifactId() );
+
+        File repoFiles[] = repoDir.listFiles();
+        for ( int i = 0; i < repoFiles.length; i++ )
+        {
+            if ( !repoFiles[i].isDirectory() )
+            {
+                // Skip it. not a directory.
+                continue;
+            }
+
+            // Test if dir has an artifact, which proves to us that it is a valid version directory.
+            String version = repoFiles[i].getName();
+            versionRef.setVersion( version );
+
+            if ( hasArtifact( versionRef ) )
+            {
+                // Found an artifact, must be a valid version.
+                foundVersions.add( version );
+            }
+        }
+
+        return foundVersions;
+    }
+
+    public Set<String> getVersions( VersionedReference reference )
+        throws ContentNotFoundException, LayoutException
+    {
+        String path = toMetadataPath( reference );
+
+        int idx = path.lastIndexOf( '/' );
+        if ( idx > 0 )
+        {
+            path = path.substring( 0, idx );
+        }
+
+        File repoDir = new File( repository.getLocation(), path );
+
+        if ( !repoDir.exists() )
+        {
+            throw new ContentNotFoundException( "Unable to get versions on a non-existant directory: "
+                + repoDir.getAbsolutePath() );
+        }
+
+        if ( !repoDir.isDirectory() )
+        {
+            throw new ContentNotFoundException( "Unable to get versions on a non-directory: "
+                + repoDir.getAbsolutePath() );
+        }
+
+        Set<String> foundVersions = new HashSet<String>();
+
+        // First gather up the versions found as artifacts in the managed repository.
+        File repoFiles[] = repoDir.listFiles();
+        for ( int i = 0; i < repoFiles.length; i++ )
+        {
+            if ( repoFiles[i].isDirectory() )
+            {
+                // Skip it. it's a directory.
+                continue;
+            }
+
+            String relativePath = PathUtil.getRelative( repository.getLocation(), repoFiles[i] );
+
+            if ( filetypes.matchesDefaultExclusions( relativePath ) )
+            {
+                // Skip it, it's metadata or similar
+                continue;
+            }
+
+            if ( filetypes.matchesArtifactPattern( relativePath ) )
+            {
+                ArtifactReference artifact = toArtifactReference( relativePath );
+
+                foundVersions.add( artifact.getVersion() );
+            }
+        }
+
+        return foundVersions;
+    }
+
+    
+    public String toMetadataPath( ProjectReference reference )
+    {
+        StringBuffer path = new StringBuffer();
+    
+        path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR );
+        path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
+        path.append( MAVEN_METADATA );
+    
+        return path.toString();
+    }
+    
+    public String toMetadataPath( VersionedReference reference )
+    {
+        StringBuffer path = new StringBuffer();
+    
+        path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR );
+        path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
+        if ( reference.getVersion() != null )
+        {
+            // add the version only if it is present
+            path.append( VersionUtil.getBaseVersion( reference.getVersion() ) ).append( PATH_SEPARATOR );
+        }
+        path.append( MAVEN_METADATA );
+    
+        return path.toString();
+    }
+    
+    public String toPath( ArtifactReference reference )
+    {
+        if ( reference == null )
+        {
+            throw new IllegalArgumentException( "Artifact reference cannot be null" );
+        }
+    
+        String baseVersion = VersionUtil.getBaseVersion( reference.getVersion() );
+        return toPath( reference.getGroupId(), reference.getArtifactId(), baseVersion, reference.getVersion(),
+                       reference.getClassifier(), reference.getType() );
+    }
+
+    public void setRepository( LocalRepository repository )
+    {
+        this.repository = repository;
+    }
+
+    /**
+     * Convert a path to an artifact reference.
+     * 
+     * @param path the path to convert. (relative or full location path)
+     * @throws LayoutException if the path cannot be converted to an artifact reference.
+     */
+    public ArtifactReference toArtifactReference( String path )
+        throws LayoutException
+    {
+        if ( ( path != null ) && path.startsWith( repository.getLocation() ) )
+        {
+            return defaultPathParser.toArtifactReference( path.substring( repository.getLocation().length() ) );
+        }
+
+        return defaultPathParser.toArtifactReference( path );
+    }
+
+    public File toFile( ArtifactReference reference )
+    {
+        return new File( repository.getLocation(), toPath( reference ) );
+    }
+
+    /**
+     * Get the first Artifact found in the provided VersionedReference location.
+     *
+     * @param managedRepository the repository to search within.
+     * @param reference         the reference to the versioned reference to search within
+     * @return the ArtifactReference to the first artifact located within the versioned reference. or null if
+     *         no artifact was found within the versioned reference.
+     * @throws IOException     if the versioned reference is invalid (example: doesn't exist, or isn't a directory)
+     * @throws LayoutException
+     */
+    private ArtifactReference getFirstArtifact( VersionedReference reference )
+        throws LayoutException, IOException
+    {
+        String path = toMetadataPath( reference );
+
+        int idx = path.lastIndexOf( '/' );
+        if ( idx > 0 )
+        {
+            path = path.substring( 0, idx );
+        }
+
+        File repoDir = new File( repository.getLocation(), path );
+
+        if ( !repoDir.exists() )
+        {
+            throw new IOException( "Unable to gather the list of snapshot versions on a non-existant directory: "
+                + repoDir.getAbsolutePath() );
+        }
+
+        if ( !repoDir.isDirectory() )
+        {
+            throw new IOException( "Unable to gather the list of snapshot versions on a non-directory: "
+                + repoDir.getAbsolutePath() );
+        }
+
+        File repoFiles[] = repoDir.listFiles();
+        for ( int i = 0; i < repoFiles.length; i++ )
+        {
+            if ( repoFiles[i].isDirectory() )
+            {
+                // Skip it. it's a directory.
+                continue;
+            }
+
+            String relativePath = PathUtil.getRelative( repository.getLocation(), repoFiles[i] );
+
+            if ( filetypes.matchesArtifactPattern( relativePath ) )
+            {
+                ArtifactReference artifact = toArtifactReference( relativePath );
+
+                return artifact;
+            }
+        }
+
+        // No artifact was found.
+        return null;
+    }
+
+    private boolean hasArtifact( VersionedReference reference )
+        throws LayoutException
+    {
+        try
+        {
+            return ( getFirstArtifact( reference ) != null );
+        }
+        catch ( IOException e )
+        {
+            return false;
+        }
+    }
+    
+    private String formatAsDirectory( String directory )
+    {
+        return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR );
+    }
+    
+    private String toPath( String groupId, String artifactId, String baseVersion, String version, String classifier,
+                           String type )
+    {
+        StringBuffer path = new StringBuffer();
+    
+        path.append( formatAsDirectory( groupId ) ).append( PATH_SEPARATOR );
+        path.append( artifactId ).append( PATH_SEPARATOR );
+    
+        if ( baseVersion != null )
+        {
+            path.append( baseVersion ).append( PATH_SEPARATOR );
+            if ( ( version != null ) && ( type != null ) )
+            {
+                path.append( artifactId ).append( ARTIFACT_SEPARATOR ).append( version );
+    
+                if ( StringUtils.isNotBlank( classifier ) )
+                {
+                    path.append( ARTIFACT_SEPARATOR ).append( classifier );
+                }
+    
+                path.append( GROUP_SEPARATOR ).append( ArtifactExtensionMapping.getExtension( type ) );
+            }
+        }
+    
+        return path.toString();
+    }
+}
\ No newline at end of file

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/content/ManagedDefaultRepositoryContent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/content/ManagedDefaultRepositoryContent.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Revision Id

Added: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/content/ManagedLegacyRepositoryContent.java
URL: http://svn.apache.org/viewvc/continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/content/ManagedLegacyRepositoryContent.java?rev=679588&view=auto
==============================================================================
--- continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/content/ManagedLegacyRepositoryContent.java (added)
+++ continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/content/ManagedLegacyRepositoryContent.java Thu Jul 24 15:31:19 2008
@@ -0,0 +1,480 @@
+package org.apache.continuum.purge.repository.content;
+
+/*
+ * 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.StringUtils;
+import org.apache.continuum.model.repository.LocalRepository;
+import org.apache.continuum.purge.repository.utils.FileTypes;
+import org.apache.maven.archiva.common.utils.PathUtil;
+import org.apache.maven.archiva.model.ArtifactReference;
+import org.apache.maven.archiva.model.ProjectReference;
+import org.apache.maven.archiva.model.VersionedReference;
+import org.apache.maven.archiva.repository.content.ArtifactExtensionMapping;
+import org.apache.maven.archiva.repository.content.PathParser;
+import org.apache.maven.archiva.repository.ContentNotFoundException;
+import org.apache.maven.archiva.repository.layout.LayoutException;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Taken from Archiva's ManagedLegacyRepositoryContent and made some few changes
+ * 
+ * @plexus.component 
+ *      role="org.apache.continuum.purge.repository.content.RepositoryManagedContent"
+ *      role-hint="legacy"
+ *      instantiation-strategy="per-lookup"
+ */
+public class ManagedLegacyRepositoryContent
+    implements RepositoryManagedContent
+{
+    private static final String PATH_SEPARATOR = "/";
+
+    private static final Map<String, String> typeToDirectoryMap;
+
+    static
+    {
+        typeToDirectoryMap = new HashMap<String, String>();
+        typeToDirectoryMap.put( "ejb-client", "ejb" );
+        typeToDirectoryMap.put( ArtifactExtensionMapping.MAVEN_PLUGIN, "maven-plugin" );
+        typeToDirectoryMap.put( ArtifactExtensionMapping.MAVEN_ONE_PLUGIN, "plugin" );
+        typeToDirectoryMap.put( "distribution-tgz", "distribution" );
+        typeToDirectoryMap.put( "distribution-zip", "distribution" );
+        typeToDirectoryMap.put( "javadoc", "javadoc.jar" );
+    }
+
+    /**
+     * @plexus.requirement role-hint="legacy-parser"
+     */
+    private PathParser legacyPathParser;
+    
+    /**
+     * @plexus.requirement role-hint="file-types"
+     */
+    private FileTypes filetypes;
+    
+    private LocalRepository repository;
+    
+    public void deleteVersion( VersionedReference reference )
+        throws ContentNotFoundException
+    {
+        File groupDir = new File( repository.getLocation(), reference.getGroupId() );
+    
+        if ( !groupDir.exists() )
+        {
+            throw new ContentNotFoundException( "Unable to get versions using a non-existant groupId directory: "
+                + groupDir.getAbsolutePath() );
+        }
+    
+        if ( !groupDir.isDirectory() )
+        {
+            throw new ContentNotFoundException( "Unable to get versions using a non-directory: "
+                + groupDir.getAbsolutePath() );
+        }
+    
+        // First gather up the versions found as artifacts in the managed repository.
+        File typeDirs[] = groupDir.listFiles();
+        for ( File typeDir : typeDirs )
+        {
+            if ( !typeDir.isDirectory() )
+            {
+                // Skip it, we only care about directories.
+                continue;
+            }
+    
+            if ( !typeDir.getName().endsWith( "s" ) )
+            {
+                // Skip it, we only care about directories that end in "s".
+            }
+    
+            deleteVersions( typeDir, reference );
+        }
+    }
+    
+    private void deleteVersions( File typeDir, VersionedReference reference )
+    {
+        File repoFiles[] = typeDir.listFiles();
+        for ( File repoFile : repoFiles )
+        {
+            if ( repoFile.isDirectory() )
+            {
+                // Skip it. it's a directory.
+                continue;
+            }
+    
+            String relativePath = PathUtil.getRelative( repository.getLocation(), repoFile );
+    
+            if ( filetypes.matchesArtifactPattern( relativePath ) )
+            {
+                try
+                {
+                    ArtifactReference artifact = toArtifactReference( relativePath );
+                    if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() )
+                        && StringUtils.equals( artifact.getVersion(), reference.getVersion() ) )
+                    {
+                        repoFile.delete();
+                        deleteSupportFiles( repoFile );
+                    }
+                }
+                catch ( LayoutException e )
+                {
+                    /* don't fail the process if there is a bad artifact within the directory. */
+                }
+            }
+        }
+    }
+
+    private void deleteSupportFiles( File repoFile )
+    {
+        deleteSupportFile( repoFile, ".sha1" );
+        deleteSupportFile( repoFile, ".md5" );
+        deleteSupportFile( repoFile, ".asc" );
+        deleteSupportFile( repoFile, ".gpg" );
+    }
+    
+    private void deleteSupportFile( File repoFile, String supportExtension )
+    {
+        File supportFile = new File( repoFile.getAbsolutePath() + supportExtension );
+        if ( supportFile.exists() && supportFile.isFile() )
+        {
+            supportFile.delete();
+        }
+    }
+    
+    public int getId()
+    {
+        return repository.getId();
+    }
+    
+    public Set<ArtifactReference> getRelatedArtifacts( ArtifactReference reference )
+        throws ContentNotFoundException, LayoutException
+    {
+        File artifactFile = toFile( reference );
+        File repoDir = artifactFile.getParentFile();
+    
+        if ( !repoDir.exists() )
+        {
+            throw new ContentNotFoundException( "Unable to get related artifacts using a non-existant directory: "
+                + repoDir.getAbsolutePath() );
+        }
+    
+        if ( !repoDir.isDirectory() )
+        {
+            throw new ContentNotFoundException( "Unable to get related artifacts using a non-directory: "
+                + repoDir.getAbsolutePath() );
+        }
+    
+        Set<ArtifactReference> foundArtifacts = new HashSet<ArtifactReference>();
+    
+        // First gather up the versions found as artifacts in the managed repository.
+        File projectParentDir = repoDir.getParentFile();
+        File typeDirs[] = projectParentDir.listFiles();
+        for ( File typeDir : typeDirs )
+        {
+            if ( !typeDir.isDirectory() )
+            {
+                // Skip it, we only care about directories.
+                continue;
+            }
+    
+            if ( !typeDir.getName().endsWith( "s" ) )
+            {
+                // Skip it, we only care about directories that end in "s".
+            }
+    
+            getRelatedArtifacts( typeDir, reference, foundArtifacts );
+        }
+    
+        return foundArtifacts;
+    }
+    
+    public String getRepoRoot()
+    {
+        return repository.getLocation();
+    }
+    
+    public LocalRepository getRepository()
+    {
+        return repository;
+    }
+    
+    public Set<String> getVersions( ProjectReference reference )
+        throws ContentNotFoundException
+    {
+        File groupDir = new File( repository.getLocation(), reference.getGroupId() );
+    
+        if ( !groupDir.exists() )
+        {
+            throw new ContentNotFoundException( "Unable to get versions using a non-existant groupId directory: "
+                + groupDir.getAbsolutePath() );
+        }
+    
+        if ( !groupDir.isDirectory() )
+        {
+            throw new ContentNotFoundException( "Unable to get versions using a non-directory: "
+                + groupDir.getAbsolutePath() );
+        }
+    
+        Set<String> foundVersions = new HashSet<String>();
+    
+        // First gather up the versions found as artifacts in the managed repository.
+        File typeDirs[] = groupDir.listFiles();
+        for ( File typeDir : typeDirs )
+        {
+            if ( !typeDir.isDirectory() )
+            {
+                // Skip it, we only care about directories.
+                continue;
+            }
+    
+            if ( !typeDir.getName().endsWith( "s" ) )
+            {
+                // Skip it, we only care about directories that end in "s".
+            }
+    
+            getProjectVersions( typeDir, reference, foundVersions );
+        }
+    
+        return foundVersions;
+    }
+    
+    public Set<String> getVersions( VersionedReference reference )
+        throws ContentNotFoundException
+    {
+        File groupDir = new File( repository.getLocation(), reference.getGroupId() );
+    
+        if ( !groupDir.exists() )
+        {
+            throw new ContentNotFoundException( "Unable to get versions using a non-existant groupId directory: "
+                + groupDir.getAbsolutePath() );
+        }
+    
+        if ( !groupDir.isDirectory() )
+        {
+            throw new ContentNotFoundException( "Unable to get versions using a non-directory: "
+                + groupDir.getAbsolutePath() );
+        }
+    
+        Set<String> foundVersions = new HashSet<String>();
+    
+        // First gather up the versions found as artifacts in the managed repository.
+        File typeDirs[] = groupDir.listFiles();
+        for ( File typeDir : typeDirs )
+        {
+            if ( !typeDir.isDirectory() )
+            {
+                // Skip it, we only care about directories.
+                continue;
+            }
+    
+            if ( !typeDir.getName().endsWith( "s" ) )
+            {
+                // Skip it, we only care about directories that end in "s".
+            }
+    
+            getVersionedVersions( typeDir, reference, foundVersions );
+        }
+    
+        return foundVersions;
+    }
+
+    /**
+     * Convert a path to an artifact reference.
+     * 
+     * @param path the path to convert. (relative or full location path)
+     * @throws LayoutException if the path cannot be converted to an artifact reference.
+     */
+    public ArtifactReference toArtifactReference( String path )
+        throws LayoutException
+    {
+        if ( ( path != null ) && path.startsWith( repository.getLocation() ) )
+        {
+            return legacyPathParser.toArtifactReference( path.substring( repository.getLocation().length() ) );
+        }
+    
+        return legacyPathParser.toArtifactReference( path );
+    }
+    
+    public File toFile( ArtifactReference reference )
+    {
+        return new File( repository.getLocation(), toPath( reference ) );
+    }
+    
+    public String toMetadataPath( ProjectReference reference )
+    {
+        // No metadata present in legacy repository.
+        return null;
+    }
+    
+    public String toMetadataPath( VersionedReference reference )
+    {
+        // No metadata present in legacy repository.
+        return null;
+    }
+    
+    public String toPath( ArtifactReference reference )
+    {
+        if ( reference == null )
+        {
+            throw new IllegalArgumentException( "Artifact reference cannot be null" );
+        }
+
+        return toPath( reference.getGroupId(), reference.getArtifactId(), reference.getVersion(), reference
+            .getClassifier(), reference.getType() );
+    }
+    
+    public void setRepository( LocalRepository repo )
+    {
+        this.repository = repo;
+    }
+    
+    private void getProjectVersions( File typeDir, ProjectReference reference, Set<String> foundVersions )
+    {
+        File repoFiles[] = typeDir.listFiles();
+        for ( File repoFile : repoFiles )
+        {
+            if ( repoFile.isDirectory() )
+            {
+                // Skip it. it's a directory.
+                continue;
+            }
+    
+            String relativePath = PathUtil.getRelative( repository.getLocation(), repoFile );
+    
+            if ( filetypes.matchesArtifactPattern( relativePath ) )
+            {
+                try
+                {
+                    ArtifactReference artifact = toArtifactReference( relativePath );
+                    if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() ) )
+                    {
+                        foundVersions.add( artifact.getVersion() );
+                    }
+                }
+                catch ( LayoutException e )
+                {
+                    /* don't fail the process if there is a bad artifact within the directory. */
+                }
+            }
+        }
+    }
+    
+    private void getRelatedArtifacts( File typeDir, ArtifactReference reference, Set<ArtifactReference> foundArtifacts )
+    {
+        File repoFiles[] = typeDir.listFiles();
+        for ( int i = 0; i < repoFiles.length; i++ )
+        {
+            if ( repoFiles[i].isDirectory() )
+            {
+                // Skip it. it's a directory.
+                continue;
+            }
+    
+            String relativePath = PathUtil.getRelative( repository.getLocation(), repoFiles[i] );
+    
+            if ( filetypes.matchesArtifactPattern( relativePath ) )
+            {
+                try
+                {
+                    ArtifactReference artifact = toArtifactReference( relativePath );
+                    if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() )
+                        && artifact.getVersion().startsWith( reference.getVersion() ) )
+                    {
+                        foundArtifacts.add( artifact );
+                    }
+                }
+                catch ( LayoutException e )
+                {
+                    /* don't fail the process if there is a bad artifact within the directory. */
+                }
+            }
+        }
+    }
+    
+    private void getVersionedVersions( File typeDir, VersionedReference reference, Set<String> foundVersions )
+    {
+        File repoFiles[] = typeDir.listFiles();
+        for ( int i = 0; i < repoFiles.length; i++ )
+        {
+            if ( repoFiles[i].isDirectory() )
+            {
+                // Skip it. it's a directory.
+                continue;
+            }
+    
+            String relativePath = PathUtil.getRelative( repository.getLocation(), repoFiles[i] );
+    
+            if ( filetypes.matchesArtifactPattern( relativePath ) )
+            {
+                try
+                {
+                    ArtifactReference artifact = toArtifactReference( relativePath );
+                    if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() )
+                        && artifact.getVersion().startsWith( reference.getVersion() ) )
+                    {
+                        foundVersions.add( artifact.getVersion() );
+                    }
+                }
+                catch ( LayoutException e )
+                {
+                    /* don't fail the process if there is a bad artifact within the directory. */
+                }
+            }
+        }
+    }
+
+    private String toPath( String groupId, String artifactId, String version, String classifier, String type )
+    {
+        StringBuffer path = new StringBuffer();
+
+        path.append( groupId ).append( PATH_SEPARATOR );
+        path.append( getDirectory( classifier, type ) ).append( PATH_SEPARATOR );
+
+        if ( version != null )
+        {
+            path.append( artifactId ).append( '-' ).append( version );
+
+            if ( StringUtils.isNotBlank( classifier ) )
+            {
+                path.append( '-' ).append( classifier );
+            }
+
+            path.append( '.' ).append( ArtifactExtensionMapping.getExtension( type ) );
+        }
+
+        return path.toString();
+    }
+
+    private String getDirectory( String classifier, String type )
+    {
+        String dirname = (String) typeToDirectoryMap.get( type );
+
+        if ( dirname != null )
+        {
+            return dirname + "s";
+        }
+
+        // Default process.
+        return type + "s";
+    }
+}
\ No newline at end of file

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/content/ManagedLegacyRepositoryContent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/content/ManagedLegacyRepositoryContent.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Revision Id

Added: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/scanner/DefaultRepositoryScanner.java
URL: http://svn.apache.org/viewvc/continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/scanner/DefaultRepositoryScanner.java?rev=679588&view=auto
==============================================================================
--- continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/scanner/DefaultRepositoryScanner.java (added)
+++ continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/scanner/DefaultRepositoryScanner.java Thu Jul 24 15:31:19 2008
@@ -0,0 +1,101 @@
+package org.apache.continuum.purge.repository.scanner;
+
+/*
+ * 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;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.continuum.model.repository.LocalRepository;
+import org.apache.continuum.purge.controller.PurgeController;
+import org.apache.continuum.purge.executor.ContinuumPurgeExecutorException;
+import org.apache.continuum.purge.repository.scanner.RepositoryScannerInstance;
+import org.apache.continuum.purge.repository.utils.FileTypes;
+import org.codehaus.plexus.util.DirectoryWalker;
+
+/**
+ * Codes were taken from Archiva and made some changes.
+ * 
+ * @plexus.component role="org.apache.continuum.purge.repository.scanner.RepositoryScanner" role-hint="repository-scanner"
+ */
+public class DefaultRepositoryScanner
+    implements RepositoryScanner
+{
+    /**
+     * @plexus.requirement role-hint="file-types"
+     */
+    private FileTypes filetypes;
+    
+    public void scan( LocalRepository repository, PurgeController purgeController )
+        throws ContinuumPurgeExecutorException
+    {
+        List<String> ignoredPatterns = filetypes.getIgnoredFileTypePatterns();
+        scan( repository, purgeController, ignoredPatterns );
+    }
+    
+    public void scan( LocalRepository repository, PurgeController purgeController,  
+                      List<String> ignoredContentPatterns )
+        throws ContinuumPurgeExecutorException
+    {
+        File repositoryBase = new File ( repository.getLocation() );
+        
+        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<String> allExcludes = new ArrayList<String>();
+        List<String> allIncludes = new ArrayList<String>();
+
+        if ( CollectionUtils.isNotEmpty( ignoredContentPatterns ) )
+        {
+            allExcludes.addAll( ignoredContentPatterns );
+        }
+
+        // Scan All Content. (intentional)
+        allIncludes.add( "**/*" );
+
+        // Setup Directory Walker
+        DirectoryWalker dirWalker = new DirectoryWalker();
+
+        dirWalker.setBaseDir( repositoryBase );
+
+        dirWalker.setIncludes( allIncludes );
+        dirWalker.setExcludes( allExcludes );
+
+        RepositoryScannerInstance scannerInstance = new RepositoryScannerInstance( repository, purgeController );
+        
+        dirWalker.addDirectoryWalkListener( scannerInstance );
+
+        // Execute scan.
+        dirWalker.scan();
+
+    }
+}
\ No newline at end of file

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/scanner/DefaultRepositoryScanner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/scanner/DefaultRepositoryScanner.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Revision Id

Added: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/scanner/RepositoryScannerInstance.java
URL: http://svn.apache.org/viewvc/continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/scanner/RepositoryScannerInstance.java?rev=679588&view=auto
==============================================================================
--- continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/scanner/RepositoryScannerInstance.java (added)
+++ continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/scanner/RepositoryScannerInstance.java Thu Jul 24 15:31:19 2008
@@ -0,0 +1,70 @@
+package org.apache.continuum.purge.repository.scanner;
+
+/*
+ * 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;
+
+import org.apache.continuum.model.repository.LocalRepository;
+import org.apache.continuum.purge.controller.PurgeController;
+import org.apache.maven.archiva.common.utils.BaseFile;
+import org.codehaus.plexus.util.DirectoryWalkListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Codes were taken from Archiva and made some few changes
+ */
+public class RepositoryScannerInstance
+    implements DirectoryWalkListener
+{
+    private Logger log = LoggerFactory.getLogger( RepositoryScannerInstance.class );
+    
+    private LocalRepository repository;
+    
+    private PurgeController purgeController;
+    
+    public RepositoryScannerInstance( LocalRepository repository, PurgeController purgeController )
+    {
+        this.repository = repository;
+        this.purgeController = purgeController;
+    }
+    
+    public void debug( String message )
+    {
+        log.debug( "Repository Scanner: " + message );
+    }
+
+    public void directoryWalkFinished()
+    {
+        log.info( "Walk Finished: [" + this.repository.getId() + "] " + this.repository.getLocation() );
+    }
+
+    public void directoryWalkStarting( File file )
+    {
+        log.info( "Walk started [" + this.repository.getId() + "] " + this.repository.getLocation() );
+    }
+
+    public void directoryWalkStep( int percentage, File file )
+    {
+        BaseFile basefile = new BaseFile( repository.getLocation(), file );
+        purgeController.doPurge( basefile.getRelativePath() );
+    }
+
+}
\ No newline at end of file

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/scanner/RepositoryScannerInstance.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/scanner/RepositoryScannerInstance.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Revision Id

Added: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/FileTypes.java
URL: http://svn.apache.org/viewvc/continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/FileTypes.java?rev=679588&view=auto
==============================================================================
--- continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/FileTypes.java (added)
+++ continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/FileTypes.java Thu Jul 24 15:31:19 2008
@@ -0,0 +1,95 @@
+package org.apache.continuum.purge.repository.utils;
+
+/*
+ * 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.Arrays;
+import java.util.List;
+
+import org.codehaus.plexus.util.SelectorUtils;
+
+/**
+ * Codes were taken from Archiva and made some changes.
+ */
+public class FileTypes
+{
+    private List<String> artifactFileTypePatterns;
+    
+    private List<String> ignoredFileTypePatterns;
+    
+    public static final List<String> DEFAULT_EXCLUSIONS = Arrays.asList( "**/maven-metadata.xml",
+                                                                          "**/maven-metadata-*.xml", "**/*.sha1",
+                                                                          "**/*.asc", "**/*.md5", "**/*.pgp" );
+    
+    public List<String> getIgnoredFileTypePatterns()
+    {
+        if ( ignoredFileTypePatterns == null )
+        {
+            ignoredFileTypePatterns = DEFAULT_EXCLUSIONS;
+        }
+        
+        return ignoredFileTypePatterns;
+    }
+    
+    public List<String> getArtifactFileTypePatterns()
+    {
+        return artifactFileTypePatterns;
+    }
+    
+    public synchronized boolean matchesArtifactPattern( String relativePath )
+    {
+        // Correct the slash pattern.
+        relativePath = relativePath.replace( '\\', '/' );
+
+        if ( artifactFileTypePatterns == null )
+        {
+            return false;
+        }
+
+        for ( String pattern : (List<String>)artifactFileTypePatterns )
+        {
+            if ( SelectorUtils.matchPath( pattern, relativePath, false ) )
+            {
+                // Found match
+                return true;
+            }
+        }
+
+        // No match.
+        return false;
+    }
+
+    public boolean matchesDefaultExclusions( String relativePath )
+    {
+        // Correct the slash pattern.
+        relativePath = relativePath.replace( '\\', '/' );
+
+        for ( String pattern : DEFAULT_EXCLUSIONS )
+        {
+            if ( SelectorUtils.matchPath( pattern, relativePath, false ) )
+            {
+                // Found match
+                return true;
+            }
+        }
+
+        // No match.
+        return false;
+    }    
+}

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/FileTypes.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/FileTypes.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Revision Id

Added: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/FilenameParser.java
URL: http://svn.apache.org/viewvc/continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/FilenameParser.java?rev=679588&view=auto
==============================================================================
--- continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/FilenameParser.java (added)
+++ continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/FilenameParser.java Thu Jul 24 15:31:19 2008
@@ -0,0 +1,144 @@
+package org.apache.continuum.purge.repository.utils;
+
+/*
+ * 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.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.maven.archiva.common.utils.VersionUtil;
+
+/**
+ * Codes were taken from Archiva's FilenameParser
+ */
+public class FilenameParser
+{
+    private String name;
+    
+    private String extension;
+    
+    private int offset;
+    
+    private static final Pattern mavenPluginPattern = Pattern.compile( "(maven-.*-plugin)|(.*-maven-plugin)" );
+
+    private static final Pattern extensionPattern =
+        Pattern.compile( "(\\.tar\\.gz$)|(\\.tar\\.bz2$)|(\\.[\\-a-z0-9]*$)", Pattern.CASE_INSENSITIVE );
+
+    private static final Pattern section = Pattern.compile( "([^-]*)" );
+
+    private Matcher matcher;
+
+    public FilenameParser( String filename )
+    {
+        this.name = filename;
+        
+        Matcher mat = extensionPattern.matcher( name );
+        if ( mat.find() )
+        {
+            extension = filename.substring( mat.start() + 1 );
+            name = name.substring( 0, name.length() - extension.length() - 1 );
+        }
+
+        matcher = section.matcher( name );
+
+        reset();
+    }
+    
+    public void reset()
+    {
+        offset = 0;
+    }
+    
+    public String next()
+    {
+        // Past the end of the string.
+        if ( offset > name.length() )
+        {
+            return null;
+        }
+
+        // Return the next section.
+        if ( matcher.find( offset ) )
+        {
+            // Return found section.
+            offset = matcher.end() + 1;
+            return matcher.group();
+        }
+
+        // Nothing to return.
+        return null;
+    }
+    
+    protected String remaining()
+    {
+        if ( offset >= name.length() )
+        {
+            return null;
+        }
+
+        String end = name.substring( offset );
+        offset = name.length();
+        return end;
+    }
+
+    protected String nextNonVersion()
+    {
+        boolean done = false;
+
+        StringBuffer ver = new StringBuffer();
+
+        // Any text upto the end of a special case is considered non-version. 
+        Matcher specialMat = mavenPluginPattern.matcher( name );
+        if ( specialMat.find() )
+        {
+            ver.append( name.substring( offset, specialMat.end() ) );
+            offset = specialMat.end() + 1;
+        }
+
+        while ( !done )
+        {
+            int initialOffset = offset;
+            String section = next();
+            if ( section == null )
+            {
+                done = true;
+            }
+            else if ( !VersionUtil.isVersion( section ) )
+            {
+                if ( ver.length() > 0 )
+                {
+                    ver.append( '-' );
+                }
+                ver.append( section );
+            }
+            else
+            {
+                offset = initialOffset;
+                done = true;
+            }
+        }
+
+        return ver.toString();
+    }
+    
+    public String getExtension()
+    {
+        return extension;
+    }
+}
\ No newline at end of file

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/FilenameParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/FilenameParser.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Revision Id

Added: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/LegacyPathParser.java
URL: http://svn.apache.org/viewvc/continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/LegacyPathParser.java?rev=679588&view=auto
==============================================================================
--- continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/LegacyPathParser.java (added)
+++ continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/LegacyPathParser.java Thu Jul 24 15:31:19 2008
@@ -0,0 +1,180 @@
+package org.apache.continuum.purge.repository.utils;
+
+/*
+ * 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.StringUtils;
+import org.apache.maven.archiva.model.ArtifactReference;
+import org.apache.maven.archiva.repository.content.ArtifactClassifierMapping;
+import org.apache.maven.archiva.repository.content.ArtifactExtensionMapping;
+import org.apache.maven.archiva.repository.content.PathParser;
+import org.apache.maven.archiva.repository.layout.LayoutException;
+
+/**
+ * Codes were taken from Archiva's LegacyPathParser and made some few changes.
+ * 
+ * @plexus.component role="org.apache.maven.archiva.repository.content.PathParser" role-hint="legacy-parser"
+ */
+public class LegacyPathParser
+    implements PathParser
+{
+    private static final String INVALID_ARTIFACT_PATH = "Invalid path to Artifact: ";
+    
+    public ArtifactReference toArtifactReference( String path )
+        throws LayoutException
+    {
+        ArtifactReference artifact = new ArtifactReference();
+    
+        String normalizedPath = StringUtils.replace( path, "\\", "/" );
+
+        String pathParts[] = StringUtils.split( normalizedPath, '/' );
+
+        /* Always 3 parts. (Never more or less)
+         * 
+         *   path = "commons-lang/jars/commons-lang-2.1.jar"
+         *   path[0] = "commons-lang";          // The Group ID
+         *   path[1] = "jars";                  // The Directory Type
+         *   path[2] = "commons-lang-2.1.jar";  // The Filename.
+         */
+
+        if ( pathParts.length != 3 )
+        {
+            // Illegal Path Parts Length.
+            throw new LayoutException( INVALID_ARTIFACT_PATH
+                    + "legacy paths should only have 3 parts [groupId]/[type]s/[artifactId]-[version].[type], found "
+                    + pathParts.length + " instead." );
+        }
+
+
+        // The Group ID.
+        artifact.setGroupId( pathParts[0] );
+
+        // The Expected Type.
+        String expectedType = pathParts[1];
+
+        // Sanity Check: expectedType should end in "s".
+        if ( !expectedType.endsWith( "s" ) )
+        {
+            throw new LayoutException( INVALID_ARTIFACT_PATH
+                    + "legacy paths should have an expected type ending in [s] in the second part of the path." );
+        }
+
+        // The Filename.
+        String filename = pathParts[2];
+
+        FilenameParser parser = new FilenameParser( filename );
+
+        artifact.setArtifactId( parser.nextNonVersion() );
+
+        // Sanity Check: does it have an artifact id?
+        if ( StringUtils.isEmpty( artifact.getArtifactId() ) )
+        {
+            // Special Case: The filename might start with a version id (like "test-arch-1.0.jar").
+            int idx = filename.indexOf( '-' );
+            if ( idx > 0 )
+            {
+                parser.reset();
+                // Take the first section regardless of content.
+                String artifactId = parser.next();
+
+                // Is there anything more that is considered not a version id?
+                String moreArtifactId = parser.nextNonVersion();
+                if ( StringUtils.isNotBlank( moreArtifactId ) )
+                {
+                    artifact.setArtifactId( artifactId + "-" + moreArtifactId );
+                }
+                else
+                {
+                    artifact.setArtifactId( artifactId );
+                }
+            }
+
+            // Sanity Check: still no artifact id?
+            if ( StringUtils.isEmpty( artifact.getArtifactId() ) )
+            {
+                throw new LayoutException( INVALID_ARTIFACT_PATH + "no artifact id present." );
+            }
+        }
+
+        artifact.setVersion( parser.remaining() );
+
+        // Sanity Check: does it have a version?
+        if ( StringUtils.isEmpty( artifact.getVersion() ) )
+        {
+            // Special Case: use last section of artifactId as version.
+            String artifactId = artifact.getArtifactId();
+            int idx = artifactId.lastIndexOf( '-' );
+            if ( idx > 0 )
+            {
+                artifact.setVersion( artifactId.substring( idx + 1 ) );
+                artifact.setArtifactId( artifactId.substring( 0, idx ) );
+            }
+            else
+            {
+                throw new LayoutException( INVALID_ARTIFACT_PATH + "no version found." );
+            }
+        }
+
+        String classifier = ArtifactClassifierMapping.getClassifier( expectedType );
+        if ( classifier != null )
+        {
+            String version = artifact.getVersion();
+            if ( ! version.endsWith( "-" + classifier ) )
+            {
+                throw new LayoutException( INVALID_ARTIFACT_PATH + expectedType + " artifacts must use the classifier " + classifier );
+            }
+            version = version.substring( 0, version.length() - classifier.length() - 1 );
+            artifact.setVersion( version );
+            artifact.setClassifier( classifier );
+        }
+
+        String extension = parser.getExtension();
+
+        // Set Type
+        String defaultExtension = expectedType.substring( 0, expectedType.length() - 1 );
+        artifact.setType(
+            ArtifactExtensionMapping.mapExtensionAndClassifierToType( classifier, extension, defaultExtension ) );
+
+        // Sanity Check: does it have an extension?
+        if ( StringUtils.isEmpty( artifact.getType() ) )
+        {
+            throw new LayoutException( INVALID_ARTIFACT_PATH + "no extension found." );
+        }
+
+        // Special Case with Maven Plugins
+        if ( StringUtils.equals( "jar", extension ) && StringUtils.equals( "plugins", expectedType ) )
+        {
+            artifact.setType( ArtifactExtensionMapping.MAVEN_ONE_PLUGIN );
+        }
+        else
+        {
+            // Sanity Check: does extension match pathType on path?
+            String expectedExtension = ArtifactExtensionMapping.getExtension( artifact.getType() );
+
+            if ( !expectedExtension.equals( extension ) )
+            {
+                throw new LayoutException( INVALID_ARTIFACT_PATH + "mismatch on extension [" + extension
+                    + "] and layout specified type [" + artifact.getType() + "] (which maps to extension: ["
+                    + expectedExtension + "]) on path [" + path + "]" );
+            }
+        }
+
+        return artifact;
+    }
+}
\ No newline at end of file

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/LegacyPathParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/repository/utils/LegacyPathParser.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Revision Id

Added: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/task/PurgeTask.java
URL: http://svn.apache.org/viewvc/continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/task/PurgeTask.java?rev=679588&view=auto
==============================================================================
--- continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/task/PurgeTask.java (added)
+++ continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/task/PurgeTask.java Thu Jul 24 15:31:19 2008
@@ -0,0 +1,67 @@
+package org.apache.continuum.purge.task;
+
+/*
+ * 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.codehaus.plexus.taskqueue.Task;
+
+/**
+ * @author Maria Catherine Tan
+ */
+public class PurgeTask
+    implements Task
+{
+    private int purgeConfigurationId;
+    
+    private long timestamp;
+    
+    private long maxExecutionTime;
+
+    public PurgeTask( int purgeConfigurationId )
+    {
+        this.purgeConfigurationId = purgeConfigurationId;
+        
+        this.timestamp = System.currentTimeMillis();
+    }
+    
+    public int getPurgeConfigurationId()
+    {
+        return purgeConfigurationId;
+    }
+    
+    public void setPurgeConfigurationId( int purgeConfigurationId )
+    {
+        this.purgeConfigurationId = purgeConfigurationId;
+    }
+    
+    public void setMaxExecutionTime( long maxExecutionTime )
+    {
+        this.maxExecutionTime = maxExecutionTime;
+    }
+    
+    public long getMaxExecutionTime()
+    {
+        return maxExecutionTime;
+    }
+    
+    public long getTimestamp()
+    {
+        return timestamp;
+    }
+}

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/task/PurgeTask.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/task/PurgeTask.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Revision Id

Added: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/task/PurgeTaskExecutor.java
URL: http://svn.apache.org/viewvc/continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/task/PurgeTaskExecutor.java?rev=679588&view=auto
==============================================================================
--- continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/task/PurgeTaskExecutor.java (added)
+++ continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/task/PurgeTaskExecutor.java Thu Jul 24 15:31:19 2008
@@ -0,0 +1,120 @@
+package org.apache.continuum.purge.task;
+
+/*
+ * 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.continuum.model.repository.AbstractPurgeConfiguration;
+import org.apache.continuum.model.repository.DirectoryPurgeConfiguration;
+import org.apache.continuum.model.repository.LocalRepository;
+import org.apache.continuum.model.repository.RepositoryPurgeConfiguration;
+import org.apache.continuum.purge.PurgeConfigurationService;
+import org.apache.continuum.purge.controller.PurgeController;
+import org.apache.continuum.purge.executor.ContinuumPurgeExecutorException;
+import org.apache.continuum.purge.repository.scanner.RepositoryScanner;
+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;
+import org.codehaus.plexus.taskqueue.Task;
+import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
+import org.codehaus.plexus.taskqueue.execution.TaskExecutor;
+
+/**
+ * @author Maria Catherine Tan
+ */
+public class PurgeTaskExecutor
+    implements TaskExecutor, Contextualizable
+{
+    private PurgeController purgeController;
+
+    /**
+     * @plexus.requirement
+     */
+    private PurgeConfigurationService purgeConfigurationService;
+    
+    /**
+     * @plexus.requirement
+     */
+    private RepositoryScanner scanner;
+    
+    private PlexusContainer container;
+    
+    public void executeTask( Task task )
+        throws TaskExecutionException
+    {
+        PurgeTask purgeTask = (PurgeTask) task;
+        
+        AbstractPurgeConfiguration purgeConfig = purgeConfigurationService.getPurgeConfiguration( purgeTask.getPurgeConfigurationId() );
+        
+        try
+        {
+            if ( purgeConfig != null && purgeConfig instanceof RepositoryPurgeConfiguration )
+            {
+                RepositoryPurgeConfiguration repoPurge = (RepositoryPurgeConfiguration) purgeConfig;
+                
+                LocalRepository repository = repoPurge.getRepository();
+                
+                if ( repository == null )
+                {
+                    throw new TaskExecutionException( "Error while executing purge repository task: no repository set" );
+                }
+        
+                purgeController = (PurgeController) container.lookup( PurgeController.ROLE, "purge-repository" );
+                
+                purgeController.initializeExecutors( repoPurge );
+                
+                if ( repoPurge.isDeleteAll() )
+                {
+                    purgeController.doPurge( repository.getLocation() );
+                }
+                else
+                {
+                    scanner.scan( repository, purgeController );
+                }
+            }
+            else if ( purgeConfig != null && purgeConfig instanceof DirectoryPurgeConfiguration )
+            {
+                DirectoryPurgeConfiguration dirPurge = (DirectoryPurgeConfiguration) purgeConfig;
+                
+                purgeController = (PurgeController) container.lookup( PurgeController.ROLE, "purge-directory" );
+                
+                purgeController.initializeExecutors( dirPurge );
+                
+                purgeController.doPurge( dirPurge.getLocation() );            
+            }
+            
+        }
+        catch ( ComponentLookupException e )
+        {
+            throw new TaskExecutionException( "Error while executing purge task", e );
+        }
+        catch ( ContinuumPurgeExecutorException e )
+        {
+            throw new TaskExecutionException( "Error while executing purge task", e );
+        }
+    }
+
+    public void contextualize( Context context )
+        throws ContextException
+    {
+        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
+    }
+}
\ No newline at end of file

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/task/PurgeTaskExecutor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/java/org/apache/continuum/purge/task/PurgeTaskExecutor.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Revision Id

Added: continuum/branches/CONTINUUM-782/continuum-purge/src/main/resources/META-INF/plexus/components.xml
URL: http://svn.apache.org/viewvc/continuum/branches/CONTINUUM-782/continuum-purge/src/main/resources/META-INF/plexus/components.xml?rev=679588&view=auto
==============================================================================
--- continuum/branches/CONTINUUM-782/continuum-purge/src/main/resources/META-INF/plexus/components.xml (added)
+++ continuum/branches/CONTINUUM-782/continuum-purge/src/main/resources/META-INF/plexus/components.xml Thu Jul 24 15:31:19 2008
@@ -0,0 +1,103 @@
+<!--
+  ~ 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.
+  -->
+
+<component-set>
+  <components>
+  
+    <!--
+     |
+     | Purge Task Queue
+     |
+     |-->
+    
+    <component>
+      <role>org.codehaus.plexus.taskqueue.TaskQueue</role>
+      <role-hint>purge</role-hint>
+      <implementation>org.codehaus.plexus.taskqueue.DefaultTaskQueue</implementation>
+      <lifecycle-handler>plexus-configurable</lifecycle-handler>
+      <configuration>
+        <task-entry-evaluators>
+        </task-entry-evaluators>
+        <task-exit-evaluators>
+        </task-exit-evaluators>
+        <task-viability-evaluators>
+        </task-viability-evaluators>
+      </configuration>
+    </component>
+    
+    <component>
+      <role>org.codehaus.plexus.taskqueue.execution.TaskExecutor</role>
+      <role-hint>purge</role-hint>
+      <implementation>org.apache.continuum.purge.task.PurgeTaskExecutor</implementation>
+      <requirements>
+        <requirement>
+          <role>org.apache.continuum.purge.PurgeConfigurationService</role>
+          <role-hint>default</role-hint>
+        </requirement>
+        <requirement>
+          <role>org.apache.continuum.purge.repository.scanner.RepositoryScanner</role>
+          <role-hint>repository-scanner</role-hint>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor</role>
+      <role-hint>purge</role-hint>
+      <implementation>org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor</implementation>
+      <instantiation-strategy>singleton</instantiation-strategy>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.taskqueue.execution.TaskExecutor</role>
+          <role-hint>purge</role-hint>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.taskqueue.TaskQueue</role>
+          <role-hint>purge</role-hint>
+        </requirement>
+      </requirements>
+      <configuration>
+        <name>purge</name>
+      </configuration>
+    </component>
+    
+    <component>
+      <role>org.apache.continuum.purge.repository.utils.FileTypes</role>
+      <role-hint>file-types</role-hint>
+      <implementation>org.apache.continuum.purge.repository.utils.FileTypes</implementation>
+      <configuration>
+        <artifactFileTypePatterns>
+          <artifactFileTypePattern>**/*.pom</artifactFileTypePattern>
+          <artifactFileTypePattern>**/*.jar</artifactFileTypePattern>
+          <artifactFileTypePattern>**/*.ear</artifactFileTypePattern>
+          <artifactFileTypePattern>**/*.war</artifactFileTypePattern>
+          <artifactFileTypePattern>**/*.car</artifactFileTypePattern>
+          <artifactFileTypePattern>**/*.sar</artifactFileTypePattern>
+          <artifactFileTypePattern>**/*.mar</artifactFileTypePattern>
+          <artifactFileTypePattern>**/*.rar</artifactFileTypePattern>
+          <artifactFileTypePattern>**/*.dtd</artifactFileTypePattern>
+          <artifactFileTypePattern>**/*.tld</artifactFileTypePattern>
+          <artifactFileTypePattern>**/*.tar.gz</artifactFileTypePattern>
+          <artifactFileTypePattern>**/*.tar.bz2</artifactFileTypePattern>
+          <artifactFileTypePattern>**/*.zip</artifactFileTypePattern>
+        </artifactFileTypePatterns>
+      </configuration>
+    </component>
+  </components>
+</component-set>
\ No newline at end of file

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/resources/META-INF/plexus/components.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/main/resources/META-INF/plexus/components.xml
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: continuum/branches/CONTINUUM-782/continuum-purge/src/test/java/org/apache/continuum/purge/AbstractPurgeTest.java
URL: http://svn.apache.org/viewvc/continuum/branches/CONTINUUM-782/continuum-purge/src/test/java/org/apache/continuum/purge/AbstractPurgeTest.java?rev=679588&view=auto
==============================================================================
--- continuum/branches/CONTINUUM-782/continuum-purge/src/test/java/org/apache/continuum/purge/AbstractPurgeTest.java (added)
+++ continuum/branches/CONTINUUM-782/continuum-purge/src/test/java/org/apache/continuum/purge/AbstractPurgeTest.java Thu Jul 24 15:31:19 2008
@@ -0,0 +1,257 @@
+package org.apache.continuum.purge;
+
+/*
+ * 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;
+import java.net.URL;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+
+import org.apache.continuum.model.repository.DirectoryPurgeConfiguration;
+import org.apache.continuum.model.repository.LocalRepository;
+import org.apache.continuum.model.repository.RepositoryPurgeConfiguration;
+import org.apache.maven.continuum.jdo.MemoryJdoFactory;
+import org.apache.maven.continuum.store.ContinuumStore;
+import org.codehaus.plexus.jdo.JdoFactory;
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+import org.jpox.SchemaTool;
+
+/**
+ * @author Maria Catherine Tan
+ */
+public abstract class AbstractPurgeTest
+    extends PlexusInSpringTestCase
+{   
+    private static final String TEST_DEFAULT_REPO_DIR = "target/default-repository";
+    
+    private static final String TEST_DEFAULT_REPO_NAME = "defaultRepo";
+    
+    private static final String TEST_DEFAULT_RELEASES_DIR = "target/working-directory";
+    
+    private static final String TEST_DEFAULT_BUILDOUTPUT_DIR = "target/build-output-directory";
+    
+    protected static final int TEST_DAYS_OLDER = 30;
+    
+    protected static final int TEST_RETENTION_COUNT = 2;
+    
+    protected static final String TEST_RELEASES_DIRECTORY_TYPE = "releases";
+    
+    protected static final String TEST_BUILDOUTPUT_DIRECTORY_TYPE = "buildOutput";
+    
+    private ContinuumStore store;
+    
+    protected RepositoryPurgeConfiguration defaultRepoPurge;
+    
+    protected DirectoryPurgeConfiguration defaultReleasesDirPurge;
+    
+    protected DirectoryPurgeConfiguration defaultBuildOutputDirPurge;
+    
+    protected LocalRepository defaultRepository;
+    
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+    
+        getStore();        
+        
+        if ( store.getAllLocalRepositories().size() == 0 )
+        {
+            createDefaultRepository();
+            assertEquals( "check # repository", 1, store.getAllLocalRepositories().size() );
+            createDefaultRepoPurgeConfiguration();
+        }
+        else
+        {
+            assertEquals( "check # repository", 1, store.getAllLocalRepositories().size() );
+            defaultRepository = store.getLocalRepositoryByName( TEST_DEFAULT_REPO_NAME );
+            defaultRepoPurge = store.getRepositoryPurgeConfigurationsByLocalRepository( defaultRepository.getId() ).get( 0 );
+        }
+        
+        if ( store.getDirectoryPurgeConfigurationsByType( TEST_RELEASES_DIRECTORY_TYPE ).size() == 0 )
+        {
+            createDefaultReleasesDirPurgeConfiguration();
+        }
+        else
+        {
+            defaultReleasesDirPurge = store.getDirectoryPurgeConfigurationsByType( TEST_RELEASES_DIRECTORY_TYPE ).get( 0 );
+        }
+        
+        if ( store.getDirectoryPurgeConfigurationsByType( TEST_BUILDOUTPUT_DIRECTORY_TYPE ).size() == 0 )
+        {
+            createDefaultBuildOutputDirPurgeConfiguration();
+        }
+        else
+        {
+            defaultBuildOutputDirPurge = store.getDirectoryPurgeConfigurationsByType( TEST_BUILDOUTPUT_DIRECTORY_TYPE ).get( 0 );
+        }
+    }
+    
+    protected ContinuumStore getStore()
+        throws Exception
+    {
+        if ( store != null )
+        {
+            return store;
+        }
+    
+        // ----------------------------------------------------------------------
+        // Set up the JDO factory
+        // ----------------------------------------------------------------------
+    
+        Object o = lookup( JdoFactory.ROLE, "continuum" );
+    
+        assertEquals( MemoryJdoFactory.class.getName(), o.getClass().getName() );
+    
+        MemoryJdoFactory jdoFactory = (MemoryJdoFactory) o;
+        
+        String url = "jdbc:hsqldb:mem:" + getClass().getName() + "." + getName();
+    
+        jdoFactory.setUrl( url );
+    
+        jdoFactory.reconfigure();
+        
+        // ----------------------------------------------------------------------
+        // Check the configuration
+        // ----------------------------------------------------------------------
+        
+        PersistenceManagerFactory pmf = jdoFactory.getPersistenceManagerFactory();
+    
+        assertNotNull( pmf );
+    
+        assertEquals( url, pmf.getConnectionURL() );
+    
+        PersistenceManager pm = pmf.getPersistenceManager();
+    
+        pm.close();
+        
+        // ----------------------------------------------------------------------
+        //
+        // ----------------------------------------------------------------------
+    
+        Properties properties = jdoFactory.getProperties();
+    
+        for ( Map.Entry entry : properties.entrySet() )
+        {
+            System.setProperty( (String) entry.getKey(), (String) entry.getValue() );
+        }
+    
+        SchemaTool.createSchemaTables( new URL[]{getClass().getResource( "/META-INF/package.jdo" )}, new URL[]{}, null,
+                                       false, null );
+    
+        // ----------------------------------------------------------------------
+        //
+        // ----------------------------------------------------------------------
+    
+        store = (ContinuumStore) lookup( ContinuumStore.ROLE, "jdo" );
+    
+        return store;
+    }
+    
+    protected File getDefaultRepositoryLocation()
+        throws Exception
+    {
+        File repositoryLocation = getTestFile( TEST_DEFAULT_REPO_DIR );
+        
+        if ( !repositoryLocation.exists() )
+        {
+            repositoryLocation.mkdirs();
+        }
+        
+        return repositoryLocation;
+    }
+    
+    protected File getReleasesDirectoryLocation()
+    {
+        File releasesDirectory = getTestFile( TEST_DEFAULT_RELEASES_DIR );
+        
+        if ( !releasesDirectory.exists() )
+        {
+            releasesDirectory.mkdir();
+        }
+        
+        return releasesDirectory;
+    }
+    
+    protected File getBuildOutputDirectoryLocation()
+    {
+        File buildOutputDir = getTestFile( TEST_DEFAULT_BUILDOUTPUT_DIR );
+        
+        if ( !buildOutputDir.exists() )
+        {
+            buildOutputDir.mkdir();
+        }
+        
+        return buildOutputDir;
+    }
+
+    private void createDefaultRepository()
+        throws Exception
+    {
+        defaultRepository = store.getLocalRepositoryByName( TEST_DEFAULT_REPO_NAME );
+        
+        if ( defaultRepository == null )
+        {
+            LocalRepository repository = new LocalRepository();
+            
+            repository.setName( TEST_DEFAULT_REPO_NAME );
+            repository.setLocation( getDefaultRepositoryLocation().getAbsolutePath() );
+            defaultRepository = store.addLocalRepository( repository );
+        }
+    }
+    
+    private void createDefaultRepoPurgeConfiguration()
+        throws Exception
+    {
+        RepositoryPurgeConfiguration repoPurge = new RepositoryPurgeConfiguration();
+        
+        repoPurge.setRepository( defaultRepository );
+        repoPurge.setDeleteAll( true );
+        
+        defaultRepoPurge = store.addRepositoryPurgeConfiguration(  repoPurge );
+    }
+    
+    private void createDefaultReleasesDirPurgeConfiguration()
+        throws Exception
+    {
+        DirectoryPurgeConfiguration dirPurge = new DirectoryPurgeConfiguration();
+        
+        dirPurge.setLocation( getReleasesDirectoryLocation().getAbsolutePath() );
+        dirPurge.setDirectoryType( "releases" );
+        dirPurge.setDeleteAll( true );
+        
+        defaultReleasesDirPurge = store.addDirectoryPurgeConfiguration( dirPurge );
+    }
+    
+    private void createDefaultBuildOutputDirPurgeConfiguration()
+        throws Exception
+    {
+        DirectoryPurgeConfiguration dirPurge = new DirectoryPurgeConfiguration();
+        
+        dirPurge.setLocation( getBuildOutputDirectoryLocation().getAbsolutePath() );
+        dirPurge.setDirectoryType( "buildOutput" );
+        dirPurge.setDeleteAll( true );
+        
+        defaultBuildOutputDirPurge = store.addDirectoryPurgeConfiguration( dirPurge );
+    }
+}

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/test/java/org/apache/continuum/purge/AbstractPurgeTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: continuum/branches/CONTINUUM-782/continuum-purge/src/test/java/org/apache/continuum/purge/AbstractPurgeTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Revision Id