You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by jd...@apache.org on 2006/02/14 22:33:06 UTC

svn commit: r377837 - in /maven/shared/trunk: ./ file-management/ file-management/src/ file-management/src/main/ file-management/src/main/java/ file-management/src/main/java/org/ file-management/src/main/java/org/apache/ file-management/src/main/java/o...

Author: jdcasey
Date: Tue Feb 14 13:33:03 2006
New Revision: 377837

URL: http://svn.apache.org/viewcvs?rev=377837&view=rev
Log:
Adding file-managemement, which includes handling for FileSet's.

Added:
    maven/shared/trunk/file-management/
    maven/shared/trunk/file-management/pom.xml   (with props)
    maven/shared/trunk/file-management/src/
    maven/shared/trunk/file-management/src/main/
    maven/shared/trunk/file-management/src/main/java/
    maven/shared/trunk/file-management/src/main/java/org/
    maven/shared/trunk/file-management/src/main/java/org/apache/
    maven/shared/trunk/file-management/src/main/java/org/apache/maven/
    maven/shared/trunk/file-management/src/main/java/org/apache/maven/shared/
    maven/shared/trunk/file-management/src/main/java/org/apache/maven/shared/model/
    maven/shared/trunk/file-management/src/main/java/org/apache/maven/shared/model/fileset/
    maven/shared/trunk/file-management/src/main/java/org/apache/maven/shared/model/fileset/util/
    maven/shared/trunk/file-management/src/main/java/org/apache/maven/shared/model/fileset/util/FileSetUtils.java   (with props)
    maven/shared/trunk/file-management/src/main/mdo/
    maven/shared/trunk/file-management/src/main/mdo/fileset.mdo   (with props)
    maven/shared/trunk/file-management/src/test/
    maven/shared/trunk/file-management/src/test/java/
    maven/shared/trunk/file-management/src/test/java/org/
    maven/shared/trunk/file-management/src/test/java/org/apache/
    maven/shared/trunk/file-management/src/test/java/org/apache/maven/
    maven/shared/trunk/file-management/src/test/java/org/apache/maven/shared/
    maven/shared/trunk/file-management/src/test/java/org/apache/maven/shared/model/
    maven/shared/trunk/file-management/src/test/java/org/apache/maven/shared/model/fileset/
    maven/shared/trunk/file-management/src/test/java/org/apache/maven/shared/model/fileset/util/
    maven/shared/trunk/file-management/src/test/java/org/apache/maven/shared/model/fileset/util/FileSetUtilsTest.java   (with props)
    maven/shared/trunk/file-management/src/test/resources/
    maven/shared/trunk/file-management/src/test/resources/testDelete/
    maven/shared/trunk/file-management/src/test/resources/testDelete/excluded.txt   (with props)
    maven/shared/trunk/file-management/src/test/resources/testDelete/included.txt   (with props)
    maven/shared/trunk/file-management/src/test/resources/testDelete/subdir/
    maven/shared/trunk/file-management/src/test/resources/testDelete/subdir/included.txt   (with props)
    maven/shared/trunk/file-management/src/test/resources/testDeleteDontFollowSymlinks/
    maven/shared/trunk/file-management/src/test/resources/testDeleteDontFollowSymlinks/included.txt   (with props)
    maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/
    maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/otherStuff/
    maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/otherStuff/excluded.txt   (with props)
    maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/
    maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/excluded.txt   (with props)
    maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/included.txt   (with props)
    maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/
    maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/excluded.txt   (with props)
    maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/included.txt   (with props)
Modified:
    maven/shared/trunk/pom.xml

Added: maven/shared/trunk/file-management/pom.xml
URL: http://svn.apache.org/viewcvs/maven/shared/trunk/file-management/pom.xml?rev=377837&view=auto
==============================================================================
--- maven/shared/trunk/file-management/pom.xml (added)
+++ maven/shared/trunk/file-management/pom.xml Tue Feb 14 13:33:03 2006
@@ -0,0 +1,59 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+  xsi:noNamespaceSchemaLocation="http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+  
+  <parent>
+    <groupId>org.apache.maven.shared</groupId>
+    <artifactId>shared-components-parent</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>file-management</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  
+  <name>Maven Shared File Management API</name>
+  <description>Basic API for lightweight logging</description>
+  
+  <contributors>
+    <contributor>
+      <name>Joakim Erdfelt</name>
+      <email>joakim@erdfelt.com</email>
+    </contributor>
+  </contributors>
+  
+  <dependencies>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-utils</artifactId>
+      <version>1.0.4</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.modello</groupId>
+        <artifactId>modello-maven-plugin</artifactId>
+        <configuration>
+          <version>1.0.0</version>
+        </configuration>
+        <executions>
+          <execution>
+            <id>fileset</id>
+            <goals>
+              <goal>xpp3-reader</goal>
+              <goal>xpp3-writer</goal>
+              <goal>java</goal>
+              <goal>xsd</goal>
+            </goals>
+            <configuration>
+              <model>src/main/mdo/fileset.mdo</model>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>

Propchange: maven/shared/trunk/file-management/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/shared/trunk/file-management/pom.xml
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/shared/trunk/file-management/src/main/java/org/apache/maven/shared/model/fileset/util/FileSetUtils.java
URL: http://svn.apache.org/viewcvs/maven/shared/trunk/file-management/src/main/java/org/apache/maven/shared/model/fileset/util/FileSetUtils.java?rev=377837&view=auto
==============================================================================
--- maven/shared/trunk/file-management/src/main/java/org/apache/maven/shared/model/fileset/util/FileSetUtils.java (added)
+++ maven/shared/trunk/file-management/src/main/java/org/apache/maven/shared/model/fileset/util/FileSetUtils.java Tue Feb 14 13:33:03 2006
@@ -0,0 +1,298 @@
+package org.apache.maven.shared.model.fileset.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.shared.model.fileset.FileSet;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.FileUtils;
+
+public final class FileSetUtils
+{
+    
+    private static final int DELETE_RETRY_SLEEP_MILLIS = 10;
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+    private FileSetUtils()
+    {
+        // deny construction.
+    }
+    
+    public static String[] getIncludedFiles( FileSet fileSet )
+    {
+        DirectoryScanner scanner = scan( fileSet );
+        
+        if ( scanner != null )
+        {
+            return scanner.getIncludedFiles();
+        }        
+        else
+        {
+            return EMPTY_STRING_ARRAY;
+        }
+    }
+
+    public static String[] getIncludedDirectories( FileSet fileSet )
+    {
+        DirectoryScanner scanner = scan( fileSet );
+        
+        if ( scanner != null )
+        {
+            return scanner.getIncludedDirectories();
+        }        
+        else
+        {
+            return EMPTY_STRING_ARRAY;
+        }
+    }
+
+    public static String[] getExcludedFiles( FileSet fileSet )
+    {
+        DirectoryScanner scanner = scan( fileSet );
+        
+        if ( scanner != null )
+        {
+            return scanner.getExcludedFiles();
+        }        
+        else
+        {
+            return EMPTY_STRING_ARRAY;
+        }
+    }
+
+    public static String[] getExcludedDirectories( FileSet fileSet )
+    {
+        DirectoryScanner scanner = scan( fileSet );
+        
+        if ( scanner != null )
+        {
+            return scanner.getExcludedDirectories();
+        }        
+        else
+        {
+            return EMPTY_STRING_ARRAY;
+        }
+    }
+    
+    public static void delete( FileSet fileSet ) throws IOException
+    {
+        Set deletablePaths = findDeletablePaths( fileSet );
+        
+        for ( Iterator it = deletablePaths.iterator(); it.hasNext(); )
+        {
+            String path = (String) it.next();
+            
+            File file = new File( fileSet.getDirectory(), path );
+            
+            if ( file.exists() )
+            {
+                if ( file.isDirectory() && ( fileSet.isFollowSymlinks() || !isSymlink( file ) ) )
+                {
+                    FileUtils.deleteDirectory( file );
+                }
+                else
+                {
+                    if ( !delete( file ) )
+                    {
+                        throw new IOException( "Failed to delete file: " + file + ". Reason is unknown." );
+                    }
+                }
+            }            
+        }
+    }
+    
+    private static boolean isSymlink( File file ) throws IOException
+    {
+        File parent = file.getParentFile();
+        File canonicalFile = file.getCanonicalFile();
+        
+        return parent != null && ( !canonicalFile.getName().equals( file.getName() ) || !canonicalFile.getPath().startsWith( parent.getCanonicalPath() ) );
+    }
+
+    private static Set findDeletablePaths( FileSet fileSet )
+    {
+        Set includes = findDeletableDirectories( fileSet );
+        includes.addAll( findDeletableFiles( fileSet, includes ) );
+        
+        return includes;
+    }
+
+    private static Set findDeletableDirectories( FileSet fileSet )
+    {
+        DirectoryScanner scanner = scan( fileSet );
+        
+        if ( scanner == null )
+        {
+            return Collections.EMPTY_SET;
+        }
+        
+        String[] includedDirs = scanner.getIncludedDirectories();
+        String[] excludedDirs = scanner.getExcludedDirectories();
+        
+        Set includes = new HashSet( Arrays.asList( includedDirs ) );
+        List excludes = new ArrayList( Arrays.asList( excludedDirs ) );
+        List linksForDeletion = new ArrayList();
+        
+        if ( !fileSet.isFollowSymlinks() )
+        {
+            // we need to see which entries were excluded because they're symlinks...
+            scanner.setFollowSymlinks( true );
+            scanner.scan();
+            
+            List notSymlinks = Arrays.asList( scanner.getIncludedDirectories() );
+            
+            linksForDeletion.addAll( excludes );
+            linksForDeletion.retainAll( notSymlinks );
+            
+            excludes.removeAll( notSymlinks );
+        }
+        
+        for ( int i = 0; i < excludedDirs.length; i++ )
+        {
+            String path = excludedDirs[i];
+            
+            File excluded = new File( path );
+            
+            String parentPath = excluded.getParent();
+            
+            while( parentPath != null )
+            {
+                includes.remove( parentPath );
+                
+                parentPath = new File( parentPath ).getParent();
+            }
+        }
+        
+        includes.addAll( linksForDeletion );
+        
+        return includes;
+    }
+
+    private static Set findDeletableFiles( FileSet fileSet, Set deletableDirectories )
+    {
+        DirectoryScanner scanner = scan( fileSet );
+        
+        if ( scanner == null )
+        {
+            return deletableDirectories;
+        }
+        
+        String[] includedFiles = scanner.getIncludedFiles();
+        String[] excludedFiles = scanner.getExcludedFiles();
+        
+        Set includes = deletableDirectories;
+        includes.addAll( Arrays.asList( includedFiles ) );
+        List excludes = new ArrayList( Arrays.asList( excludedFiles ) );
+        List linksForDeletion = new ArrayList();
+        
+        if ( !fileSet.isFollowSymlinks() )
+        {
+            // we need to see which entries were excluded because they're symlinks...
+            scanner.setFollowSymlinks( true );
+            scanner.scan();
+            
+            List notSymlinks = Arrays.asList( scanner.getExcludedFiles() );
+            
+            linksForDeletion.addAll( excludes );
+            linksForDeletion.retainAll( notSymlinks );
+            
+            excludes.removeAll( notSymlinks );
+        }
+        
+        for ( int i = 0; i < excludedFiles.length; i++ )
+        {
+            String path = excludedFiles[i];
+            
+            File excluded = new File( path );
+            
+            String parentPath = excluded.getParent();
+            
+            while( parentPath != null )
+            {
+                includes.remove( parentPath );
+                
+                parentPath = new File( parentPath ).getParent();
+            }
+        }
+        
+        includes.addAll( linksForDeletion );
+        
+        for ( Iterator it = includes.iterator(); it.hasNext(); )
+        {
+            String path = (String) it.next();
+            
+            if ( includes.contains( new File( path ).getParent() ) )
+            {
+                it.remove();
+            }
+        }
+        
+        return includes;
+    }
+
+    /**
+     * Accommodate Windows bug encountered in both Sun and IBM JDKs.
+     * Others possible. If the delete does not work, call System.gc(),
+     * wait a little and try again.
+     */
+    private static boolean delete( File f )
+    {
+        if ( !f.delete() )
+        {
+            if ( System.getProperty( "os.name" ).toLowerCase().indexOf( "windows" ) > -1 )
+            {
+                System.gc();
+            }
+            try
+            {
+                Thread.sleep( DELETE_RETRY_SLEEP_MILLIS );
+                return f.delete();
+            }
+            catch ( InterruptedException ex )
+            {
+                return f.delete();
+            }
+        }
+        
+        return true;
+    }
+
+    private static DirectoryScanner scan( FileSet fileSet )
+    {
+        File basedir = new File( fileSet.getDirectory() );
+        if ( !basedir.exists() )
+        {
+            return null;
+        }
+        
+        DirectoryScanner scanner = new DirectoryScanner();
+        
+        String[] includesArray = fileSet.getIncludesArray();
+        String[] excludesArray = fileSet.getExcludesArray();
+        
+        if ( includesArray.length < 1 && excludesArray.length < 1 )
+        {
+            scanner.setIncludes( new String[]{ "**" } );
+        }
+        else
+        {
+            scanner.setIncludes( includesArray );
+            scanner.setExcludes( excludesArray );
+        }
+        
+        scanner.setBasedir( basedir );
+        scanner.setFollowSymlinks( fileSet.isFollowSymlinks() );
+
+        scanner.scan();
+        
+        return scanner;
+    }
+
+}

Propchange: maven/shared/trunk/file-management/src/main/java/org/apache/maven/shared/model/fileset/util/FileSetUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/shared/trunk/file-management/src/main/java/org/apache/maven/shared/model/fileset/util/FileSetUtils.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/shared/trunk/file-management/src/main/mdo/fileset.mdo
URL: http://svn.apache.org/viewcvs/maven/shared/trunk/file-management/src/main/mdo/fileset.mdo?rev=377837&view=auto
==============================================================================
--- maven/shared/trunk/file-management/src/main/mdo/fileset.mdo (added)
+++ maven/shared/trunk/file-management/src/main/mdo/fileset.mdo Tue Feb 14 13:33:03 2006
@@ -0,0 +1,183 @@
+<?xml version="1.0"?>
+
+<model>
+  <id>fileset</id>
+  <name>FileSet</name>
+  <description>
+    <![CDATA[
+	<p>
+	A definition of a file-set. This model defines how file-sets can be
+        captured, using directory, includes, and excludes.
+	</p>
+    ]]>
+  </description>
+  <defaults>
+    <default>
+      <key>package</key>
+      <value>org.apache.maven.shared.model.fileset</value>
+    </default>
+  </defaults>
+  <classes>
+    <class>
+      <name>SetBase</name>
+      <version>1.0.0</version>
+      <fields>
+        <field>
+          <name>followSymlinks</name>
+          <version>1.0.0</version>
+          <type>boolean</type>
+          <default>false</default>
+          <description>
+            Specifies whether symbolic links should be traversed, or handled as-is.
+          </description>
+        </field>
+        <field>
+          <name>outputDirectory</name>
+          <version>1.0.0</version>
+          <type>String</type>
+          <description>
+            Specifies the output directory relative to the root
+            of the root directory of the assembly.  For example,
+            "log" will put the specified files in the log directory.
+          </description>
+        </field>
+        <field>
+          <name>includes</name>
+          <version>1.0.0</version>
+          <association>
+            <type>String</type>
+            <multiplicity>*</multiplicity>
+          </association>
+          <description>
+            <![CDATA[
+            When &lt;include&gt; subelements are present, they define
+            a set of files and directory to include.
+            ]]>
+          </description>
+        </field>
+        <field>
+          <name>excludes</name>
+          <version>1.0.0</version>
+          <association>
+            <type>String</type>
+            <multiplicity>*</multiplicity>
+          </association>
+          <description>
+            <![CDATA[
+            When &lt;exclude&gt; subelements are present, they define
+            a set of files and directory to exclude.
+            ]]>
+          </description>
+        </field>
+        <field>
+          <name>fileMode</name>
+          <version>1.0.0</version>
+          <type>String</type>
+          <defaultValue>0644</defaultValue>
+          <description>
+            <![CDATA[
+            Similar to a UNIX permission.  Format: (User)(Group)(Other) where each
+            component is a sum of Read = 4, Write = 2, and Execute = 1.  For example,
+            the default value of 0644 translates to User read-write, Group and Other 
+            read-only. 
+            <a href="http://www.onlamp.com/pub/a/bsd/2000/09/06/FreeBSD_Basics.html">(more on unix-style permissions)</a>
+          	]]>
+          </description>
+        </field>
+        <field>
+          <name>directoryMode</name>
+          <version>1.0.0</version>
+          <type>String</type>
+          <defaultValue>0755</defaultValue>
+          <description>
+            <![CDATA[
+            Similar to a UNIX permission.  Format: (User)(Group)(Other) where each
+            component is a sum of Read = 4, Write = 2, and Execute = 1.  For example,
+            the default value of 0644 translates to User read-write, Group and Other 
+            read-only. 
+            <a href="http://www.onlamp.com/pub/a/bsd/2000/09/06/FreeBSD_Basics.html">(more on unix-style permissions)</a>
+          	]]>
+          </description>
+        </field>
+      </fields>
+      <codeSegments>
+        <codeSegment>
+          <version>1.0.0</version>
+          <code><![CDATA[
+    public String[] getIncludesArray()
+    {
+        String[] includesArry = null;
+        java.util.Collection includes = getIncludes();
+        if ( includes != null && !includes.isEmpty() )
+        {
+            includesArry = new String[includes.size()];
+            includesArry = (String[]) includes.toArray( includesArry );
+        }
+        else if ( includes != null )
+        {
+            includesArry = new String[0];
+        }
+          
+        return includesArry;
+    }
+
+    public String[] getExcludesArray()
+    {
+        String[] excludesArry = null;
+        java.util.Collection excludes = getExcludes();
+        if ( excludes != null && !excludes.isEmpty() )
+        {
+            excludesArry = new String[excludes.size()];
+            excludesArry = (String[]) excludes.toArray( excludesArry );
+        }
+        else if ( excludes != null )
+        {
+            excludesArry = new String[0];
+        }
+          
+        return excludesArry;
+    }
+
+          ]]></code>
+        </codeSegment>
+      </codeSegments>
+    </class>
+    <class rootElement="true" xml.tagName="fileSet">
+      <name>FileSet</name>
+      <version>1.0.0</version>
+      <superClass>SetBase</superClass>
+      <fields>
+        <field>
+          <name>directory</name>
+          <version>1.0.0</version>
+          <type>String</type>
+          <description>
+            Absolute or relative from the module's directory.  For
+            example, "src/main/bin" would select this subdirectory
+            of the project in which this dependency is defined.
+          </description>
+          <required>true</required>
+        </field>
+        <field>
+          <name>lineEnding</name>
+          <version>1.0.0</version>
+          <type>String</type>
+          <description>
+            <![CDATA[
+            Controls the line-endings of files in this fileSet.
+            Valid values: 
+            <ul>
+              <li><b>"keep"</b> - Preserve all line endings</li>
+              <li><b>"unix"</b> - Use Unix-style line endings</li>
+              <li><b>"lf"</b> - Use a single line-feed line endings</li>
+              <li><b>"dos"</b> - Use DOS-style line endings</li>
+              <li><b>"crlf"</b> - Use Carraige-return, line-feed line endings</li>
+            </ul>
+            ]]>
+          </description>
+        </field>
+      </fields>
+    </class>
+  </classes>
+</model>
+

Propchange: maven/shared/trunk/file-management/src/main/mdo/fileset.mdo
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/shared/trunk/file-management/src/main/mdo/fileset.mdo
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/shared/trunk/file-management/src/test/java/org/apache/maven/shared/model/fileset/util/FileSetUtilsTest.java
URL: http://svn.apache.org/viewcvs/maven/shared/trunk/file-management/src/test/java/org/apache/maven/shared/model/fileset/util/FileSetUtilsTest.java?rev=377837&view=auto
==============================================================================
--- maven/shared/trunk/file-management/src/test/java/org/apache/maven/shared/model/fileset/util/FileSetUtilsTest.java (added)
+++ maven/shared/trunk/file-management/src/test/java/org/apache/maven/shared/model/fileset/util/FileSetUtilsTest.java Tue Feb 14 13:33:03 2006
@@ -0,0 +1,173 @@
+package org.apache.maven.shared.model.fileset.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.maven.shared.model.fileset.FileSet;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.cli.CommandLineException;
+import org.codehaus.plexus.util.cli.Commandline;
+
+public class FileSetUtilsTest
+    extends TestCase
+{
+    private static final List LINK_ENABLED_OSES = Arrays.asList( new String[]{ "unix", "osx", "bsd" } );
+    
+    private Set testDirectories = new HashSet();
+    private Set linkFiles = new HashSet();
+    
+    public void tearDown() throws IOException
+    {
+        for ( Iterator it = linkFiles.iterator(); it.hasNext(); )
+        {
+            File linkFile = (File) it.next();
+            
+            linkFile.delete();
+        }
+        
+        for ( Iterator it = testDirectories.iterator(); it.hasNext(); )
+        {
+            File dir = (File) it.next();
+            
+            FileUtils.deleteDirectory( dir );
+        }
+    }
+    
+    public void testGetIncludedFiles() throws IOException
+    {
+        File directory = setupTestDirectory( "testGetIncludedFiles" );
+        
+        FileSet set = new FileSet();
+        set.setDirectory( directory.getPath() );
+        set.addInclude( "**/included.txt" );
+        
+        String[] included = FileSetUtils.getIncludedFiles( set );
+        
+        Assert.assertEquals( 1, included.length );
+    }
+    
+    public void testIncludesDontFollowSymlinks() throws IOException, InterruptedException, CommandLineException
+    {
+        if ( operatingSystemAllowsLinking() )
+        {
+            File directory = setupTestDirectory( "testIncludesDontFollowSymlinks" );
+            File subdir = new File( directory, "linked-to-self" );
+            
+            if ( !createSymlink( directory, subdir ) )
+            {
+                fail( "Cannot create symlink." );
+            }
+            
+            FileSet set = new FileSet();
+            set.setDirectory( directory.getPath() );
+            set.addInclude( "**/included.txt" );
+            set.setFollowSymlinks( false );
+            
+            String[] included = FileSetUtils.getIncludedFiles( set );
+            
+            Assert.assertEquals( 1, included.length );
+        }        
+    }
+    
+    public void testDeleteDontFollowSymlinks() throws IOException, InterruptedException, CommandLineException
+    {
+        if ( operatingSystemAllowsLinking() )
+        {
+            File directory = setupTestDirectory( "testDeleteDontFollowSymlinks" );
+            File subdir = new File( directory, "linked-to-self" );
+            
+            if ( !createSymlink( directory, subdir ) )
+            {
+                fail( "Cannot create symlink." );
+            }
+            
+            FileSet set = new FileSet();
+            set.setDirectory( directory.getPath() );
+            set.addInclude( "**/included.txt" );
+            set.addInclude( "**/linked-to-self" );
+            set.setFollowSymlinks( false );
+            
+            FileSetUtils.delete( set );
+            
+            Assert.assertFalse( subdir.exists() );
+        }        
+    }
+    
+    public void testDelete() throws IOException
+    {
+        File directory = setupTestDirectory( "testDelete" );
+        File subdirFile = new File( directory, "subdir/excluded.txt" );
+        
+        FileSet set = new FileSet();
+        set.setDirectory( directory.getPath() );
+        set.addInclude( "**/included.txt" );
+        set.addInclude( "**/subdir" );
+        
+        FileSetUtils.delete( set );
+        
+        Assert.assertFalse( "file in marked subdirectory still exists.", subdirFile.exists() );
+    }
+    
+    private boolean operatingSystemAllowsLinking()
+    {
+        String osFamily = System.getProperty( "os.family", "unix" );
+        
+        return LINK_ENABLED_OSES.contains( osFamily );
+    }
+
+    private boolean createSymlink( File from, File to ) throws InterruptedException, CommandLineException
+    {
+        if ( to.exists() )
+        {
+            to.delete();
+        }
+        
+        Commandline cli = new Commandline();
+        cli.setExecutable( "ln" );
+        cli.createArgument().setLine( "-s" );
+        cli.createArgument().setLine( from.getPath() );
+        cli.createArgument().setLine( to.getPath() );
+        
+        int result = cli.execute().waitFor();
+        
+        linkFiles.add( to );
+
+        return result == 0;
+    }
+    
+    private File setupTestDirectory( String directoryName ) throws IOException
+    {
+        System.out.println( "Setting up directory for test: " + directoryName );
+        
+        URL sourceResource = getClass().getClassLoader().getResource( directoryName );
+        
+        if ( sourceResource == null )
+        {
+            Assert.fail( "Source directory for test: " + directoryName + " cannot be found." );
+        }
+        
+        File sourceDir = new File( sourceResource.getPath() );
+        
+        String basedir = System.getProperty( "basedir", System.getProperty( "user.dir" ) );
+        String testBase = System.getProperty( "testBase", "target/test-directories" );
+        
+        File testDir = new File( basedir, testBase + "/" + directoryName );
+        testDir.mkdirs();
+        
+        FileUtils.copyDirectoryStructure( sourceDir, testDir );
+        
+        testDirectories.add( testDir );
+        
+        return testDir;
+    }
+
+}

Propchange: maven/shared/trunk/file-management/src/test/java/org/apache/maven/shared/model/fileset/util/FileSetUtilsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/shared/trunk/file-management/src/test/java/org/apache/maven/shared/model/fileset/util/FileSetUtilsTest.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/shared/trunk/file-management/src/test/resources/testDelete/excluded.txt
URL: http://svn.apache.org/viewcvs/maven/shared/trunk/file-management/src/test/resources/testDelete/excluded.txt?rev=377837&view=auto
==============================================================================
--- maven/shared/trunk/file-management/src/test/resources/testDelete/excluded.txt (added)
+++ maven/shared/trunk/file-management/src/test/resources/testDelete/excluded.txt Tue Feb 14 13:33:03 2006
@@ -0,0 +1 @@
+this should be excluded.
\ No newline at end of file

Propchange: maven/shared/trunk/file-management/src/test/resources/testDelete/excluded.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/shared/trunk/file-management/src/test/resources/testDelete/excluded.txt
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/shared/trunk/file-management/src/test/resources/testDelete/included.txt
URL: http://svn.apache.org/viewcvs/maven/shared/trunk/file-management/src/test/resources/testDelete/included.txt?rev=377837&view=auto
==============================================================================
--- maven/shared/trunk/file-management/src/test/resources/testDelete/included.txt (added)
+++ maven/shared/trunk/file-management/src/test/resources/testDelete/included.txt Tue Feb 14 13:33:03 2006
@@ -0,0 +1 @@
+this should be included.
\ No newline at end of file

Propchange: maven/shared/trunk/file-management/src/test/resources/testDelete/included.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/shared/trunk/file-management/src/test/resources/testDelete/included.txt
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/shared/trunk/file-management/src/test/resources/testDelete/subdir/included.txt
URL: http://svn.apache.org/viewcvs/maven/shared/trunk/file-management/src/test/resources/testDelete/subdir/included.txt?rev=377837&view=auto
==============================================================================
--- maven/shared/trunk/file-management/src/test/resources/testDelete/subdir/included.txt (added)
+++ maven/shared/trunk/file-management/src/test/resources/testDelete/subdir/included.txt Tue Feb 14 13:33:03 2006
@@ -0,0 +1 @@
+this should be included.
\ No newline at end of file

Propchange: maven/shared/trunk/file-management/src/test/resources/testDelete/subdir/included.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/shared/trunk/file-management/src/test/resources/testDelete/subdir/included.txt
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/shared/trunk/file-management/src/test/resources/testDeleteDontFollowSymlinks/included.txt
URL: http://svn.apache.org/viewcvs/maven/shared/trunk/file-management/src/test/resources/testDeleteDontFollowSymlinks/included.txt?rev=377837&view=auto
==============================================================================
--- maven/shared/trunk/file-management/src/test/resources/testDeleteDontFollowSymlinks/included.txt (added)
+++ maven/shared/trunk/file-management/src/test/resources/testDeleteDontFollowSymlinks/included.txt Tue Feb 14 13:33:03 2006
@@ -0,0 +1 @@
+this should be included.
\ No newline at end of file

Propchange: maven/shared/trunk/file-management/src/test/resources/testDeleteDontFollowSymlinks/included.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/shared/trunk/file-management/src/test/resources/testDeleteDontFollowSymlinks/included.txt
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/otherStuff/excluded.txt
URL: http://svn.apache.org/viewcvs/maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/otherStuff/excluded.txt?rev=377837&view=auto
==============================================================================
--- maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/otherStuff/excluded.txt (added)
+++ maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/otherStuff/excluded.txt Tue Feb 14 13:33:03 2006
@@ -0,0 +1 @@
+this should be excluded.
\ No newline at end of file

Propchange: maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/otherStuff/excluded.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/otherStuff/excluded.txt
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/excluded.txt
URL: http://svn.apache.org/viewcvs/maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/excluded.txt?rev=377837&view=auto
==============================================================================
--- maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/excluded.txt (added)
+++ maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/excluded.txt Tue Feb 14 13:33:03 2006
@@ -0,0 +1 @@
+this should be excluded.
\ No newline at end of file

Propchange: maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/excluded.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/excluded.txt
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/included.txt
URL: http://svn.apache.org/viewcvs/maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/included.txt?rev=377837&view=auto
==============================================================================
--- maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/included.txt (added)
+++ maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/included.txt Tue Feb 14 13:33:03 2006
@@ -0,0 +1 @@
+this should be included.
\ No newline at end of file

Propchange: maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/included.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/shared/trunk/file-management/src/test/resources/testGetIncludedFiles/stuff/included.txt
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/excluded.txt
URL: http://svn.apache.org/viewcvs/maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/excluded.txt?rev=377837&view=auto
==============================================================================
--- maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/excluded.txt (added)
+++ maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/excluded.txt Tue Feb 14 13:33:03 2006
@@ -0,0 +1 @@
+this should be excluded.
\ No newline at end of file

Propchange: maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/excluded.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/excluded.txt
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/included.txt
URL: http://svn.apache.org/viewcvs/maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/included.txt?rev=377837&view=auto
==============================================================================
--- maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/included.txt (added)
+++ maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/included.txt Tue Feb 14 13:33:03 2006
@@ -0,0 +1 @@
+this should be included.
\ No newline at end of file

Propchange: maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/included.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/shared/trunk/file-management/src/test/resources/testIncludesDontFollowSymlinks/included.txt
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: maven/shared/trunk/pom.xml
URL: http://svn.apache.org/viewcvs/maven/shared/trunk/pom.xml?rev=377837&r1=377836&r2=377837&view=diff
==============================================================================
--- maven/shared/trunk/pom.xml (original)
+++ maven/shared/trunk/pom.xml Tue Feb 14 13:33:03 2006
@@ -112,6 +112,7 @@
   <modules>
     <module>maven-shared-io</module>
     <module>maven-shared-monitor</module>
+    <module>file-management</module>
   </modules>
   <scm>
     <connection>scm:svn:http://svn.apache.org/repos/asf/maven/shared/trunk/</connection>